coprocess question - Linux

This is a discussion on coprocess question - Linux ; The program below is from APUE. It is about coprocess. Mainly, the parent deliver input to ``add2" through pipe A, and the result is deliver back from ``add2" through pipe B. The question is about stability, please search ``**" for ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: coprocess question

  1. coprocess question

    The program below is from APUE.
    It is about coprocess.
    Mainly, the parent deliver input to ``add2" through pipe A, and the
    result is deliver back from ``add2" through pipe B.
    The question is about stability, please search ``**" for it.

    #include
    #include
    #include
    #include
    #include
    #include


    #define MAXLINE 80


    static void sig_pipe(int signo);

    int main()
    {
    int n,fd1[2],fd2[2];
    pid_t pid;
    char line[MAXLINE];

    if(signal(SIGPIPE,sig_pipe)==SIG_ERR){
    perror("signal error");
    exit(-1);
    }

    if(pipe(fd1)<0 || pipe(fd2)<0){
    perror("pipe error");
    exit(-1);
    }

    if((pid=fork())<0){
    perror("fork error");
    exit(-1);
    }else if(pid>0){
    close(fd1[0]);
    close(fd2[1]);
    while(fgets(line,MAXLINE,stdin)!=NULL){
    n=strlen(line);
    if(write(fd1[1],line,n)!=n){
    perror("write error");
    exit(-1);
    }
    //** Here is the question:
    //Is it possible that the result is
    //more than one digit, but only
    //one digit is read from the pipe?
    //For example:
    //input is ``11 22\nC-d"
    //will the output be "3"?
    if((n=read(fd2[0],line,MAXLINE))<0){
    perror("read error");
    exit(-1);
    }
    if (n==0){
    fprintf(stderr,"child closed pipe");
    break;
    }
    }
    line[n]=0;
    if(fputs(line,stdout)==EOF){
    perror("fputs error");
    exit(-1);
    }
    exit(0);
    } else {
    close(fd1[1]);
    close(fd2[0]);
    if(fd1[0]!=STDIN_FILENO){
    if(dup2(fd1[0],STDIN_FILENO)!=STDIN_FILENO){
    perror("dup2 to STDIN_FILENO error");
    exit(-1);
    }
    close(fd1[0]);
    }
    if(fd2[1]!=STDOUT_FILENO){
    if(dup2(fd2[1],STDOUT_FILENO)!=STDOUT_FILENO){
    perror("dup2 to STDOUT_FILENO error");
    exit(-1);
    }
    close(fd2[1]);
    }
    if(execl("./add2","add2",(char*)0)<0){
    perror("execl error");
    exit(-1);
    }
    }
    }

    static void sig_pipe(int signo)
    {
    printf("SIGPIPE caught\n");
    exit(1);
    }

  2. Re: coprocess question

    > if(write(fd1[1],line,n)!=n){
    > perror("write error");
    > exit(-1);
    > }
    > //** Here is the question:
    > //Is it possible that the result is
    > //more than one digit, but only
    > //one digit is read from the pipe?
    > //For example:
    > //input is ``11 22\nC-d"
    > //will the output be "3"?
    > if((n=read(fd2[0],line,MAXLINE))<0){
    > perror("read error");
    > exit(-1);
    > }


    POSIX [and all Unix] guarantees that write() on a pipe is atomic
    up to length _POSIX_PIPE_BUF; see /usr/include/bits/posix1_lim.h.
    POSIX requires that this limit be at least 512 bytes.
    Linux is more generous. Until about 2 years ago, the actual limit
    was 4096. With the new pipe filesystem in 2.6.11 and later (see
    http://lwn.net/Articles/119682/ ) the minimum is 64KB.

    So you are OK with write() and read(), but perhaps not with *printf(),
    fputs(), scanf(), gets(), etc., which offer no guarantees with respect
    to atomicity. In practice you can expect atomic writes if the stream
    is buffered and if you flush() before and after output. Atomic input
    with anything other than read() is problematic because of buffer
    boundaries.

    --

  3. Re: coprocess question

    On 2006-12-21, Ronald wrote:
    > The program below is from APUE.
    > It is about coprocess.
    > Mainly, the parent deliver input to ``add2" through pipe A, and the
    > result is deliver back from ``add2" through pipe B.
    > The question is about stability, please search ``**" for it.


    > //** Here is the question:
    > //Is it possible that the result is
    > //more than one digit, but only
    > //one digit is read from the pipe?
    > //For example:
    > //input is ``11 22\nC-d"
    > //will the output be "3"?


    in general yes, in this artificial case the result is most unlikely to be split.

    > static void sig_pipe(int signo)
    > {
    > printf("SIGPIPE caught\n");
    > exit(1);
    > }


    that is most naughty. you shouldn't call printf from a signal, handler,
    almost guaranteed to cause erattic, hard to find, problems.

    Bye.
    Jasen

+ Reply to Thread