免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5334 | 回复: 8
打印 上一主题 下一主题

[C] 关于popen [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-26 12:56 |只看该作者 |倒序浏览
APUE第2版406页说
每次调用popen时,应当记住所创建子进程的ID
请问,怎么得到这个子进程ID的?

有些人推荐用fork+execl,但是我要在这个管道里传输一些指令,所以就选择了popen

论坛徽章:
0
2 [报告]
发表于 2009-05-26 15:01 |只看该作者
popen的时候子进程还没有创建

之后需要你手动创建



popen只是创建了管道

论坛徽章:
0
3 [报告]
发表于 2009-05-26 15:28 |只看该作者
#include <stdio.h>

       FILE *popen(const char *command, const char *type);

       int pclose(FILE *stream);

DESCRIPTION
       The popen() function opens a process by creating a pipe, forking, and invoking the shell.  Since a pipe is by defâ

论坛徽章:
0
4 [报告]
发表于 2009-06-01 14:08 |只看该作者
原帖由 net_robber 于 2009-5-26 15:01 发表
popen的时候子进程还没有创建

之后需要你手动创建



popen只是创建了管道


popen需要自己手动创建子进程?

popen的第一个参数不是cmd吗?然后就直接自动fork然后执行了


我的代码:
snprintf(t_cmd, 256, "main_dec -f %s_ -s %s -m %d -q %d", t_fname, g_rec_path, 2, play_mode);
       
play_fp = popen(t_cmd, "w");

[ 本帖最后由 marco_hxj 于 2009-6-1 14:30 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-06-01 17:39 |只看该作者
原帖由 marco_hxj 于 2009-5-26 12:56 发表
APUE第2版406页说
每次调用popen时,应当记住所创建子进程的ID
请问,怎么得到这个子进程ID的?

有些人推荐用fork+execl,但是我要在这个管道里传输一些指令,所以就选择了popen


你不需要知道PID,stdio记住就行了,pclose的时候用得着。

论坛徽章:
0
6 [报告]
发表于 2009-06-01 17:49 |只看该作者
popen执行后就创建了pipe和process了,怎么还要手动创建子进程???第一次听说

论坛徽章:
1
天蝎座
日期:2013-10-23 21:11:03
7 [报告]
发表于 2009-06-01 19:48 |只看该作者
原帖由 marco_hxj 于 2009-5-26 12:56 发表
APUE第2版406页说
每次调用popen时,应当记住所创建子进程的ID
请问,怎么得到这个子进程ID的?

有些人推荐用fork+execl,但是我要在这个管道里传输一些指令,所以就选择了popen


  1. Figure 15.12. The popen and pclose functions
  2. #include "apue.h"
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <sys/wait.h>

  6. /*
  7. * Pointer to array allocated at run-time.
  8. */
  9. static pid_t    *childpid = NULL;

  10. /*
  11. * From our open_max(), Figure 2.16.
  12. */
  13. static int      maxfd;

  14. FILE *
  15. popen(const char *cmdstring, const char *type)
  16. {
  17.     int     i;
  18.     int     pfd[2];
  19.     pid_t   pid;
  20.     FILE    *fp;

  21.     /* only allow "r" or "w" */
  22.     if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) {
  23.         errno = EINVAL;     /* required by POSIX */
  24.         return(NULL);
  25.     }

  26.     if (childpid == NULL) {     /* first time through */
  27.         /* allocate zeroed out array for child pids */
  28.         maxfd = open_max();
  29.         if ((childpid = calloc(maxfd, sizeof(pid_t))) == NULL)
  30.             return(NULL);
  31.     }

  32.     if (pipe(pfd) < 0)
  33.         return(NULL);   /* errno set by pipe() */

  34.     if ((pid = fork()) < 0) {
  35.         return(NULL);   /* errno set by fork() */
  36.     } else if (pid == 0) {                           /* child */
  37.         if (*type == 'r') {
  38.             close(pfd[0]);
  39.             if (pfd[1] != STDOUT_FILENO) {
  40.                 dup2(pfd[1], STDOUT_FILENO);
  41.                 close(pfd[1]);
  42.             }
  43.         } else {
  44.             close(pfd[1]);
  45.             if (pfd[0] != STDIN_FILENO) {
  46.                 dup2(pfd[0], STDIN_FILENO);
  47.                 close(pfd[0]);
  48.             }
  49.         }

  50.         /* close all descriptors in childpid[] */
  51.         for (i = 0; i < maxfd; i++)
  52.             if (childpid[i] > 0)
  53.                 close(i);

  54.         execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
  55.         _exit(127);
  56.     }

  57.     /* parent continues... */
  58.     if (*type == 'r') {
  59.         close(pfd[1]);
  60.         if ((fp = fdopen(pfd[0], type)) == NULL)
  61.             return(NULL);
  62.     } else {
  63.         close(pfd[0]);
  64.         if ((fp = fdopen(pfd[1], type)) == NULL)
  65.             return(NULL);
  66.     }

  67.     childpid[fileno(fp)] = pid; /* remember child pid for this fd */
  68.     return(fp);
  69. }


  70. int
  71. pclose(FILE *fp)
  72. {
  73.     int     fd, stat;
  74.     pid_t   pid;

  75.     if (childpid == NULL) {
  76.         errno = EINVAL;
  77.         return(-1);     /* popen() has never been called */
  78.     }

  79.     fd = fileno(fp);
  80.     if ((pid = childpid[fd]) == 0) {
  81.         errno = EINVAL;
  82.         return(-1);     /* fp wasn't opened by popen() */
  83.     }

  84.     childpid[fd] = 0;
  85.     if (fclose(fp) == EOF)
  86.         return(-1);

  87.     while (waitpid(pid, &stat, 0) < 0)
  88.         if (errno != EINTR)
  89.             return(-1); /* error other than EINTR from waitpid() */

  90.     return(stat);   /* return child's termination status */
  91. }

复制代码


内部实现需要这样
至于当做API函数使用就不需要考虑这些了

论坛徽章:
0
8 [报告]
发表于 2009-06-04 10:08 |只看该作者
原帖由 JohnBull 于 2009-6-1 17:39 发表


你不需要知道PID,stdio记住就行了,pclose的时候用得着。


我主要想知道这个子进程什么时候退出,看来得用7楼的方法。
7楼的方法第一次看到,我以为popen只有是自动调用fork+excel的

论坛徽章:
0
9 [报告]
发表于 2009-06-04 10:14 |只看该作者
Figure 15.12. The popen and pclose functions
#include "apue.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>

/*
* Pointer to array allocated at run-time.
*/

static pid_t    *childpid = NULL;

/*
* From our open_max(), Figure 2.16.
*/

static int      maxfd;

FILE *
popen(const char *cmdstring, const char *type)
{
&nbsp;&nbsp;&nbsp;&nbsp;int     i;
&nbsp;&nbsp;&nbsp;&nbsp;int     pfd[2];
&nbsp;&nbsp;&nbsp;&nbsp;pid_t   pid;
&nbsp;&nbsp;&nbsp;&nbsp;FILE    *fp;

&nbsp;&nbsp;&nbsp;&nbsp;/* only allow "r" or "w" */
&nbsp;&nbsp;&nbsp;&nbsp;if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errno = EINVAL;     /* required by POSIX */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (childpid == NULL) {     /* first time through */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* allocate zeroed out array for child pids */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxfd = open_max();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((childpid = calloc(maxfd, sizeof(pid_t))) == NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (pipe(pfd) < 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);   /* errno set by pipe() */

&nbsp;&nbsp;&nbsp;&nbsp;if ((pid = fork()) < 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);   /* errno set by fork() */
&nbsp;&nbsp;&nbsp;&nbsp;} else if (pid == 0) {                           /* child */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (*type == 'r') {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pfd[1] != STDOUT_FILENO) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dup2(pfd[1], STDOUT_FILENO);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pfd[0] != STDIN_FILENO) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dup2(pfd[0], STDIN_FILENO);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* close all descriptors in childpid[] */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < maxfd; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (childpid[i] > 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(i);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_exit(127);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;/* parent continues... */
&nbsp;&nbsp;&nbsp;&nbsp;if (*type == 'r') {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((fp = fdopen(pfd[0], type)) == NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(pfd[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((fp = fdopen(pfd[1], type)) == NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;childpid[fileno(fp)] = pid; /* remember child pid for this fd */
&nbsp;&nbsp;&nbsp;&nbsp;return(fp);
}


int
pclose(FILE *fp)
{
&nbsp;&nbsp;&nbsp;&nbsp;int     fd, stat;
&nbsp;&nbsp;&nbsp;&nbsp;pid_t   pid;

&nbsp;&nbsp;&nbsp;&nbsp;if (childpid == NULL) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errno = EINVAL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1);     /* popen() has never been called */
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;fd = fileno(fp);
&nbsp;&nbsp;&nbsp;&nbsp;if ((pid = childpid[fd]) == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errno = EINVAL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1);     /* fp wasn't opened by popen() */
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;childpid[fd] = 0;
&nbsp;&nbsp;&nbsp;&nbsp;if (fclose(fp) == EOF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1);

&nbsp;&nbsp;&nbsp;&nbsp;while (waitpid(pid, &stat, 0) < 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (errno != EINTR)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1); /* error other than EINTR from waitpid() */

&nbsp;&nbsp;&nbsp;&nbsp;return(stat);   /* return child's termination status */
}



APUE上也给出了这个代码。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP