COHERENT manpages

This page displays the COHERENT manpage for pipe() [Open a pipe].

List of available manpages
Index


pipe() -- System Call (libc)

Open a pipe
#include <unistd.h>
int pipe(fd)
int fd[2];

A pipe is an  interprocess communication mechanism.  pipe() creates a pipe,
typically to construct pipelines in the shell sh.

pipe()  fills in  fd[0] and  fd[1]  with read  and write  file descriptors,
respectively.  The file descriptors allow  the transfer of data from one or
more writers  to one or more  readers.  Pipes are buffered  to 5,120 bytes.
If more than  5,120 bytes are written into the  pipe, the write() call will
not return until the reader has  removed sufficient data for the write() to
complete.  If a  read() occurs on an empty pipe,  its completion awaits the
writing of data.

When all  writing processe close  their write file  descriptors, the reader
receives an  end of file indication.   A write on a  pipe with no remaining
readers generates a SIGPIPE signal to the caller.

pipe() is  generally called just  before fork(). Once the  parent and child
processes are created, the unused file descriptors should be closed in each
process.

Example

The  following example  prints the  word Waiting  until a  line of  data is
entered.  It illustrates how to use pipe(), fstat(), and fork().

#include <stdio.h>
#include <sys/stat.h>     /* for stat */
#include <sgtty.h>        /* for stty/gtty functions */
#include <unistd.h>

static int fd[2];       /* pipe array */

main()
{
    printf("This prints 'Waiting' every second until a 'q' is hit.\n");

    /*
     * Pipe may also be constructed by /etc/mknod
     * If it is desired to have tasks communicate where
     * they are not parent and child. In this case make
     * sure the constructed pipe has the correct owner and
     * permissions. Such pipe may be used exactly like this
     * but open()ed on each side.
     */

    if (-1 == pipe(fd)) {
        fprintf(stderr, "Cannot open pipe\n");
        exit(EXIT_FAILURE);
    }

    if (fork())
        parentProcess();
    else
        childProcess();
    exit(EXIT_SUCCESS);
}

parentProcess()
{
    struct stat s;
    char buff;

    for (buff = ' '; 'q' != buff;) {
        fstat(fd[0], &s);   /* get status of pipe */
        if (s.st_size) {        /* char in the pipe */
            read(fd[0], &buff, sizeof(buff));
            printf("Got a '%c'\n", buff);
            continue;
        }

        /*
         * This can be any process, it can use system()
         * or exec()
         */
        printf("Waiting\n");
        sleep(1);
    }
}

childProcess()
{
    struct  sgttyb  os, ns;
    char buff;

    gtty(fileno(stdin), &os);   /* save old state */
    ns = os;            /* get base of new state */
    ns.sg_flags |= RAW;     /* process each character as entered */
    ns.sg_flags &= ~(ECHO|CRMOD);/* no echo for now... */
    stty(fileno(stdin), &ns);   /* set mode */

    do {
        buff = getchar();   /* wait for the keyboard */
        write(fd[1], &buff, sizeof(buff));
    } while ('q' != buff);

    stty(fileno(stdin), &os);   /* reset mode */
}

See Also

close(),
libc,
libsocket,
mkfifo(),
mknod(),
read(),
sh,
signal(),
unistd.h,
write()
POSIX Standard, §6.1.1

Diagnostics

pipe() returns zero  on successful calls, or -1 if  it could not create the
pipe.

If it is  necessary to create a pipe between  tasks that are not parent and
child, use  /etc/mknod to create  a named pipe.   These named pipes  can be
opened and used by  different programs for communication.  Remember to give
them the correct owner and permissions.

If you  attempt to open a  pipe write only, O_NDELAY is  set, and there are
currently  no readers  on this  pipe, open()  returns immediately  and sets
errno to ENXIO.