久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

【C/C++】Linux下使用system()函數(shù)一定要謹(jǐn)慎

 ColonelLee 2012-08-06
曾經(jīng)的曾經(jīng),,被system()函數(shù)折磨過(guò),,之所以這樣,是因?yàn)閷?duì)system()函數(shù)了解不夠深入,。只是簡(jiǎn)單的知道用這個(gè)函數(shù)執(zhí)行一個(gè)系統(tǒng)命令,,這遠(yuǎn)遠(yuǎn)不夠,它的返回值,、它所執(zhí)行命令的返回值以及命令執(zhí)行失敗原因如何定位,,這才是重點(diǎn)。當(dāng)初因?yàn)檫@個(gè)函數(shù)風(fēng)險(xiǎn)較多,,故拋棄不用,,改用其他的方法。這里先不說(shuō)我用了什么方法,,這里必須要搞懂system()函數(shù),,因?yàn)檫€是有很多人用了system()函數(shù),有時(shí)你不得不面對(duì)它,。

先來(lái)看一下system()函數(shù)的簡(jiǎn)單介紹:
1 #include <stdlib.h>
2 int system(const char *command);

system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

system()函數(shù)調(diào)用/bin/sh來(lái)執(zhí)行參數(shù)指定的命令,,/bin/sh 一般是一個(gè)軟連接,指向某個(gè)具體的shell,,比如bash,,-c選項(xiàng)是告訴shell從字符串command中讀取命令;
在該command執(zhí)行期間,,SIGCHLD是被阻塞的,,好比在說(shuō):hi,內(nèi)核,,這會(huì)不要給我送SIGCHLD信號(hào),,等我忙完再說(shuō);
在該command執(zhí)行期間,,SIGINT和SIGQUIT是被忽略的,,意思是進(jìn)程收到這兩個(gè)信號(hào)后沒(méi)有任何動(dòng)作,。

再來(lái)看一下system()函數(shù)返回值:
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2). Thus, the exit code of the command will be WEXITSTATUS(status). In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127).
If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not.
為了更好的理解system()函數(shù)返回值,需要了解其執(zhí)行過(guò)程,,實(shí)際上system()函數(shù)執(zhí)行了三步操作:
1.fork一個(gè)子進(jìn)程,;
2.在子進(jìn)程中調(diào)用exec函數(shù)去執(zhí)行command;
3.在父進(jìn)程中調(diào)用wait去等待子進(jìn)程結(jié)束,。
對(duì)于fork失敗,,system()函數(shù)返回-1。
如果exec執(zhí)行成功,,也即command順利執(zhí)行完畢,,則返回command通過(guò)exit或return返回的值。
(注意,,command順利執(zhí)行不代表執(zhí)行成功,,比如command:"rm debuglog.txt",不管文件存不存在該command都順利執(zhí)行了)
如果exec執(zhí)行失敗,,也即command沒(méi)有順利執(zhí)行,,比如被信號(hào)中斷,或者command命令根本不存在,,system()函數(shù)返回127.
如果command為NULL,,則system()函數(shù)返回非0值,一般為1.

看一下system()函數(shù)的源碼
看完這些,,我想肯定有人對(duì)system()函數(shù)返回值還是不清楚,,看源碼最清楚,下面給出一個(gè)system()函數(shù)的實(shí)現(xiàn):
01 int system(const char * cmdstring)
02 {
03     pid_t pid;
04     int status;
05   
06 if(cmdstring == NULL)
07 {
08     return (1); //如果cmdstring為空,,返回非零值,,一般為1
09 }
10   
11 if((pid = fork())<0)
12 {
13     status = -1; //fork失敗,,返回-1
14 }
15 else if(pid == 0)
16 {
17     execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
18     _exit(127); // exec執(zhí)行失敗返回127,,注意exec只在失敗時(shí)才返回現(xiàn)在的進(jìn)程,成功的話現(xiàn)在的進(jìn)程就不存在啦~~
19 }
20 else //父進(jìn)程
21 {
22     while(waitpid(pid, &status, 0) < 0)
23     {
24         if(errno != EINTR)
25         {
26             status = -1; //如果waitpid被信號(hào)中斷,,則返回-1
27             break;
28         }
29     }
30 }
31   
32     return status; //如果waitpid成功,,則返回子進(jìn)程的返回狀態(tài)
33 }

仔細(xì)看完這個(gè)system()函數(shù)的簡(jiǎn)單實(shí)現(xiàn),那么該函數(shù)的返回值就清晰了吧,,那么什么時(shí)候system()函數(shù)返回0呢,?只在command命令返回0時(shí),。

看一下該怎么監(jiān)控system()函數(shù)執(zhí)行狀態(tài)
這里給我出的做法:
01 int status;
02 if(NULL == cmdstring) //如果cmdstring為空趁早閃退吧,,盡管system()函數(shù)也能處理空指針
03 {
04     return XXX;
05 }
06 status = system(cmdstring);
07 if(status < 0)
08 {
09     printf("cmd: %s\t error: %s", cmdstring, strerror(errno)); // 這里務(wù)必要把errno信息輸出或記入Log
10     return XXX;
11 }
12   
13 if(WIFEXITED(status))
14 {
15     printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring執(zhí)行結(jié)果
16 }
17 else if(WIFSIGNALED(status))
18 {
19     printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //如果cmdstring被信號(hào)中斷,,取得信號(hào)值
20 }
21 else if(WIFSTOPPED(status))
22 {
23     printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //如果cmdstring被信號(hào)暫停執(zhí)行,取得信號(hào)值
24 }

到于取得子進(jìn)程返回值的相關(guān)介紹可以參考另一篇文章:http://my.oschina.net/renhc/blog/35116

 

system()函數(shù)用起來(lái)很容易出錯(cuò),,返回值太多,,而且返回值很容易跟command的返回值混淆。這里推薦使用popen()函數(shù)替代,,關(guān)于popen()函數(shù)的簡(jiǎn)單使用也可以通過(guò)上面的鏈接查看,。

popen()函數(shù)較于system()函數(shù)的優(yōu)勢(shì)在于使用簡(jiǎn)單,popen()函數(shù)只返回兩個(gè)值:
成功返回子進(jìn)程的status,,使用WIFEXITED相關(guān)宏就可以取得command的返回結(jié)果,;
失敗返回-1,我們可以使用perro()函數(shù)或strerror()函數(shù)得到有用的錯(cuò)誤信息,。

這篇文章只涉及了system()函數(shù)的簡(jiǎn)單使用,,還沒(méi)有談及SIGCHLD、SIGINT和SIGQUIT對(duì)system()函數(shù)的影響,,事實(shí)上,之所以今天寫(xiě)這篇文章,,是因?yàn)轫?xiàng)目中因有人使用了system()函數(shù)而造成了很嚴(yán)重的事故?,F(xiàn)像是system()函數(shù)執(zhí)行時(shí)會(huì)產(chǎn)生一個(gè)錯(cuò)誤:“No child processes”。

關(guān)于這個(gè)錯(cuò)誤的分析,,將會(huì)專門(mén)寫(xiě)一篇文章分析,。

 

2012-04-14 任洪彩 [email protected]

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多