本文共 5313 字,大约阅读时间需要 17 分钟。
1、exec()函数执行一个新的程序 exec()函数原型如下 int execl(cons char *pathname, const char *arg0,....);int execle(const char *pathname, const char *arg0,..../*char *const envp[]*/);
int execv(const char *pathname,char *const argv[];
int execve(const char *pathname,char *const argv[],char *const envp[]);
int execlp(const char *filename,const char *arro,...);
int execvp(const char *filename, char *const argv[]); "l"表示list,说明执行程序的命令行参数以列表的方式提供,并且以NULL结尾,但是没有参数个数限制。 "v"表示vector,说明命令行参数要以二维数组的形式提供给新程序,这个数组的每一行是一个命令参数。 "e"表示传递给新程序的环境变量,这个列表是一个二维数组,每一行是一个环境变量。如果没有显示地传递一个环境 表量表,那么新程序将复制父进程的环境表。 以p结尾的exec()函数表示第一个参数不是完整的路径名,而是一个程序名。 返回值:如果成功不返回任何值,如失败则返回-1。 例:#include执行了exec()函数的进程不改变以下进程特征 1、进程ID和父进程ID 2、实际用户ID和实际组ID 3、进程组ID和附加组ID 4、控制终端 5、会话ID 6、时钟余留时间 7、当前工作目录和根目录。 8、文件创建屏蔽字和文件锁 9、信号屏蔽字和未处理信号集 10、资源限制。#include #include #include #include int main(void){ pid_t pid; pid = fork(); if(pid<0){ printf("fail to fork\n"); exit(0); }else if(pid == 0){ if(execvp("./hello",NULL) < 0) { printf("fail to exec\n"); printf("%s\n",strerror(errno)); exit(errno); } printf("the child is not hello\n"); exit(errno); } printf("the parent\n"); return 0;}$lshell.c hello hello.c test test.c$./test the parenthello
改变
1、有效用户ID和有效组ID 2、在程序中执行shell命令system()函数调用shell指令
#include<stdlib.h> int system(const char * cmdstring) 参数cmdstring是需要执行的shell命令。 system的返回值的情况比较复杂,system()函数是一个库函数,其中封装了fork、exec和waitpid这个3个系统, 其返回值也要根据这3个系统调用的情况来讨论1、如果fork()函数和waitpid函数执行失败,则system()函数返回-1
2、如果exec()函数执行失败,system()函数返回如图shell调用了exit(127)一样,表示指定文件不可执行
3、如果3个函数都成功执行,system()函数返回执行程序的终止状态,其值和echo $?的值是一样的。
4、如果参数cmdstring所指向的命令字符串为NULL,system()函数返回1。
例:#include$gcc system.c -o system $./system#include #include #include #define MAX 1024int main(void){ int fd,n; char buf[MAX]; if(system("ls > temp.txt") == -1) { perror("fail to exec command\n"); exit(0); } if(fd = open("temp.txt",O_RDWR) == -1) { perror("fail to open\n"); exit(1); } if(fd = read(fd,buf,MAX) == -1){ perror("fail to read\n"); exit(1); } buf[n] = '\0'; printf("%s",buf); return 0;}
temp.txt
system.c
system 3、等待进程退出操作 a、wait()函数得到子进程的结束信息。
#include<sys/wait.h>
pid_t wait(int *statloc);
调用wait()函数的进程会阻塞,直到该进程的任意一个子进程结束。wait()函数会取得结束的子进程的信息并返回子进程的进程ID,结束信息保存在参数statloc所指向的内存空间中,如果该进程没有子进程,则立即出错返回,返回值为-1.
状态 判断宏 取得宏 进程正常结束 WIFEXITED(status) WEXITSTATUS(status) 进程异常结束 WIFSIGNALED(status) WTERMSIG(status) 进程暂停 WIFSTOPPED(status) WSTOPSIG(status)例:
#include#include #include #include int main(void){ pid_t pid; int num,status; pid = fork(); if(pid<0){ printf("fail to fork\n"); exit(0); }else if(pid == 0) { printf("the fist, exit normally\n"); exit(0); }else { if(wait(&status) == -1) { perror("fail to wait"); exit(1); } if(WIFEXITED(status) == 1) { printf("the status of first is :%d\n",WEXITSTATUS(status)); } } pid = fork(); if(pid<0) { printf("fail to fork\n"); exit(0); }else if(pid == 0) { printf("the second, exit abnormally\n"); num = 1/0; }else { if(wait(&status) == -1){ perror("fail to wait"); exit(1); } if(WIFEXITED(status) == 1) { printf("the terminated signal is :%d\n",WEXITSTATUS(status)); } } return 0;}
$gcc wait.c -o wait $./wait the first ,exot normally the stasus of first is:0 the second,exit abnormally the terminated signal is:8
b、#include<sys/wait.h>
pid_t waitpid(pid_t pid, int *statloc,int options); pid :指定要等待的子进程的进程ID,其还有一些其他作用,如 -1 : 等待任意子进程 >0: 等待进程ID和pid相等的子进程 0: 等待组ID和pid相等的子进程 <-1: 等待组ID等于pid绝对值的组内的任意子进程。 option: WCONTINNUED : 当进程在暂停后继续执行,且其状态尚未报告,则返回其状态 WNOHANG: 当等待进程尚未结束运行时不阻塞,waitpid()函数直接返回 WUNTRACED: 当子进程暂停,并且其状态自暂停以来还未报告过,则返回其状态 例:#include$gcc waitpid.c -o waitpid ./waitpid#include #include #include int main(void){ pid_t pid; int num,status; pid = fork(); if(pid<0) { printf("fail to fork\n"); exit(1); }else if(pid == 0) { printf("the to fork\n"); sleep(5); exit(0); }else { printf("the parent\n"); if(waitpid(pid,NULL,WNOHANG) == 0) { printf("the child is not available now\n"); } } printf("no waiting,parent done\n"); return 0;}
the parent
the child is not available now no waiting, parent done the child waitpid()函数和wait()函数的区别有以下3点:1、waitpid()函数可以指定一个子进程。
2、waitpid()函数可以不阻塞等待一个子进程。
3、waitpid()函数支持作业控制。4、输出进程统计信息
#include#include #include #include pid_t wait3(int *statlic, int options, struct rusage *rusage);pid_t wait4(pid_t pid, int *statloc, int options,struct rusage *rusage);
转载地址:http://tynws.baihongyu.com/