亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1393 | 回復(fù): 0
打印 上一主題 下一主題

Linux中的system函數(shù)詳細(xì)分析 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-09-21 16:47 |只看該作者 |倒序?yàn)g覽
Linux中的system函數(shù)詳細(xì)分析system()函數(shù)功能強(qiáng)大,很多人用卻對它的原理知之甚少,也就有了上面
那么多的回帖,我想大家如果知道了system的具體實(shí)現(xiàn)就不會(huì)對樓主程序在很多編譯器中不能表現(xiàn)自己希望的功能感到費(fèi)解了。我對linux中的實(shí)現(xiàn)比較
了解,具體分析這個(gè),windows中的類似就不詳解了。
好了,先看linux版system函數(shù)的源碼:
  1. #include
  2. #include
  3. #include
  4. #include
  5. int system(const char * cmdstring)
  6. {
  7.     pid_t pid;
  8.     int status;
  9.     if(cmdstring == NULL){
  10.          
  11.          return (1);
  12.     }
  13.     if((pid = fork())<0){
  14.             status = -1;
  15.     }
  16.     else if(pid == 0){
  17.         execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
  18.         -exit(127); //子進(jìn)程正常執(zhí)行則不會(huì)執(zhí)行此語句
  19.         }
  20.     else{
  21.             while(waitpid(pid, &status, 0) < 0){
  22.                 if(errno != EINTER){
  23.                     status = -1;
  24.                     break;
  25.                 }
  26.             }
  27.         }
  28.         return status;
  29. }
復(fù)制代碼
先分析一下原理,然后再看上面的代碼大家估計(jì)就能看懂了:   
當(dāng)system接受的命令為NULL時(shí)直接返回,否則fork出一個(gè)子進(jìn)程,因?yàn)閒ork在兩個(gè)進(jìn)程:父進(jìn)程和子進(jìn)程中都返回,這里要檢查返回的
pid,fork在子進(jìn)程中返回0,在父進(jìn)程中返回子進(jìn)程的pid,父進(jìn)程使用waitpid等待子進(jìn)程結(jié)束,子進(jìn)程則是調(diào)用execl來啟動(dòng)一個(gè)程序代
替自己,execl("/bin/sh", "sh", "-c",
cmdstring,(char*)0)是調(diào)用shell,這個(gè)shell的路徑是/bin/sh,后面的字符串都是參數(shù),然后子進(jìn)程就變成了一個(gè)
shell進(jìn)程,這個(gè)shell的參數(shù)是cmdstring,就是system接受的參數(shù)。在windows中的shell是command,想必大家很
熟悉shell接受命令之后做的事了。
   
如果上面的你沒有看懂,那我再解釋下fork的原理:當(dāng)一個(gè)進(jìn)程A調(diào)用fork時(shí),系統(tǒng)內(nèi)核創(chuàng)建一個(gè)新的進(jìn)程B,并將A的內(nèi)存映像復(fù)制到B的進(jìn)程空間中,
因?yàn)锳和B是一樣的,那么他們怎么知道自己是父進(jìn)程還是子進(jìn)程呢,看fork的返回值就知道,上面也說了fork在子進(jìn)程中返回0,在父進(jìn)程中返回子進(jìn)程
的pid。
windows中的情況也類似,就是execl換了個(gè)又臭又長的名字,參數(shù)名也換的看了讓人發(fā)暈的,我在MSDN中找到了原型,給大家看看:
HINSTANCE   ShellExecute(
               HWND   hwnd,
               LPCTSTR   lpVerb,
               LPCTSTR   lpFile,
               LPCTSTR   lpParameters,
               LPCTSTR   lpDirectory,
               INT   nShowCmd
   );   
用法如下:  
    ShellExecute(NULL,   "open",   "c:\\a.reg",   NULL,   NULL,   SW_SHOWNORMAL);   
你也許會(huì)奇怪 ShellExecute中有個(gè)用來傳遞父進(jìn)程環(huán)境變量的參數(shù)
lpDirectory,linux中的execl卻沒有,這是因?yàn)閑xecl是編譯器的函數(shù)(在一定程度上隱藏具體系統(tǒng)實(shí)現(xiàn)),在linux中它會(huì)接著
產(chǎn)生一個(gè)linux系統(tǒng)的調(diào)用execve, 原型見下:
    int execve(const char * file,const char **argv,const char **envp);
   
看到這里你就會(huì)明白為什么system()會(huì)接受父進(jìn)程的環(huán)境變量,但是用system改變環(huán)境變量后,system一返回主函數(shù)還是沒變,這就是我在
22樓反復(fù)強(qiáng)調(diào)的。原因從system的實(shí)現(xiàn)可以看到,它是通過產(chǎn)生新進(jìn)程實(shí)現(xiàn)的,從我的分析中可以看到父進(jìn)程和子進(jìn)程間沒有進(jìn)程通信,子進(jìn)程自然改變不
了父進(jìn)程的環(huán)境變量。希望小菜們不要拿tc或使用tc庫的其他編譯器中的system的調(diào)用結(jié)果來反駁我,這不是一個(gè)概念,DOS早死翹翹了,玩
linux吧。就說到這里了。
               
               
               

本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u2/66576/showart_2056977.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP