This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: readelf_need_wide


Hey Phil,

[Please assume a light-hearted answer is what was intended; I know I
 can sound snooty when writing these responses. ;-]

> We're checking for whether readelf supports a certain option.  But the
> method used (feeding grep through system()) doesn't do what we think it
> does; system() returns nonzero iff the command dies in some freaky way.

I concede that my knowledge of system() portability may be flawed.  My
understanding is based on the current BSD 4.4 man page, as conveyed in
FreeBSD 4.x; _The UNIX Programming Environment_ circa 1984; and K&R
circa 1988. ;-)  As usual, K&R is the most straight-forward: "*system*
returns a system-dependent integer status from the command executed.
In the UNIX system, the status return is the value returned by *exit*."

In a modern UNIX system, the status return is actually encoded
somewhere in that value along with other general failure markers (the
ones you noted below).

> The command's normal exit value has to be extracted with WEXITSTATUS.

Yikes!  Using this macro would appear to be *far* less portable IMHO!

Your removed test code is buggy IMHO; at least with respects to
testing the actual feature I used.  Here is how your test program is
tricked: On many/all UNIX systems, return from main() only uses the
lowest 8 bits to generate the value returned to the shell.  On
many/all modern UNIX systems, system() actually encoded the command
status << 8 (i.e. a tad divergent from K&R).  I am not prepared to
make any statement about POSIX specification in this area.

> Loren, do you actually get the correct answers using an older readelf that
> doesn't have -W/--wide?

Yes.  And I did test it before committing it.  Check the record for
how many different versions of readelf were actually checked.  ;-)
Granted, all testing took place on only one platform along with my
understanding of the portability of the construct to various modern
and past UNIX machines.  Could you report where you see the exact
run-time test, as written, fail?

> I would expect that in this code,
>
>  bool readelf_need_wide =
>    (system("readelf --help | grep -- --wide >/dev/null") == 0);
>
> readelf_need_wide should always be zero, unless grep itself segfaults or
> otherwise craps out with a signal.

In my experience, under modern UNIX (BSD and SysV types), when grep
executed in system() returns 1 without any signal-based kill; 256 is
returned from system().  Thus, to check the portability of my use of
system(), try this test program instead, please:

#include <stdlib.h>
#include <stdio.h>
 
int main()
{
  printf ("%d\n", system("/usr/bin/readelf --help | grep -- --wide"));
  printf ("%d\n", system("/usr/local/bin/readelf --help | grep -- --wide"));
  printf ("%d\n", system("true"));
  printf ("%d\n", system("false"));
  printf ("%d\n", system("echo|true"));
  printf ("%d\n", system("echo|false"));
  printf ("%x\n", system("NoCommandInPath"));
}

S rittle@latour; a.out
256
  -W --wide              Allow output width to exceed 80 characters
0
0
256
0
256
NoCommandInPath: not found
7f00

On RedHat 6/7, I see, as I expected:

S rittle@aspen; a.out
sh: /usr/bin/readelf: No such file or directory
256
sh: /usr/local/bin/readelf: No such file or directory
256
0
256
0
256
sh: NoCommandInPath: command not found
7f00

On Solaris 2.X, I see:

S rittle@magoo; a.out
sh: /usr/bin/readelf: not found
256
256
0
65280
0
65280
sh: NoCommandInPath: not found
100


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]