c语言system返回信息,理解c语言system函数的返回值

c语言system返回信息,理解c语言system函数的返回值作者:新浪微博(@NP等不等于P)计算机学习微信公众号(jsj_xx)c语言中的system函数可以说是程序执行时的一道重生之门,其重生妙效犹如我们之前《透析硬链接和软链接的区别》一文中的软链接文件。然而,system函数也带来了判断返回值的烦恼!本文分享我们对system函数的返回值的理解,希望对c语言学习者有所帮助(如有错误,还望指正,谢谢)。先给出我们理解的system函数执行原理:fork…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

作者:新浪微博(@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)

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192203.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 全新企业发卡系统源码/带有代理功能发卡平台源码[通俗易懂]

    全新企业发卡系统源码/带有代理功能发卡平台源码[通俗易懂]☑️编号:ym286☑️品牌:无☑️语言:PHP☑️大小:105MB☑️类型:企业发卡系统☑️支持:pc+wap????欢迎免费领取(注明编号)????✨源码介绍全新企业发卡系统源码,带有代理功能的发卡平台源码,目前应该算是最完美的一款了,亲测可运营。并且多套模板可以切换,有需要的自取吧。更新说明:支付界面短链接二维码后台模板等修复及一些细节优化pc用户端后台稍微美化(颜色调整)安卓用户端后台界面UI美化重写,商户头像根据QQ获取Admin后台登录页面重写(

    2022年7月14日
    28
  • python字典和json字符串相互转化的方法_pythonjson文件存储

    python字典和json字符串相互转化的方法_pythonjson文件存储序列化与反序列化按照某种规则,把内存中的数据保存到文件中,文件是一个字节序列,所以必须要把内存数据转换成为字节序列,输出到文件,这就是序列化;反之,从文件的字节恢复到内存,就是反序列化;pytho

    2022年7月29日
    9
  • java 集合

    java 集合一、java集合:1.collection接口的子接口:set接口跟list接口2.map接口的实现类:hashMap、hashTable、concurrentHashMap、hashTable、

    2022年7月1日
    29
  • 你的礼物

    你的礼物你的礼物

    2022年4月23日
    35
  • SecureCRT SSH远程连接出现connection was reset或者connection closed

    SecureCRT SSH远程连接出现connection was reset或者connection closedSecureCRT SSH远程连接出现connection was reset或者connection closed

    2022年4月24日
    235
  • 怪盗基德的滑翔翼(最长上升子序列)「建议收藏」

    怪盗基德的滑翔翼(最长上升子序列)「建议收藏」最长上神子序列(nlogn)原题链接怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为目标的超级盗窃犯。而他最为突出的地方,就是他每次都能逃脱中村警部的重重围堵,而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼。有一天,怪盗基德像往常一样偷走了一颗珍贵的钻石,不料却被柯南小朋友识破了伪装,而他的滑翔翼的动力装置也被柯南踢出的足球破坏了。不得已,怪盗基德只能操作受损的滑翔翼逃脱。假设城市中一共有N幢建筑排成一条线,每幢建筑的高度各不相同。初始时,怪盗基德可以在任何一幢建筑的顶端。他可以选择一个

    2022年8月8日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号