NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/55836: popen(3)'s type "r+" doesn't work correctly



The following reply was made to PR lib/55836; it has been noted by GNATS.

From: Michael Scholz <mike%fth-devel.net@localhost>
To: RVP <rvp%SDF.ORG@localhost>
Cc: gnats-bugs%netbsd.org@localhost
Subject: Re: lib/55836: popen(3)'s type "r+" doesn't work correctly
Date: Thu, 3 Dec 2020 22:55:30 +0100 (CET)

 Hi!
 
 On Thu, 3 Dec 2020, RVP wrote:
 
 > On Wed, 2 Dec 2020 23:20:11 +0100 (CET), Michael Scholz wrote:
 >
 >> According to the man pages "the command's standard input is the same as
 >> that of the process that called popen()".
 >
 > Only when popen(3) is called with type == "r".
 >
 > When popen(3) is called with "r+", as you are doing, then *both* stdin
 > and stdout of the command point to the socketpair created by popen(3):
 >
 > $ fstat -p $(pgrep -x cat)
 > USER     CMD          PID   FD  MOUNT         INUM MODE         SZ|DV R/W
 > rvp      cat        24353   wd  /          1222645 drwx------     512 r
 > rvp      cat        24353    0* unix stream  0xffff941232bace80 <-> 
 > 0xffff9412551784c0
 > rvp      cat        24353    1* unix stream  0xffff941232bace80 <-> 
 > 0xffff9412551784c0
 > rvp      cat        24353    2  /dev/pts         7 crw--w----   pts/2 rw
 >
 > $ fstat -p $(pgrep -x /tmp/foo)
 > USER     CMD          PID   FD  MOUNT         INUM MODE         SZ|DV R/W
 > rvp      foo        21406   wd  /          1222645 drwx------     512 r
 > rvp      foo        21406    0* pipe 0xffff941255818000 <- 0x0 r
 > rvp      foo        21406    1  /dev/pts         7 crw--w----   pts/2 rw
 > rvp      foo        21406    2  /dev/pts         7 crw--w----   pts/2 rw
 > rvp      foo        21406    3* unix stream  0xffff9412551784c0 <-> 
 > 0xffff941232bace80
 >
 > Where, /tmp/foo is your program.
 >
 > This is not a bug. Certainly, the popen(3) man-page could elaborate on the
 > "r+" case too.
 >
 > I think this is the code you are aiming for:
 >
 > ---START---
 > #include <stdio.h>
 > #include <stdlib.h>
 > #include <err.h>
 >
 > int
 > main(void)
 > {
 >        char    buf[BUFSIZ];
 >        FILE    *fp;
 >
 >        if ((fp = popen("cat", "r+")) == NULL)
 >                err(EXIT_FAILURE, "popen");
 >
 >        while (fgets(buf, sizeof(buf), stdin) != NULL) {
 >                if (fputs(buf, fp) == EOF)
 >                        err(EXIT_FAILURE, "fputs(cat)");
 >
 >                if (fgets(buf, sizeof buf, fp) != NULL)
 >                        fputs(buf, stdout);
 >                else
 >                        err(EXIT_FAILURE, "fgets(cat)");
 >        }
 >
 >        if (pclose(fp) == EOF)
 >                err(EXIT_FAILURE, "pclose");
 >
 >        return EXIT_SUCCESS;
 > }
 > ---END---
 >
 >
 > -RVP
 
 Thank you very much.  With your and Wolfgang's clarifications I see now
 how I have to handle this.
 
 Mike
 



Home | Main Index | Thread Index | Old Index