Súbor: [Platon] / scripts / ep / pipe-test.c (stiahnutie)
Revízia 1.3, Mon Feb 4 15:04:47 2002 UTC (22 years, 1 month ago) by host8
Zmeny od 1.2: +4 -0
[lines]
Added '$Id/Log: $' keyword substitution for simple identification version of file.
|
/*
* $Log: pipe-test.c,v $
* Revision 1.3 2002/02/04 15:04:47 host8
* Added '$Id/Log: $' keyword substitution for simple identification version of file.
*
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFSIZE 128
int read_to_buffer(int fd, char *buf);
int sh_unset_nodelay_mode (int fd);
int give_terminal_to (pid_t pgrp, int shell_tty, int force);
/* Function int main(int argc, char **argv) {{{ */
int main(int argc, char **argv)
{
register int ret, pid;
int pipe0[2], pipe1[2], pipe2[2];
char buf[BUFSIZE];
fd_set fds;
if (argc <= 1) {
printf("Usage: %s <command>\n", argv[0]);
return 1;
}
if (pipe(pipe0)
|| pipe(pipe1)
|| pipe(pipe2)) {
puts("pipe() failure");
return 1;
}
/*
fcntl(pipe1[1], F_SETFL, O_NONBLOCK|O_NDELAY);
fcntl(pipe2[1], F_SETFL, O_NONBLOCK|O_NDELAY);
sh_unset_nodelay_mode(0);
sh_unset_nodelay_mode(pipe1[1]);
sh_unset_nodelay_mode(pipe1[2]);
*/
switch (pid = fork()) {
case -1:
puts("fork() failure");
return 1;
break;
case 0: /* Child */
if (dup2(pipe0[0], 0) == -1
|| dup2(pipe1[1], 1) == -1
|| dup2(pipe2[1], 2) == -1) {
puts("dup2() failure");
return 1;
}
close(pipe0[0]);
close(pipe0[1]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(argv[1], argv + 1);
break;
default: /* Parent */
break;
};
give_terminal_to(pid, 1, 0);
while (1) {
FD_ZERO(&fds);
FD_SET(0, &fds);
FD_SET(pipe1[0], &fds);
FD_SET(pipe2[0], &fds);
switch (select(FD_SETSIZE, &fds, NULL, NULL, NULL)) {
case -1:
puts("select() failure");
return 1;
break;
default:
if (FD_ISSET(0, &fds)) {
ret = read_to_buffer(0, buf);
write(pipe0[1], buf, ret);
}
if (FD_ISSET(pipe1[0], &fds)) {
ret = read_to_buffer(pipe1[0], buf);
write(1, buf, ret);
}
if (FD_ISSET(pipe2[0], &fds)) {
ret = read_to_buffer(pipe2[0], buf);
write(2, buf, ret);
}
break;
}
}
return 0;
} /* }}} */
int read_to_buffer(int fd, char *buf)
{
register int ret;
ret = read(fd, buf, BUFSIZE);
if (ret < 0) {
printf("read() error, returned %d\n", ret);
exit(-1 * ret);
}
else if (ret == 0) {
printf("read() == 0, terminating\n");
exit(0);
}
return ret;
}
/* Make sure no-delay mode is not set on file descriptor FD. */
int sh_unset_nodelay_mode (int fd)
{
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
return -1;
bflags = 0;
/* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
and O_NDELAY is defined. */
#ifdef O_NONBLOCK
bflags |= O_NONBLOCK;
#endif
#ifdef O_NDELAY
bflags |= O_NDELAY;
#endif
if (flags & bflags)
{
flags &= ~bflags;
return (fcntl (fd, F_SETFL, flags));
}
return 0;
}
/* Give the terminal to PGRP. */
int give_terminal_to (pid_t pgrp, int shell_tty, int force)
{
sigset_t set, oset;
int r;
r = 0;
if (/* job_control ||*/ force) {
sigemptyset (&set);
sigaddset (&set, SIGTTOU);
sigaddset (&set, SIGTTIN);
sigaddset (&set, SIGTSTP);
sigaddset (&set, SIGCHLD);
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &set, &oset);
if (tcsetpgrp (shell_tty, pgrp) < 0) {
/* Maybe we should print an error message? */
#if 0
sys_error ("tcsetpgrp(%d) failed: pid %ld to pgrp %ld",
shell_tty, (long)getpid(), (long)pgrp);
#endif
r = -1;
}
else {
/* terminal_pgrp = pgrp; */
}
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
}
return r;
}
/* Modeline for ViM {{{1
* vim:set ts=4:
* vim600:fdm=marker fdl=0 fdc=3:
* }}}1 */
Platon Group <platon@platon.sk> http://platon.sk/
|