linux exec函數家族


  1.exec家族一共有六個函數,分別是:

  (1)int execl(const char *path, const char *arg, ......);

  (2)int execle(const char *path, const char *arg, ...... , char * const envp[]);

  (3)int execv(const char *path, char *const argv[]);

  (4)int execve(const char *filename, char *const argv[], char *const envp[]);

  (5)int execvp(const char *file, char * const argv[]);

  (6)int execlp(const char *file, const char *arg, ......);

  其中只有execve是真正意義上的系統調用,其它都是在此基礎上經過包裝的庫函數。

     exec函數族的作用是根據指定的文件名找到可執行文件,並用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行文件這里的可執行文件既可以是二進制文件,也可以是任何Linux下可執行的腳本文件。

  與一般情況不同,exec函數族的函數執行成功后不會返回,因為調用進程的實體,包括代碼段,數據段和堆棧等都已經被新的內容取代,只留下進程ID等一些表面上的信息仍保持原樣,頗有些神似"三十六計"中的"金蟬脫殼"。看上去還是舊的軀殼,卻已經注入了新的靈魂。只有調用失敗了,它們才會返回一個-1,從原程序的調用點接着往下執行。

  

  2.它們之間的區別:

  1)前四個取路徑名做為參數,后兩個取文件名做為參數,如果文件名中不包含 / 則從PATH環境變量中搜尋可執行文件, 如果找到了一個可執行文件,但是該文件不是連接編輯程序產生的可執行代碼文件,則當做shell腳本處理。

  2)前兩個和最后一個函數中都包括“ l ”這個字母 ,而另三個都包括“ v ”, " l "代表 list即表 ,而" v "代表 vector即矢量,也是是前三個函數的參數都是以list的形式給出的,但最后要加一個空指針,如果用常數0來表示空指針,則必須將它強行轉換成字符指針,否則有可能出錯。,而后三個都是以矢量的形式給出,即數組。

  3)與向新程序傳遞環境變量有關,如第二個和第四個以e結尾的函數,可以向函數傳遞一個指向環境字符串指針數組的指針。即自個定義各個環境變量,而其它四個則使用進程中的環境變量。

 

  3.實例:

  1)在平時的編程中,如果用到了exec函數族,一定記得要加錯誤判斷語句。先判斷execl的返回值,如果出錯,可以用perror( )函數打印出錯誤信息。

  如:if (execl(path,..””(char *)0) < 0)

      {

           perror(“execl error!”);

     }

  如果調用出錯,可輸出:execl error!: 錯誤原因   這樣可方便查找出錯原因

  (2)注意下面書寫格式:

  先定義一個指針數組:char *argv[]={ls,-l,(char *)0}

  用execv調用ls:    execv(/bin/ls,argv)

   如果用execvp

  execvp(ls,argv)      //直接寫ls就可以了

  注意:

  execl調用shell 時,要在shell腳本中指明使用的shell版本:#/bin/bash。在命令行下執行shell腳本,系統為它自動打開一個shell,在程序中沒有shell,在調用shell腳本時,會出錯,所以要在shell腳本中先打開shell

 

  (3)

  1 #ifdef HAVE_CONFIG_H
  2 #include <config.h>
  3 #endif
  4 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <unistd.h>
  8 #include <string.h>
  9 #include <errno.h>
 10 
 11 int main(int argc, char *argv[])
 12 {
 13   //以NULL結尾的字符串數組的指針,適合包含v的exec函數參數
 14   char *arg[] = {"ls", "-a", NULL};
 15   
 16   /**
 17    * 創建子進程並調用函數execl
 18    * execl 中希望接收以逗號分隔的參數列表,並以NULL指針為結束標志
 19    */
 20   if( fork() == 0 )
 21   {
 22     // in clild 
 23     printf( "1------------execl------------\n" );
 24     if( execl( "/bin/ls", "ls","-a", NULL ) == -1 )
 25     {
 26       perror( "execl error " );
 27       exit(1);
 28     }
 29   }
 30   
 31   /**
 32    *創建子進程並調用函數execv
 33    *execv中希望接收一個以NULL結尾的字符串數組的指針
 34    */
 35   if( fork() == 0 )
 36   {
 37     // in child 
 38     printf("2------------execv------------\n");
 39     if( execv( "/bin/ls",arg) < 0)
 40     {
 41       perror("execv error ");
 42       exit(1);
 43     }
 44   }
 45   
 46   /**
 47    *創建子進程並調用 execlp
 48    *execlp中
 49    *l希望接收以逗號分隔的參數列表,列表以NULL指針作為結束標志
 50    *p是一個以NULL結尾的字符串數組指針,函數可以DOS的PATH變量查找子程序文件
 51    */
 52   if( fork() == 0 )
 53   {
 54     // in clhild 
 55     printf("3------------execlp------------\n");
 56     if( execlp( "ls", "ls", "-a", NULL ) < 0 )
 57     {
 58       perror( "execlp error " );
 59       exit(1);
 60     }
 61   }
 62   
 63   /**
 64    *創建子里程並調用execvp
 65    *v 望接收到一個以NULL結尾的字符串數組的指針
 66    *p 是一個以NULL結尾的字符串數組指針,函數可以DOS的PATH變量查找子程序文件
 67    */
 68   if( fork() == 0 )
 69   {
 70     printf("4------------execvp------------\n");
 71     if( execvp( "ls", arg ) < 0 )
 72     {
 73       perror( "execvp error " );
 74       exit( 1 );
 75     }
 76   }
 77   
 78   /**
 79    *創建子進程並調用execle
 80    *l 希望接收以逗號分隔的參數列表,列表以NULL指針作為結束標志
 81    *e 函數傳遞指定參數envp,允許改變子進程的環境,無后綴e時,子進程使用當前程序的環境
 82    */
 83   if( fork() == 0 )
 84   {
 85     printf("5------------execle------------\n");
 86     if( execle("/bin/ls", "ls", "-a", NULL, NULL) == -1 )
 87     {
 88       perror("execle error ");
 89       exit(1);
 90     }
 91   }
 92   
 93   /**
 94    *創建子進程並調用execve
 95    * v 希望接收到一個以NULL結尾的字符串數組的指針
 96    * e 函數傳遞指定參數envp,允許改變子進程的環境,無后綴e時,子進程使用當前程序的環境
 97    */
 98   if( fork() == 0 )
 99   {
100     printf("6------------execve-----------\n");
101     if( execve( "/bin/ls", arg, NULL ) == 0)
102     {
103       perror("execve error ");
104       exit(1);
105     }
106   }
107   return EXIT_SUCCESS;
108 }

  結果:

 1 1------------execl------------
 2 .  ..  .deps  exec  exec.o  .libs  Makefile
 3 2------------execv------------
 4 .  ..  .deps  exec  exec.o  .libs  Makefile
 5 3------------execlp------------
 6 .  ..  .deps  exec  exec.o  .libs  Makefile
 7 4------------execvp------------
 8 .  ..  .deps  exec  exec.o  .libs  Makefile
 9 5------------execle------------
10 .  ..  .deps  .libs  Makefile  exec  exec.o
11 6------------execve-----------
12 .  ..  .deps  .libs  Makefile  exec  exec.o
13 按回車繼續!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM