
Example 20-4. The ntfy_pipe.c program (continued)
if (!*++argv)
puts("specify a program [w/args]"), exit(1);
pipe(pipe_io[0 ]); /* set up input pipe */
pipe(pipe_io[1 ]); /* set up output pipe */
switch (pid = fork()) {
case -1:
close(pipe_io[0][0]);
close(pipe_io[0][1]);
close(pipe_io[1][0]);
close(pipe_io[1][1]);
perror("fork failed");
exit(1);
case 0: /* child */
/* redirect child’s stdin (0), stdout (1) and stderr(2) */
dup2(pipe_io[0 ][0 ], 0);
dup2(pipe_io[1 ][1 ], 1);
dup2(pipe_io[1 ][1 ], 2);
for (i = getdtablesize(); i > 2; i--)
(void) close(i);
for (i = 0; i < NSIG; i++)
(void) signal(i, SIG_DFL);
execvp(*argv, argv);
if (errno == ENOENT)
printf("%s: command not found.0, *argv);
else
perror(*argv);
perror("execvp");
_exit(-1);
default: /* parent */
close(pipe_io[0][0]); /* close unused portions of pipes */
close(pipe_io[1][1]);
}
/* when the process outputs data, read it */
notify_set_input_func(client1, read_it, pipe_io[1 ][0]);
notify_set_wait3_func(client1, sigchldcatcher, pid);
/* wait for user input -- then write data to pipe */
notify_set_input_func(client2, write_it, 0);
notify_set_wait3_func(client2, sigchldcatcher, pid);
notify_start();
}
/*
* callback routine for when there is data on the parent’s stdin to
* read. Read it and then write the data to the child process via
* the pipe.
*/
Notify_value
write_it(client, fd)
Notify_client client;
int fd;
{
484 XView Programming Manual