作者:新浪微博(@NP等不等于P)

计算机学习微信公众号(jsj_xx)

c语言中的system函数可以说是程序执行时的一道重生之门,其重生妙效犹如我们之前《透析硬链接和软链接的区别》一文中的软链接文件。然而,system函数也带来了判断返回值的烦恼!本文分享我们对system函数的返回值的理解,希望对c语言学习者有所帮助(如有错误,还望指正,谢谢)。

先给出我们理解的system函数执行原理:

fork出子进程1,该子进程1通过execl来启动bash,bash会重新fork出一个子进程2去做实际的cmdstring命令,主进程会waitpid等待此子进程1的终结(潜在地,子进程1会等待子进程2)。

理解了这个执行过程,我们很容易完备枚举出system函数返回值的各个场景了。注意,我们在本文中会将此返回值分为高8bit和低8bit两部分(具体原因看完本文即可理解)。如果fork失败,则system返回-1(16bit的整体)。

如果execl失败(包括非法的bash和非法的cmdstring),则system返回高8bit的127。

如果waitpid失败但不是EINTR导致,则system返回-1(16bit的整体)且要设置errno。

如果waitpid失败且是EINTR导致,则system返回高8bit的0和低8bit的bash返回值(128+signal number)。

如果waitpid是成功的,则system返回高8bit的cmdstring的返回值和低8bit的0(0表示bash是正常终结的)。

通过上述5种情况,我们收获了关于返回值的以下启示:低8bit是bash的返回值,高8bit是cmdstring的返回值。

waitpid期间的EINTR返回也归入bash失败的场景。

waitpid期间的非EINTR终结以及fork失败归入整体失败的场景。

execl的失败归入cmdstring失败的场景。

可见,在fork+execl+waitpid不能完美终结的情况下,也要尽量靠近完美终结时的返回值方式:高低8bit分别(独立)存储cmdstring和bash的返回值,并且倾向于将失败场景归入cmdstring的失败。这种倾向性,无可厚非,毕竟求得cmdsting的返回值是system函数的核心业务。这样,cmdstring失败的错误码里预留了127给execl失败(或bash失败),也就是说cmdstring支持的返回值范围是[0..126]了,真是让人难以接受啊。。。

另外,我们看到,cmdstring的返回值是靠waitpid返回的,而此返回值经过了多道手:子进程2、子进程1、主进程,可谓繁琐至极(考虑换别的机制了?下次我们谈popen)。。。

综上,system函数的完美终结需要以下三个条件同时成立:(status代表system函数的返回值)

1)status != -1

2)bash正常终结【即低8bit为0,或者说:WIFEXITED(status)为true】

3)cmdstring正常终结【即高8bit为0,或者说:WEXITSTATUS(status)==0】

上述引入的两个宏,具体含义如下:WIFEXITED(status)

returns true if the child terminated normally, that is, by call‐

ing exit(3) or _exit(2), or by returning from main().

WEXITSTATUS(status)

returns  the  exit  status  of  the child.  This consists of the

least significant 8 bits of the status argument that  the  child

specified  in  a  call to exit(3) or _exit(2) or as the argument

for a return statement in main().This  macro  should  only  be

employed if WIFEXITED returned true.

可见,一个聚焦于bash的终结,一个聚焦于cmdstring的终结,各有分工,互有所赖:WEXITSTATUS(status)仅在WIFEXITED(status)为true时才能使用。

附上source code:(为方便理解,我们稍微做了修改)/* If WIFEXITED(STATUS), the low-order 8 bits of the status.  */

#define __WEXITSTATUS(status)   (((status) & 0xff00) >> 8)/* Nonzero if STATUS indicates normal termination.  */

#define __WIFEXITED(status) ((status & 0x7f) == 0)

另外,system函数里的waitpid函数还要和SIGCHLD信号的处理保持和谐共处:在主进程中需要mask SIGCHLD,waitpid之后再unmask SIGCHLD,这个mask/unmask处理是system函数内部完成的。否则,SIGCHLD的handler将完全可能破坏掉主进程的waitpid,从而无法保证system函数返回值的正确性了(考虑这个场景:system函数的调用者的SIG CHLD的handler里也调用了waitpid,这样就架空了system函数里的waitpid)。。。

计算机学习微信公众号(jsj_xx)

原创技术文章,感悟计算机,透彻理解计算机!

c语言system返回信息,理解c语言system函数的返回值相关推荐

  1. 视频教程-C语言-从汇编角度理解C语言的本质-C/C++

    C语言-从汇编角度理解C语言的本质 擅长JavaWeb开发,游戏逆向外挂与反外挂,游戏保护对抗 孙冉 ¥49.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...

  2. python使用numpy的np.power函数计算numpy数组中每个数值的指定幂次(例如平方、立方)、np.power函数默认返回整数格式、np.float_power函数默认返回浮点数

    python使用numpy的np.power函数计算numpy数组中每个数值的指定幂次(例如平方.立方).np.power函数默认返回整数格式.np.float_power函数默认返回浮点数 目录

  3. 职工工资信息系统 c语言题,工资信息管理系统C语言设计.doc

    工资信息管理系统C语言设计 C语言课程实习报告 学 院: 工程学院 专 业: 岩土工程 班 级: 052052-33 学 号: 20051002623 姓 名: 刘恒 第一题:工资信息管理系统 一`题 ...

  4. 课程管理系统c语言程序,课程信息管理系统C语言程序Word版

    <课程信息管理系统C语言程序Word版>由会员分享,可在线阅读,更多相关<课程信息管理系统C语言程序Word版(19页珍藏版)>请在人人文库网上搜索. 1.传播优秀Word版文 ...

  5. 学生成绩表c语言,学生成绩信息表(c语言程序)

    <学生成绩信息表(c语言程序)>由会员分享,可在线阅读,更多相关<学生成绩信息表(c语言程序)(16页珍藏版)>请在人人文库网上搜索. 1. include# include# ...

  6. 学生信息管理系统c语言讲解,学生信息管理系统C语言课程设计讲解.doc

    课 程 设 计 报 告 课程名称 C语言程序设计 课题名称 学生信息管理系统 专 业 机械 班 级 02 学 号 20 姓 名 刘某某 指导教师 肖伟平 何宏 郭芳 2012年 12 月 19 日 湖 ...

  7. 统计员工信息c语言设计,工资信息管理系统C语言设计

    <工资信息管理系统C语言设计>由会员分享,可在线阅读,更多相关<工资信息管理系统C语言设计(17页珍藏版)>请在人人文库网上搜索. 1.c语言课程实习报告学校:工程学院专业:岩 ...

  8. c 语言 函数返回数组_如何在C ++函数中返回数组

    c 语言 函数返回数组 介绍 (Introduction) In this tutorial, we are going to understand how we can return an arra ...

  9. python内置函数可以返回列表元组_Python内置函数()可以返回列表、元组、字典、集合、字符串以及range对象中元素个数....

    Python内置函数()可以返回列表.元组.字典.集合.字符串以及range对象中元素个数. 青岛远洋运输有限公司冷聚吉船长被评为全国十佳海员.()A:错B:对 有源逆变是将直流电逆变成其它频率的交流 ...

最新文章

  1. Android自定义View —— TypedArray
  2. Spring security防止跨站请求伪造(CSRF防护)
  3. BYOD安全保护的“原生态”方法
  4. deepin linux桌面设置,Deepin系统的桌面样式:高效模式和时尚模式
  5. python 元类工厂模式_Python进阶丨如何创建你的第一个Python元类?
  6. CopyOnWrite容器
  7. Python实现奖金计算两种方法的比较
  8. docker wsl2启动不了_Docker学习笔记
  9. [(转)hystar整理]Entity Framework 教程
  10. .Net Core 2.2升级3.1的避坑指南
  11. 职场潜规则:公司出现这三种信号,你必须果断辞职!
  12. AI大牛Jerry Kaplan:AGI?没有技术和工程基础
  13. Java - 多线程Callable、Executors、Future
  14. 基于jquery横向手风琴效果
  15. 使用 github + jekyll 搭建个人博客
  16. NYOJ--114--某种序列(大数)
  17. SQL 2016——新功能
  18. 全国大学生数学竞赛(非数学专业)习题精讲等相关资源
  19. 一文掌握大数据架构师需要具备的能力和格局
  20. android studio Emulator is outdated

热门文章

  1. java io流拒绝访问_JAVA IO流 - 张宏良的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. 判断计算机硬件和网络故障,计算机网络硬件的不同检测方法与维护
  3. asp毕业设计——基于asp+access的网上图书销售系统设计与实现设计与实现(毕业论文+程序源码)——网上图书销售系统
  4. springboot切面返回值_SpringBoot之切面AOP
  5. java readline 跳行_各种getline/readline的总结
  6. foss测试_什么是开源软件? 开源和FOSS解释
  7. Deepstream 6.1.1 以及 Python Binding Docker 安装
  8. [图示]做人36字诀:三)自我提升,教你拯救命运
  9. 【Java 总结思考】Java 答疑解惑之基础篇
  10. 软件工程复习之软件生命周期