《unix高级环境编程》进程控制——system函数

来源:互联网 发布:seo自学论坛 编辑:程序博客网 时间:2024/06/05 04:10

system函数

system 函数能够执行函数中参数的命令,实现如下:

[cpp] view plaincopy
  1. /* system 函数 */  
  2. #include <stdlib.h>  
  3. int system(const char *cmdstring);  
首先我们看下该函数的具体实现:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /* system 函数的实现 */  
  2. #include "apue.h"  
  3. #include <sys/wait.h>  
  4.   
  5. int system(const char *cmdstring)  
  6. {  
  7.     pid_t pid;  
  8.     int status;  
  9.   
  10.     if(NULL == cmdstring)  
  11.         return -1;  
  12.     if((pid = fork()) < 0)  
  13.         status = -1;  
  14.     else if(0 == pid)  
  15.     {  
  16.         execl("/bin/sh""sh""-c""cmdstring", (char *)0);  
  17.         _exit(127);  
  18.     }  
  19.     else  
  20.     {  
  21.         while(waitpid(pid,&status,0) < 0)  
  22.         {  
  23.             if(errno != EINTR)  
  24.             {  
  25.                 status = -1;  
  26.                 break;  
  27.             }  
  28.         }  
  29.     }  
  30.     return status;  
  31. }  
  从该函数的实现我们可以知道,在现有进程中调用 fork 函数创建新的子进程,在 fork 所返回的子进程中调用 execl 函数执行参数字符命令,在 fork 所返回父进程中调用 waitpid 函数等待进程终止;因此有下面的三个返回值:

  1. 如果 fork 失败或者 waitpid 返回值除 EINTR 之外的出错,则 system 返回-1,而且 errno 中设置了错误类型值;
  2. 如果 exec 失败(表示不能执行 shell),其返回值如同 shell 执行 exit(127)一样;
  3. 否则所有三个函数(fork、exec、waitpid)都执行成功,并且system 的返回值是 shell 的终止状态;
测试程序:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <sys/wait.h>  
  2. #include "apue.h"  
  3.   
  4. void pr_exit(int status)  
  5. {  
  6.     if(WIFEXITED(status))  
  7.         printf("normal termination, exit status = %d\n", WEXITSTATUS(status));  
  8.     else if(WIFSIGNALED(status))  
  9.         printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status),  
  10. #ifdef WCOREDUMP  
  11.                 WCOREDUMP(status) ? "(core file generated)" : " ");  
  12. #else  
  13.     " ");  
  14. #endif  
  15.   
  16.     else if(WIFSTOPPED(status))  
  17.         printf("child stoped, signal number = %d\n", WSTOPSIG(status));  
  18. }  
  19.   
  20. int main(void)  
  21. {  
  22.     int status;  
  23.   
  24.     if((status = system("date")) < 0)  
  25.         err_sys("system error");  
  26.     pr_exit(status);  
  27.   
  28.     if((status = system("nosuchcommand")) < 0)  
  29.         err_sys("system error");  
  30.     pr_exit(status);  
  31.   
  32.     if((status = system("stat;who; exit 44")) < 0)  
  33.         err_sys("system error");  
  34.     pr_exit(status);  
  35.   
  36.     exit(0);  
  37. }  
返回值:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Fri Nov  7 19:19:17 CST 2014  
  2. normal termination, exit status = 0  
  3. sh: nosuchcommand: command not found  
  4. normal termination, exit status = 127  
  5. stat: missing operand  
  6. Try `stat --help' for more information.  
  7. nifengweijifen tty7         2014-11-07 08:44  
  8. nifengweijifen pts/1        2014-11-07 08:57 (:0.0)  
  9. nifengweijifen pts/4        2014-11-07 14:44 (:0.0)  
  10. normal termination, exit status = 44  
测试程序2:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <sys/wait.h>  
  2. #include "apue.h"  
  3.   
  4. void pr_exit(int status)  
  5. {  
  6.     if(WIFEXITED(status))  
  7.         printf("normal termination, exit status = %d\n", WEXITSTATUS(status));  
  8.     else if(WIFSIGNALED(status))  
  9.         printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status),  
  10. #ifdef WCOREDUMP  
  11.                 WCOREDUMP(status) ? "(core file generated)" : " ");  
  12. #else  
  13.     " ");  
  14. #endif  
  15.   
  16.     else if(WIFSTOPPED(status))  
  17.         printf("child stoped, signal number = %d\n", WSTOPSIG(status));  
  18. }  
  19.   
  20. int main(int argc, char *argv[])  
  21. {  
  22.     int status;  
  23.     if(argc != 2)  
  24.     {  
  25.         printf("usage: a.out <cmdstring>\n");  
  26.         exit(1);  
  27.     }  
  28.     status = system(argv[1]);  
  29.     pr_exit(status);  
  30.   
  31.     exit(0);  
  32. }  
以上程序可以根据自己需要输入要执行的字符命令参数。假设编译成可执行文件 system,例如输入./system date,输出如下:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Fri Nov  7 19:28:43 CST 2014  
  2. normal termination, exit status = 0  
0 0