023 UNIX再学习 -- 函数abort

                                          
                                                                                   
                                                                                
                                           

abort 函数之前有讲过的,参看:C语言再学习 -- 关键字return和exit ()函数

然后我们在讲 8 中进程终止时,也说过。参看:UNIX再学习 -- exit 和 wait 系列函数

下面来详细讲一下它。

一、函数 abort


   
   
  1. #include <stdlib.h>
  2. void abort(void);
  3. 此函数无返回值

1、函数功能

abort 函数的功能是使程序异常终止

2、函数解析

abort 函数首先解除进程对 SIGABRT 信号的阻止,然后向调用进程发送该信号。abort 函数会导致进程的异常终止除非 SIGABRT 信号被捕捉并且信号处理句柄没有返回。
如果 abort 函数导致进程终止,则所有打开的流都将关闭并刷新。
如果SIGABRT信号被忽略,或被返回的处理程序捕获,则abort()函数仍将终止进程。 它通过恢复 SIGABRT 的默认配置,然后再次发送信号来做到这一点。

3、abort 函数实现


   
   
  1. #include <signal.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. void
  6. abort (void)    /* POSIX-style abort() function */
  7. {
  8.   sigset_t   mask;
  9.   struct sigaction action;
  10.   /* Caller can't ignore SIGABRT, if so reset to default */
  11.  sigaction(SIGABRT, NULL, &action);
  12.   if (action.sa_handler == SIG_IGN) {
  13.   action.sa_handler = SIG_DFL;
  14.   sigaction(SIGABRT, &action, NULL);
  15.  }
  16.   if (action.sa_handler == SIG_DFL)
  17.   fflush( NULL);    /* flush all open stdio streams */
  18.   /* Caller can't block SIGABRT; make sure it's unblocked */
  19.  sigfillset(&mask);
  20.  sigdelset(&mask, SIGABRT);  /* mask has only SIGABRT turned off */
  21.  sigprocmask(SIG_SETMASK, &mask, NULL);
  22.  kill(getpid(), SIGABRT);  /* send the signal */
  23.   /* If we're here, process caught SIGABRT and returned */
  24.  fflush( NULL);     /* flush all open stdio streams */
  25.  action.sa_handler = SIG_DFL;
  26.  sigaction(SIGABRT, &action, NULL);  /* reset to default */
  27.  sigprocmask(SIG_SETMASK, &mask, NULL);  /* just in case ... */
  28.  kill(getpid(), SIGABRT);     /* and one more time */
  29.   exit( 1);  /* this should never be executed ... */
  30. }

4、函数实现解析

首先看是否将执行默认动作,若是则冲洗所有标准 I/O 流。这并不等价于对所有打开的流调用 fclose (因为只冲洗,并不关闭它们),但是当进程终止时,系统会关闭所有打开的文件。 如果进程捕捉此信号并返回,那么因为进程可能产生了更多的输出,所以再一次冲洗所有的流。不进行冲洗处理的唯一条件是如果进程捕捉此信号,然后调用 _exit 或 _Exit。这种情况下,任何未冲洗的内存中的标准 I/O 缓存都被丢弃。我们假定捕捉此信号,而且 _exit 或 _Exit 的调用者并不想要冲洗缓冲区。

5、示例说明


    
    
  1. //示例一
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <signal.h>
  6. void fa (int signo)
  7. {
  8.   printf ( "捕捉到了信号%d\n", signo);
  9. }
  10. int main (void)
  11. {
  12.  signal (SIGABRT, fa);
  13.   printf ( "1111111111111\n");
  14.   abort ();
  15.   printf ( "2222222222222\n");
  16.   return 0;
  17. }
  18. 输出结果:
  19. 1111111111111
  20. 捕捉到了信号 6
  21. 已放弃 (核心已转储)

    
    
  1. //示例二
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main ()
  5. {
  6.    FILE *fp;
  7.    
  8.     printf( "准备打开 nofile.txt\n");
  9.    fp = fopen( "nofile.txt", "r" );
  10.     if(fp == NULL)
  11.    {
  12.       printf( "准备终止程序\n");
  13.       abort();
  14.    }
  15.     printf( "准备关闭 nofile.txt\n");
  16.    fclose(fp);
  17.    
  18.     return( 0);
  19. }
  20. 输出结果:
  21. 如果没有 nofile.txt 文件则:
  22. 准备打开 nofile.txt
  23. 准备终止程序
  24. 已放弃 (核心已转储)

6、示例解析

调用 abort 函数,发送 SIGABRT 信号;abort 将所有打开的流都将关闭并刷新。
                                   
                                   
               
                   
  •                                                
  •                                                     点赞                         1                        
  •                        
  •                                                     收藏
  •                        
  •                                                     分享
  •                                                                                                                        
  •                                                        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值