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: RVP <rvp%SDF.ORG@localhost>
To: Michael Scholz <mike%fth-devel.net@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 06:43:18 +0000 (UTC)

 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
 



Home | Main Index | Thread Index | Old Index