Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Monday, November 19, 2018

File: [Platon] / scripts / ep / pipe-test.c (download)

Revision 1.3, Mon Feb 4 15:04:47 2002 UTC (16 years, 9 months ago) by host8


Changes since 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.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top