From: Phred Phungus on
glen herrmannsfeldt wrote:
> Richard Maine <nospam(a)see.signature> wrote:
>> dpb <none(a)non.net> wrote:
>
>>> Or see if your compiler supports returning the exit code w/ a SYSTEM()
>>> function call (or whatever is the implemented variant name for the
>>> functionality, assuming there is one).
>
>> But be aware that most don't. That is the source of a reasonably comon
>> confusion. Some variants do return an error code, but the error code
>> usually indicates whether or not the shell command was successfully
>> spawned rather than what error code the command returned.
>
> C/unix derived system() does return the exit code, or the error
> return from the spawn. In my test on a Linux system:
>
> #include <stdio.h>
> int main() {
> printf("%d\n",system("ls | grep ."));
> }
>
> prints 256 if the directory didn't exist, and 0 if it did.
> I didn't track down if that made sense in terms of return
> codes, but that is what it did. The return code from grep is
> 0 if items were found, and 1 if they were not. There might be
> easier ways to get the results out of ls.
>
> You might be able to run the C system() through C interoperability
> if the Fortran version does not supply a return code.
>
> -- glen

[non-fortranish for the moment]

I always find your posts thought-provoking and tried to extend this
notion slightly. I asked in comp.unix.programmer whether 'system' was
state of the art, and Lew Pitcher recommended that I look at popen(3),
and this is my initial foray:

$ gcc -D_GNU_SOURCE -Wall -Wextra rr4.c -o out
rr4.c: In function �main�:
rr4.c:15: warning: suggest braces around empty body in an �if� statement
rr4.c:28: warning: format �%d� expects type �int�, but argument 2 has
type �struct FILE *�
rr4.c:30: warning: format �%d� expects type �int�, but argument 2 has
type �struct FILE *�
$ ./out
9vx-0.12
9vx-0.12.tar.bz2
....
unleashed
winter1.c
winter1.c~
z
fp is 138625032
fp is 138625032
$ cat rr4.c
#include <stdio.h>
#include <stdlib.h>
#define PATH_MAX 4096
int
main ()
{

FILE *fp;
int status;
char path[PATH_MAX];

//printf ("%d\n", system ("ls | grep ."));
fp = popen ("ls | grep .", "r");
if (fp == NULL)
/* Handle error */ ;
while (fgets (path, PATH_MAX, fp) != NULL)
printf ("%s", path);
status = pclose (fp);
if (status == -1)
{
/* Error reported by pclose() */
}
else
{
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
}
printf("fp is %d\n", fp);
fp = popen ("ls | grep zax", "r");
printf("fp is %d\n", fp);
return 0;
}
// gcc -D_GNU_SOURCE -Wall -Wextra rr4.c -o out
$

So gcc is warning that I don't have the proper descriptor, but I have
the same integer as output for fp, so that basically means that I don't
see the analog of 0 ... 256 with it, as I'd hoped.

Tja.
--
fred
From: Louis Krupp on
Phred Phungus wrote:
> glen herrmannsfeldt wrote:
<snip>
>> C/unix derived system() does return the exit code, or the error
>> return from the spawn. In my test on a Linux system:
>>
>> #include <stdio.h>
>> int main() {
>> printf("%d\n",system("ls | grep ."));
>> }
>>
>> prints 256 if the directory didn't exist, and 0 if it did.
>> I didn't track down if that made sense in terms of return
>> codes, but that is what it did. The return code from grep is
>> 0 if items were found, and 1 if they were not. There might be
>> easier ways to get the results out of ls.
>>
>> You might be able to run the C system() through C interoperability
>> if the Fortran version does not supply a return code.
>>
>> -- glen
>
> [non-fortranish for the moment]
>
> I always find your posts thought-provoking and tried to extend this
> notion slightly. I asked in comp.unix.programmer whether 'system' was
> state of the art, and Lew Pitcher recommended that I look at popen(3),
> and this is my initial foray:
>
> $ gcc -D_GNU_SOURCE -Wall -Wextra rr4.c -o out
> rr4.c: In function �main�:
> rr4.c:15: warning: suggest braces around empty body in an �if� statement
> rr4.c:28: warning: format �%d� expects type �int�, but argument 2 has
> type �struct FILE *�
> rr4.c:30: warning: format �%d� expects type �int�, but argument 2 has
> type �struct FILE *�
> $ ./out
> 9vx-0.12
> 9vx-0.12.tar.bz2
> ...
> unleashed
> winter1.c
> winter1.c~
> z
> fp is 138625032
> fp is 138625032
> $ cat rr4.c
> #include <stdio.h>
> #include <stdlib.h>
> #define PATH_MAX 4096
> int
> main ()
> {
>
> FILE *fp;
> int status;
> char path[PATH_MAX];
>
> //printf ("%d\n", system ("ls | grep ."));
> fp = popen ("ls | grep .", "r");
> if (fp == NULL)
> /* Handle error */ ;
> while (fgets (path, PATH_MAX, fp) != NULL)
> printf ("%s", path);
> status = pclose (fp);
> if (status == -1)
> {
> /* Error reported by pclose() */
> }
> else
> {
> /* Use macros described under wait() to inspect `status' in order
> to determine success/failure of command executed by popen() */
> }
> printf("fp is %d\n", fp);
> fp = popen ("ls | grep zax", "r");
> printf("fp is %d\n", fp);
> return 0;
> }
> // gcc -D_GNU_SOURCE -Wall -Wextra rr4.c -o out
> $
>
> So gcc is warning that I don't have the proper descriptor, but I have
> the same integer as output for fp, so that basically means that I don't
> see the analog of 0 ... 256 with it, as I'd hoped.
>
> Tja.

system() returns a status code, while popen() returns a file pointer.
There is no analog.

If you were to print the file pointer, you'd use a "%p" descriptor, but
there's usually not much point in doing that.

system() runs a shell command for you and gives you the status code,
while popen lets you run a shell command and either send it input or
collect its output. I'm not sure that one would be considered more
"state of the art" than the other. Since you're printing the list of
files, it means that popen() is working for you, which means you've done
everything right.

Louis