Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57702
  • 博文数量: 8
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 88
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-13 16:18
个人简介

不积跬步无以至千里,不积小流无以成江河。

文章分类
文章存档

2014年(8)

我的朋友

分类: 其他UNIX

2014-10-29 16:35:53





点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <signal.h>
  6. #include <sys/types.h>
  7. #include <fcntl.h>
  8. #include <errno.h>

  9. int status = 0;
  10. static void sig_chld(int signo){
  11.     wait(&status);
  12.     printf("status=[%x],pid=[%d]\n",status,getpid());
  13. }

  14. int mysystem(char * cmd) {
  15.     pid_t pid,wtpid;
  16.     int status = 0;
  17.     sigset_t add,save;
  18.     
  19.     sigemptyset(&add);
  20.     sigaddset(&add, SIGCHLD);
  21.     
  22.     sigprocmask(SIG_BLOCK, &add, &save);
  23. // sigprocmask(SIG_BLOCK, NULL, &save);
  24.     if ( 0 > ( pid = fork() )) {
  25.         printf("fork error\n");
  26.     }else if ( 0 == pid) {
  27.         sigprocmask(SIG_SETMASK, &save, NULL);
  28.         execl("/bin/sh","sh","-c",cmd,0);
  29.         _exit(0);
  30.     }
  31.     
  32.     while (0 > ( wtpid = waitpid(pid,&status,0) ) ) {
  33.         if (EINTR != errno) {
  34.             status = -1;
  35.             break;
  36.         }
  37.     }
  38.     
  39.     
  40.     if (0 > sigprocmask(SIG_SETMASK, &save, NULL) )
  41.         return -1;
  42.     
  43.     printf("wtpid=[%d]\n",wtpid);
  44.     return status;
  45. }
  46. /**
  47.  * systemz阻塞SIGCHLD的原因
  48.  *
  49.  * 这里如果mysystem不阻止SIGCHLD,那么在main进程中的sig_chld将会把mysystem创建的子进程的回收
  50.  * 使mysystem的wait返回-1,这样就出错了,所以防止这种情况发生,mysystem应该阻塞SIGCHLD,
  51.  * 还应该在使用mysystem前把SIGCHLD设置成默认或自定义,不能设置成忽略,要不一样wait返回-1
  52.  */
  53. int main(){
  54.     
  55.     pid_t pid;
  56.     signal(SIGCHLD,sig_chld);
  57.     
  58.     printf("main pid=[%d]\n",getpid());
  59.     if(0 > ( pid = fork() )){
  60.         printf("fork error\n");
  61.     }else if(0 == pid){ //子进程
  62.         printf("child pid=[%d]\n",getpid());
  63.         printf("ret=[%d]\n",mysystem("ls -alh /"));
  64.         _exit(0x77);
  65.     }
  66.     
  67.     pause();
  68.     return 0;
  69. }

sigprocmask
(SIG_BLOCK, NULL, &save) 打开时
输出:

点击(此处)折叠或打开

  1. main pid=[13389]
  2.  child pid=[13392]
  3.  
  4.  total 16621
  5.  drwxrwxr-t 32 root admin 1.1K Nov 18 15:51 .
  6.  drwxrwxr-t 32 root admin 1.1K Nov 18 15:51 ..
  7.  -rw-rw-r--@ 1 root admin 21K Nov 22 09:16 .DS_Store
  8.  
  9.  wtpid=[13393]
  10.  ret=[0]
  11.  status=[7700],pid=[13389]


sigprocmask(SIG_BLOCK, &add, &save)打开时
输出:

点击(此处)折叠或打开

  1. main pid=[13367]
  2.  child pid=[13370]
  3.  
  4.  total 16621
  5.  drwxrwxr-t 32 root admin 1.1K Nov 18 15:51 .
  6.  drwxrwxr-t 32 root admin 1.1K Nov 18 15:51 ..
  7.  -rw-rw-r--@ 1 root admin 21K Nov 22 09:16 .DS_Store

  8.  status=[0],pid=[13370]
  9.  wtpid=[-1]
  10.  ret=[-1]
  11.  status=[7700],pid=[13367]


当system不阻塞SIGCHLD的时候,main进程(主进程)如果自定义了SIGCHLD信号,并在SIGCHLD中使用了wait函数那么system就会返回出错。



阅读(2026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~