《unix高级环境编程》信号——abort、system和sleep函数

abort函数

  abort 函数的功能是使异常终止,此函数将 SIGABRT 信号发送给调用进程,让进程捕捉 SIGABRT 信号目的是在进程终止之前由其执行所需的清理操作。默认情况是终止调用进程。该函数实现如下: 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <signal.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5.   
  6. void Mabort(void)  
  7. {  
  8.     sigset_t mask;  
  9.     struct sigaction action;  
  10.   
  11.     /* 
  12.      * caller can't ignore SIGABRT, if so reset to default. 
  13.      */  
  14.     sigaction(SIGABRT, NULL, &action);  
  15.     if(action.sa_handler == SIG_IGN)  
  16.     {  
  17.         action.sa_handler = SIG_DFL;  
  18.         sigaction(SIGABRT, &action, NULL);  
  19.     }  
  20.   
  21.     if(action.sa_handler == SIG_DFL)  
  22.         fflush(NULL);  
  23.     /* 
  24.      * caller can't block SIGABRT; make sure it's unblock 
  25.      */  
  26.     sigfillset(&mask);  
  27.     sigdelset(&mask, SIGABRT);  /* mask has only SIGABRT turned off */  
  28.     sigprocmask(SIG_SETMASK, &mask, NULL);  
  29.     kill(getpid(), SIGABRT);    /* send the signal */  
  30.   
  31.     fflush(NULL);   /* flush all open stdio stream */  
  32.     action.sa_handler = SIG_DFL;  
  33.     sigaction(SIGABRT, &action, NULL);  /* reset to default */  
  34.     sigprocmask(SIG_SETMASK, &mask, NULL);  /* just in case ... */  
  35.     kill(getpid(), SIGABRT);    /* and one more time */  
  36.     exit(1);    /* this should never be executed ... */  
  37. }  
  38.   
  39. static void sig_abort(int signo)  
  40. {  
  41.     printf("Recevied abort ...\n");  
  42. }  
  43. int main(void)  
  44. {  
  45.     signal(SIGABRT, sig_abort);  
  46.     Mabort();  
  47.     pause();  
  48.     exit(0);  
  49. }  
输出结果:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Recevied abort ...  
  2. Aborted (core dumped)  

system函数

  这里和之前介绍的《system函数》有区别,增加了信号处理机制。POSIX.1要求 system 函数忽略 SIGINT 和 SITQUIT 信号,阻塞 SIGCHLD。system 函数实现如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/types.h>  
  5. #include <errno.h>  
  6. #include <signal.h>  
  7. #include <sys/wait.h>  
  8.   
  9. int Msystem(const char*cmdstring)  
  10. {  
  11.     pid_t   pid;  
  12.     int     status;  
  13.     struct  sigaction   ignore,saveintr,savequit;  
  14.     sigset_t    chldmask,savemask;  
  15.   
  16.     if(cmdstring == NULL)  
  17.         return 1;  
  18.     ignore.sa_handler = SIG_IGN;  
  19.     sigemptyset(&ignore.sa_mask);  
  20.     ignore.sa_flags = 0;  
  21.     if(sigaction(SIGINT,&ignore,&savequit)<0)  
  22.     {  
  23.         perror("sigaction() error");  
  24.         exit(-1);  
  25.     }  
  26.     if(sigaction(SIGQUIT,&ignore,&savequit) <0)  
  27.     {  
  28.         perror("sigaction() error");  
  29.         exit(-1);  
  30.     }  
  31.     sigemptyset(&chldmask);  
  32.     sigaddset(&chldmask,SIGCHLD);  
  33.     if(sigprocmask(SIG_BLOCK,&chldmask,&savemask) < 0)  
  34.     {  
  35.         perror("sigprocmask() error");  
  36.         exit(-1);  
  37.     }  
  38.     if((pid = fork()) == -1)  
  39.     {  
  40.         perror("fork() error");  
  41.         exit(-1);  
  42.     }  
  43.     else if(pid == 0)  
  44.     {  
  45.         sigaction(SIGINT,&saveintr,NULL);  
  46.         sigaction(SIGQUIT,&savequit,NULL);  
  47.         sigprocmask(SIG_SETMASK,&savemask,NULL);  
  48.         execl("/bin/sh","sh","-c",cmdstring,(char *)0);  
  49.         _exit(-127);  
  50.     }  
  51.     else  
  52.     {  
  53.         while(waitpid(pid,&status,0) < 0)  
  54.         {  
  55.             if(errno != EINTR)  
  56.             {  
  57.                 status = -1;  
  58.                 break;  
  59.             }  
  60.         }  
  61.     }  
  62.     if (sigaction(SIGINT,&saveintr,NULL)<0)  
  63.         return -1;  
  64.     if (sigaction(SIGQUIT,&saveintr,NULL)<0)  
  65.         return -1;  
  66.     if (sigprocmask(SIG_SETMASK,&savemask,NULL)<0)  
  67.         return -1;  
  68.     return (status);  
  69. }  
  70.   
  71. int main()  
  72. {  
  73.     printf("Print date:\n");  
  74.     Msystem("date");  
  75.     printf("Print process:\n");  
  76.     Msystem("ps");  
  77.     exit(0);  
  78. }  
输出结果:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Print date:  
  2. Sun Nov  9 21:45:37 CST 2014  
  3. Print process:  
  4.   PID TTY          TIME CMD  
  5. 15133 pts/3    00:00:00 bash  
  6. 16236 pts/3    00:00:00 sigsuspend  
  7. 17750 pts/3    00:00:00 system  
  8. 17752 pts/3    00:00:00 ps  

sleep函数

        此函数使调用进程被挂起,直到满足下列条件之一:

  1. 已经过 seconds 所指定的墙上时钟时间;
  2. 调用进程捕捉到一个信号并从信号处理程序返回。
sleep 函数的实现如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/types.h>  
  5. #include <errno.h>  
  6. #include <signal.h>  
  7.   
  8. static void sig_alrm(int signo)  
  9. {  
  10.     printf("Recevied alarm ... \n");  
  11. }  
  12.   
  13. unsigned int Msleep(unsigned int nsecs)  
  14. {  
  15.     struct sigaction    newact,oldact;  
  16.     sigset_t            newmask,oldmask,suspmask;  
  17.     unsigned int        unslept;  
  18.   
  19.     newact.sa_handler = sig_alrm;  
  20.     sigemptyset(&newact.sa_mask);  
  21.     newact.sa_flags = 0;  
  22.     sigaction(SIGALRM,&newact,&oldact);  
  23.     sigemptyset(&newmask);  
  24.     sigaddset(&newmask,SIGALRM);  
  25.     sigprocmask(SIG_BLOCK,&newmask,&oldmask);  
  26.     alarm(nsecs);  
  27.     suspmask = oldmask;  
  28.     sigdelset(&suspmask,SIGALRM);  
  29.     sigsuspend(&suspmask);  
  30.     unslept = alarm(0);  
  31.     sigprocmask(SIG_SETMASK,&oldmask,NULL);  
  32.     return unslept;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     int i;  
  38.     printf("Program starting.\n");  
  39.     printf("sleep 5 seconds.....\n");  
  40.     for(i=1;i<=5;++i)  
  41.     {  
  42.         printf("The %dth second.\n",i);  
  43.         Msleep(1);  
  44.     }  
  45.     printf("wake up.\n");  
  46.     exit(0);  
  47. }  
输出结果:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Program starting.  
  2. sleep 5 seconds.....  
  3. The 1th second.  
  4. Recevied alarm ...   
  5. The 2th second.  
  6. Recevied alarm ...   
  7. The 3th second.  
  8. Recevied alarm ...   
  9. The 4th second.  
  10. Recevied alarm ...   
  11. The 5th second.  
  12. Recevied alarm ...   
  13. wake up.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值