Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

execv and piping/redirection

2,156 views
Skip to first unread message

Adam Harris

unread,
Dec 9, 1993, 5:52:59 PM12/9/93
to

[Question for unix, posix-compliant (Linux, actually) c program,
compiled with gcc 2.4.5 (time to upgrade!)]

I need to redirect the output of an exec system call into a file.
However, freopen, pipe(), don't seem to work. So, 2 questions:

(1) is it or is it not true that a process which has been
"replaced" by an exec call inherits the redirection of stdout
from the process it replaces? Maybe I'm just doing something
wrong? Do popen, freopen, or pipe commands "stick" after
exec calls? It doesn't seem to work...

--OR--

(2) why does the following code not work, and/or how could I get
this functionality with another technique:
...
char *args[] = {"df", ">df.output", NULL};
int status;

switch ((pid = fork())) {
case -1:
.../*error handler */
case 0: /* we're in the child */
status = execv("/usr/bin/df", args);
/* something went wrong if the following is executed... */
fprintf(stderr, "exec failed: status %d\n", status);
exit(1);
default:
wait(&pid);
}

The only thing I can think of is that redirection is handled by
the shell, so my call is illegal. However, running the thing as
a shell -e command, i.e.,

char *args[] = {"sh", "-e", "df", ">df.output", NULL};
...
status = execv("/bin/sh", args);

just gives me a segmentation fault. I've tried lots of combinations
for argument groupings, or "creat"ing the file and closing it, with
an append redirect, etc, etc, and nothing seems to work. I've
also seen nothing in the unix books about using exec in conjunction
with redirection.

Thanks in advance. Post to me (har...@cs.uchicago.edu) or this
group. I will give the solution here if mailed privately...


--
......................................................Adam Harris
...........................................har...@cs.uchicago.edu

Adam Harris

unread,
Dec 12, 1993, 7:15:13 AM12/12/93
to
My redirection problem was SOLVED thanks to friendly private posters.
In case you're interested, here's the way to redirect from execv:
(or at least one way. I've been told of a few. This is just the
one I tried first...)
(names in <> are just placeholders, not to be type literally)

int fd; /* output file descriptor */
int ret_status;
char *arglist[] = {<file>, <arg1>, <arg2>, NULL};

fd = creat(<filename>, <perms>);

switch (pid = fork()) {
case -1:
<insert fork error stuff>
case 0: /* child process */
/* copy our fd to 1, aka stdout */
/* you can only do this *once* per process! */
if (dup2(fd, 1) == -1) {
<unable to switch pipe error stuff>
exit(1); /* or use _exit(1) to avoid atexit() funcs */
}
if ((ret_status = execv(<file to call w/ path>, arglist)) == -1) {
<unable to exec on file error stuff>
exit(1);
}
printf("This line will never be called, in theory.\n");
exit(1);
default:
wait(&pid);
close(fd);
return;
}

THANKS ALL!

.......................................................Adam Harris
............................................har...@cs.uchicago.edu
--
......................................................Adam Harris
...........................................har...@cs.uchicago.edu

Ariel Faigon

unread,
Dec 13, 1993, 8:08:18 PM12/13/93
to
Adam Harris (har...@cs.uchicago.edu) wrote:

: [Question for unix, posix-compliant (Linux, actually) c program,


: compiled with gcc 2.4.5 (time to upgrade!)]

: I need to redirect the output of an exec system call into a file.
: However, freopen, pipe(), don't seem to work. So, 2 questions:

: (1) is it or is it not true that a process which has been
: "replaced" by an exec call inherits the redirection of stdout
: from the process it replaces? Maybe I'm just doing something
: wrong? Do popen, freopen, or pipe commands "stick" after
: exec calls? It doesn't seem to work...

Yes, open file descriptors are inherited across 'exec'.

: --OR--

: (2) why does the following code not work, and/or how could I get
: this functionality with another technique:
: ...
: char *args[] = {"df", ">df.output", NULL};
: int status;

How can it work ?
'df' has no idea that '>' means redirection. The nice thing
about UNIX is that the redirection, globbing, alias subsitution
variable substitution, etc. are done all by one program: the shell.
This way the code to do all these marvelous things need not be
duplicated in various utilities. They all get it for free.

: switch ((pid = fork())) {


: case -1:
: .../*error handler */
: case 0: /* we're in the child */
: status = execv("/usr/bin/df", args);
: /* something went wrong if the following is executed... */
: fprintf(stderr, "exec failed: status %d\n", status);
: exit(1);
: default:
: wait(&pid);
: }

: The only thing I can think of is that redirection is handled by
: the shell, so my call is illegal. However, running the thing as
: a shell -e command, i.e.,

: char *args[] = {"sh", "-e", "df", ">df.output", NULL};
: ...
: status = execv("/bin/sh", args);

The shell expects one argument to the '-e' option, a string.
You should leave the parsing to the shell, that's what the
shell is good at. Try:
char *args[] = {"sh", "-e", "df > df.output", NULL};

: just gives me a segmentation fault. I've tried lots of combinations


: for argument groupings, or "creat"ing the file and closing it, with
: an append redirect, etc, etc, and nothing seems to work. I've
: also seen nothing in the unix books about using exec in conjunction
: with redirection.

: Thanks in advance. Post to me (har...@cs.uchicago.edu) or this
: group. I will give the solution here if mailed privately...

If you don't want to call the shell, You need to open a file
for output ('df.output') and then 'dup2' your standard output
before the exec.

: --
: ......................................................Adam Harris
: ...........................................har...@cs.uchicago.edu

--
Peace, Ariel ari...@mirage.nsc.com

0 new messages