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

分享

隨手記...

 wuxinit_ 2022-06-24 發(fā)布于湖北

在學(xué)習(xí)資料滿天飛的大環(huán)境下,知識變得非常零散,,體系化的知識并不多,,這就導(dǎo)致很多人每天都努力學(xué)習(xí)到感動自己,最終卻收效甚微,,甚至放棄學(xué)習(xí),。我的使命就是過濾掉大量的無效信息,將知識體系化,,以短平快的方式直達(dá)問題本質(zhì),,把大家從大海撈針的痛苦中解脫出來。


在Linux上編寫C代碼經(jīng)常會用到shell指令,。常用的有三種方式,,我們一一道來。

1 system

最簡單的方式就是直接調(diào)用system接口,,該接口返回-1表示調(diào)用shell指令失敗,,返回127表示調(diào)用/bin/sh失敗,,命令執(zhí)行成功返回0,。

  1 #include <stdio.h>
  2
  3 int main(void)
  4 {
  5         int ret = 0;
  6
  7         ret = system("touch test");
  8         printf("cmd ret = %d.\n", ret);
  9
 10         return 0;
 11 }

事實上事情并沒有這么簡單,在調(diào)用system期間,,SIGINT和SIGQUIT會被忽略,,這就要求盡量不要在死循環(huán)中調(diào)用system,否則就一定要對返回值做相應(yīng)處理,,man手冊中有代碼示例,。

此外,,還需要注意對SIGCHLD的處理。

system的實現(xiàn)主要是三步:

  • 調(diào)用fork創(chuàng)建子進(jìn)程,。
  • 調(diào)用execl函數(shù)運行shell程序解析指令并執(zhí)行,。
  • 調(diào)用waitpid函數(shù)等待給子進(jìn)程收尸。

由于waitpid函數(shù)執(zhí)行成功的前提是對SIGCHLD的處理不能是SIGIGN,,否則會產(chǎn)生ECHILD錯誤,。

所以,最保險的做法如下:

  1 #include <stdio.h>//erold_sighandler = signal(SIGCHLD, SIG_DFL);
  2 #include <signal.h>
  3
  4 typedef void (*sighandler_t)(int);
  5
  6
  7 int main(void)
  8 {
  9         int ret = 0;
 10         sighandler_t old_sighandler;
 11
 12         //old_sighandler = signal(SIGCHLD, SIG_IGN);    //err
 13         old_sighandler = signal(SIGCHLD, SIG_DFL);
 14         if (SIG_ERR == old_sighandler)
 15                 return -1;
 16         ret = system("touch test");
 17         if (0 != ret) {
 18                 printf("cmd ret = %d.\n", ret);
 19                 perror("");
 20                 return -2;
 21         }
 22         signal(SIGCHLD, old_sighandler);
 23
 24         return 0;
 25 }

2 popen

第二種方式就是使用popen,。該函數(shù)內(nèi)部也會調(diào)用fork產(chǎn)生子進(jìn)程,,然后在子進(jìn)程中通過exec運行/bin/sh。比起system來更靈活一些,,可以創(chuàng)建管道,,與子進(jìn)程進(jìn)行通信。但是,,本質(zhì)上和system的實現(xiàn)是一致的,。

  1 #include <stdio.h>
  2
  3 int main(void)
  4 {
  5         FILE *pfile = NULL;
  6         char buff[500] = {0};
  7
  8         pfile = popen("touch test.txt", "w");
  9         pclose(pfile);
 10
 11         pfile = popen("ls -al", "r");
 12         if (NULL == pfile)
 13                 return -1;
 14         fgets(buff, sizeof(buff), pfile);
 15
 16         printf("%s");
 17
 18         pclose(pfile);
 19
 20         return 0;
 21 }

3 exec

前兩種方式其實都是本種方式的封裝,用起來更方便而已,。

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4
  5 int main(void)
  6 {
  7         int child_pid = 0;
  8         char * argv[] = {"sh", "-c" , "ls -al .", NULL};
  9
 10         if (0 == vfork()) {//child process
 11
 12                 if (execv("/bin/sh", argv) < 0) {
 13                         perror("");
 14                         exit(-1);
 15                 }
 16
 17         } else { //parent
 18                 wait(&child_pid);
 19                 printf("child pid done.\n");
 20         }
 21
 22         return 0;
 23 }

4 該選擇哪種方式

最簡單的方式就是使用system接口,,但是需要注意對返回值的判斷和errno的解析。如果想和子進(jìn)程進(jìn)行通信(比如想拿到指令執(zhí)行后的輸出),,就考慮使用popen方式,,但由于子進(jìn)程直接繼承了父進(jìn)程的環(huán)境變量,據(jù)說是不安全的(對于系統(tǒng)安全這塊還沒有研究,,感興趣的可以深入下),。如果是讀執(zhí)行效率有一定要求(vfork比fork執(zhí)行效率高),或者想改造/擴(kuò)展上述接口功能,,則可以使用exec族函數(shù)自己實現(xiàn),。


恭喜你又堅持看完了一篇博客,又進(jìn)步了一點點,!如果感覺還不錯就點個贊再走吧,,你的點贊和關(guān)注將是我持續(xù)輸出的噠噠噠動力~~

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多