본문 바로가기
보관용

[popen & pipe & dup] 좋은 예

by 크크다스 2014. 11. 14.
반응형

= popen의 좋은 예


= BLOCK / NON-BLOCK 세팅등


= Man

PIPE(2)
       #include <unistd.h>

       int pipe(int pipefd[2]);


       int pipe2(int pipefd[2], int flags);  // O_NONBLOCK   O_CLOEXEC

POPEN(3)
       #include <stdio.h>


       FILE *popen(const char *command, const char *type);
       int pclose(FILE *stream);


DUP(2)
       #include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

       int dup3(int oldfd, int newfd, int flags);
dup2>

newfd 가 정상 fd이면 먼저 내부적으로 close(nwefd)를 하고,

만약 oldfd, newfd가 같으면 단지 newf값만 리턴한다.

= Sample Source

Setup like this:

FILE *f = popen("./output", "r");
int d = fileno(f);
fcntl(d, F_SETFL, O_NONBLOCK);

Now you can read:

ssize_t r = read(d, buf, count);
if (r == -1 && errno == EAGAIN)
    no data yet
else if (r > 0)
    received data
else
    pipe closed

When you're done, cleanup:

pclose(f);

= popen()에 해당 하는 소스

int read_pipe_for_command(const char **argv)
{
   int p[2];

   /* Create the pipe. */
   if (pipe(p))
   {
      return -1;
   }

   /* Set non-blocking on the readable end. */
   if (fcntl(p[0], F_SETFL, O_NONBLOCK))
   {
      close(p[0]);
      close(p[1]);
      return -1;
   }

   /* Create child process. */
   switch (fork())
   {
      case -1:
          close(p[0]);
          close(p[1]);
          return -1;
      case 0:
          /* We're the parent process, close the writable part of the pipe */
          close(p[1]);
          return p[0];
      default:
          /* Close readable end of pipe */
          close(p[0]);
          /* Make stdout into writable end */
          dup2(p[1], 1);
          /* Run program */
          execvp(*argv, argv);
          /* If we got this far there was an error... */
          perror(*argv);
          exit(-1);
   }
}


반응형

'보관용' 카테고리의 다른 글

[BusyBox] DropBear  (0) 2014.11.14
[Netlink] A to Z  (0) 2014.11.14
[BusyBox] hsitory 기능  (0) 2014.11.14
[jiffies] 값에 대한 단상  (0) 2014.11.14
[sHash] Simple Hash  (0) 2014.11.10