 |
|
 |
|
|
 |
reading other user's output |
 |
 |
|
|
06-11-06 06:23 AM
I'm writing a program which will read the stdout output of another
program. I do this by creating a pipe, then working, then in the child
process, dup2'ing the stdout onto the pipe and calling execl to execute
the program. The parent in the mean time read()'s from the pipe in a
loop Here is my code
The problem is that the loop with read() from the pipe forever. How do
I make it stop after the program child process dies?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
int filedes[2];
int pid;
if (pipe(filedes) == -1) {
perror("error in pipe");
exit(1);
}
pid = fork();
if (pid == 0) {
dup2(filedes[1], fileno(stdout));
execl("output", "output", NULL);
}
else if (pid) {
char c;
int len;
do {
len = read(filedes[0], &c, 1);
printf("--> %c\n", c);
} while (len);
exit(1);
}
}
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: reading other user's output |
 |
 |
|
|
06-11-06 12:24 PM
The parent will get a SIGCHLD signal when the child process exits. This
is typically used to get rid of zombie processes. If you don't flush
them they don't go away by themselves, but thats another story.
void handler(int signum){
exit(0);
}
then in main register the handler
signal(SIGCHLD,&handler);
simple as pie
khanzf@gmail.com wrote:
> I'm writing a program which will read the stdout output of another
> program. I do this by creating a pipe, then working, then in the child
> process, dup2'ing the stdout onto the pipe and calling execl to execute
> the program. The parent in the mean time read()'s from the pipe in a
> loop Here is my code
>
> The problem is that the loop with read() from the pipe forever. How do
> I make it stop after the program child process dies?
>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
>
> int main() {
> int filedes[2];
> int pid;
>
> if (pipe(filedes) == -1) {
> perror("error in pipe");
> exit(1);
> }
>
> pid = fork();
>
> if (pid == 0) {
> dup2(filedes[1], fileno(stdout));
> execl("output", "output", NULL);
> }
>
> else if (pid) {
> char c;
> int len;
>
> do {
> len = read(filedes[0], &c, 1);
> printf("--> %c\n", c);
> } while (len);
> exit(1);
>
> }
> }
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: reading other user's output |
 |
 |
|
|
06-11-06 12:24 PM
i added in child-signal catching, but that itself might not necessarily
work. That would only work if the child process only died BEFORE I
call read(), which isn't necessarily the case. That would be
problematic with smaller programs executed by execl(). the child
signal handler might be called BEFORE it has a change to read all the
data over the pipe.
- Farhan
Jolting wrote:[vbcol=seagreen]
> The parent will get a SIGCHLD signal when the child process exits. This
> is typically used to get rid of zombie processes. If you don't flush
> them they don't go away by themselves, but thats another story.
>
> void handler(int signum){
> exit(0);
> }
>
> then in main register the handler
>
> signal(SIGCHLD,&handler);
>
> simple as pie
>
> khanzf@gmail.com wrote:
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: reading other user's output |
 |
 |
|
|
06-11-06 06:27 PM
khanzf@gmail.com schrieb:
> I'm writing a program which will read the stdout output of another
> program. I do this by creating a pipe, then working, then in the child
> process, dup2'ing the stdout onto the pipe and calling execl to execute
> the program. The parent in the mean time read()'s from the pipe in a
> loop Here is my code
>
> The problem is that the loop with read() from the pipe forever. How do
> I make it stop after the program child process dies?
>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
>
> int main() {
> int filedes[2];
> int pid;
>
> if (pipe(filedes) == -1) {
> perror("error in pipe");
> exit(1);
> }
>
> pid = fork();
>
> if (pid == 0) {
> dup2(filedes[1], fileno(stdout));
> execl("output", "output", NULL);
> }
>
> else if (pid) {
> char c;
> int len;
>
> do {
> len = read(filedes[0], &c, 1);
> printf("--> %c\n", c);
> } while (len);
> exit(1);
>
> }
> }
The problem here is not that you do not wait for SIGCHLD. On reception
of sigchld, you should call wait(2). You did not close the other ends
of the filedescriptor. So if your output process exits, filedes[0] is
still open by the parent process. You should call close(filedes[0])
before your read loop in the parent. Here is code which works on my
linux box:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
int filedes[2];
int pid;
if (pipe(filedes) == -1) {
perror("error in pipe");
exit(1);
}
pid = fork();
if (pid == 0) {
close(filedes[0]);
dup2(filedes[1], fileno(stdout));
execl("output", "output", NULL);
perror("output");
_exit(1);
}
else if (pid) {
char c;
int len;
close(filedes[1]); /* important to detect EOF */
do {
len = read(filedes[0], &c, 1);
printf("--> %c %d\n", c, len);
} while (len);
exit(1);
}
}
Hubble.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: reading other user's output |
 |
 |
|
|
06-12-06 12:26 PM
khanzf@gmail.com wrote:
> I'm writing a program which will read the stdout output of another
> program. I do this by creating a pipe, then working, then in the child
> process, dup2'ing the stdout onto the pipe and calling execl to execute
> the program. The parent in the mean time read()'s from the pipe in a
> loop Here is my code
>
> The problem is that the loop with read() from the pipe forever. How do
> I make it stop after the program child process dies?
>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
>
> int main() {
> int filedes[2];
> int pid;
>
> if (pipe(filedes) == -1) {
> perror("error in pipe");
> exit(1);
> }
>
> pid = fork();
>
> if (pid == 0) {
> dup2(filedes[1], fileno(stdout));
> execl("output", "output", NULL);
> }
>
> else if (pid) {
> char c;
> int len;
>
> do {
> len = read(filedes[0], &c, 1);
> printf("--> %c\n", c);
> } while (len);
> exit(1);
>
> }
> }
>
Maybe you should better take a look on the manpage of popen.
I think it will do exactly what you want, without bothering with fork,
dup2, etc...
--
Francois Goudal
Epita promo 2008 - Ing1 - President Evolutek
francois@goudal.net
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 11:42 AM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|