Are pclose() return values useless?

5,610 views
Skip to first unread message

AJ ONeal

unread,
Jan 4, 2011, 7:56:34 PM1/4/11
to uta...@googlegroups.com
According to the manpage pclose [0] should return the value of wait4 [1], which is the value of waitpid [2].

waitpid(): on success, returns the process ID of the child whose state has changed; on error, -1 is returned; if WNOHANG was specified and no child(ren) specified by pid has yet changed state, then 0 is returned.

When my application exits with return 0 or exit(EXIT_SUCCESS) I get 36096.
When my application exits with return 1 or exit(EXIT_FAILURE) I get 256.

I'm a little hesitant to hard-code those values as success and failure, but they seem pretty consistent.

Any ideas?

AJ ONeal

[0] http://linux.die.net/man/3/pclose
[1] http://linux.die.net/man/2/wait4
[2] http://linux.die.net/man/2/waitpid

Shawn

unread,
Jan 5, 2011, 12:07:28 AM1/5/11
to Utah C Users Group
On Jan 4, 5:56 pm, AJ ONeal <coola...@gmail.com> wrote:
> When my application exits with return 0 or exit(EXIT_SUCCESS) I get 36096.
> When my application exits with return 1 or exit(EXIT_FAILURE) I get 256.
>
> I'm a little hesitant to hard-code those values as success and failure, but
> they seem pretty consistent.
>
> Any ideas?

WEXITSTATUS(child_status) will give you the actual return code. That
macro
as well as several others used to examine the status are described in
the
waitpid man page, and implemented in sys/wait.h.

--
Shawn

AJ ONeal

unread,
Jan 5, 2011, 2:57:56 AM1/5/11
to uta...@googlegroups.com
Thanks again Shawn.

I should have seen that, but I was narrowly focused on the words "return value".

AJ ONeal

AJ ONeal

unread,
Jan 7, 2011, 3:39:57 PM1/7/11
to uta...@googlegroups.com
BTW, tried what you suggested with mixed results.

WEXITSTATUS seems to reliably return 1 on error, but it doesn't seem to reliably return 0 on success.

Rather it returns 141.

AJ ONeal

Shawn

unread,
Jan 7, 2011, 3:47:37 PM1/7/11
to Utah C Users Group
On Jan 7, 1:39 pm, AJ ONeal <coola...@gmail.com> wrote:
> BTW, tried what you suggested with mixed results.
>
> WEXITSTATUS seems to reliably return 1 on error, but it doesn't seem to
> reliably return 0 on success.
>
> Rather it returns 141.

Yeah, I noticed that from the numbers you gave before, that applying
the macro to 36096 yielded 141 on my system. I was hoping maybe your
C library (assuming it isn't glibc) encoded the values a little
differently. Apparently not.

When you return 0, is WIFEXITED(status) true? WEXITSTATUS() is only
supposed to be used in that case. Other than that, I'm not sure what
might be going on. According to the docs, WEXITSTATUS(status) should
give you the low-order byte of the exit status of the child. I've
never seen any problem with this before, but I'm not sure I've ever
used it the way you are.

You might want to post a question on the libc help mailing list. This
may be a bug.

Good luck!

--
Shawn.

mivael

unread,
Mar 18, 2011, 7:22:11 AM3/18/11
to uta...@googlegroups.com, Michael...@gmail.com
Hello,

I'm having similar problem hacking wpa-supplicant and found this thread through the internet search.

Sometimes -- but not every time -- pclose() returns me 36096 (0x8d00), and WEXITSTATUS(36096) returns 141 (0x8d).

First, I don't know why "low-order 8 bits of the status" means this, but I checked include files. On my system it's calculated by __WEXITSTATUS() exactly like defined in bits/waitstatus.h:

/* If WIFEXITED(STATUS), the low-order 8 bits of the status.  */
#define __WEXITSTATUS(status)   (((status) & 0xff00) >> 8)

Second, there's a hint in this post:
http://groups.yahoo.com/group/amanda-hackers/message/1078

I added stderr redirection to the command opened by popen().
I think either of variants should work:
... = popen("... 2>&1", "r");
or
... = popen("... 2>/dev/null", "r");

If the problem will persist I'll post to this group.

If you solved this problem other way, please let me know.

Michael.

--
Michael V. Antosha
http://identi.ca/mivael
xmpp:miv...@jabber.org

mivael

unread,
Mar 18, 2011, 7:33:44 AM3/18/11
to uta...@googlegroups.com, Michael...@gmail.com
It didn't help.
Problem persists.

Michael.

mivael

unread,
Mar 18, 2011, 10:24:55 AM3/18/11
to uta...@googlegroups.com, Michael...@gmail.com
Simple enough.

1. It's shell's exit status. From 'info bash' docs:

   3.7.5 Exit Status
   ...When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.

So, we have some "fatal signal" which number is 13 (141-128).

2. From headers (<bits/signum.h> which is included to <signal.h> on my system):

   #define SIGPIPE         13      /* Broken pipe (POSIX).  */

3. From 'info SIGPIPE':

        ...If you use pipes or FIFOs...If the reading process never starts, or terminates unexpectedly, writing to the pipe or FIFO raises a `SIGPIPE' signal...

Seems logical in my case that my app can get SIGPIPE signal because pclose() was called instantly after popen(), without reading the child's output.

4. Considering the above, output from WEXITSTATUS() in my case should be considered okay if it is either zero or (128+SIGPIPE).

      wstat = WEXITSTATUS(stat = pclose (stream));
      if (stat < 0 || (wstat != 0 && wstat != 128+SIGPIPE))
        {
          /* error message... */;
        }

Michael.

AJ ONeal

unread,
Mar 19, 2011, 3:25:26 AM3/19/11
to uta...@googlegroups.com
Michael,

Thanks for following up with this! It's great to have your contribution and a better explanation. I'll refer back to this if I encounter the problem again.

AJ ONeal
Reply all
Reply to author
Forward
0 new messages