execve()系统调用学习
先来一个小程序, 它的功能是打印父子进程号, 传入的全部参数及两个环境变量(如果有):
process.c
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main(int argc,char *argv[],char *env[]) { int i; char *p; printf("\n=========I am a process image!============\n"); printf("\nMy pid = %d, parentpid = %d\n", getpid(), getppid()); for(i=0; i< argc; i++) printf("\nargv[%d]: %s\n",i ,argv[i]); p = getenv("env1"); if(p != NULL) printf("\nenv1 = %s\n",p); p = getenv("env2"); if(p != NULL) printf("\nenv2 = %s\n\n",p); printf("\n============= process =================\n\n"); sleep(atoi(argv[1])); return 99; }
另一段代码myexec.c如下:
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #define ERROR(flag) if(flag) { printf("%d: ",__LINE__); fflush(stdout); perror("error"); exit(errno); } int main() { int ret = 0; char *argv[] = {"11","22",NULL}; char *env[] = {"env1=1111111111111","env2=2222222222222",NULL}; printf("\nthis is myexec file, pid is %d, ppid is %d\n",getpid(),getppid()); // ret = execl("process","11","22",NULL); // ret = execlp("process","11","22",NULL); // ret = execle("process","11","22",NULL,NULL); // ret = execv("process",argv); // ret = execvp("process",argv); ret = execve("process",argv,env); ERROR(ret == -1); return 0; }
执行"make process myexec"后, 在当前目录下生成process和myexec两个可执行文件. 执行结果如下:
porcess.c代码将myexec.c代码执行时execve()系统调用传入的参数及环境变量息数打印了出来.
-------------------------------------------------------------------------------------------------------------------------------------------------
将myexec.c改造成如下代码:
#include <stdio.h> #include <sys/wait.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #define ERROR(flag) if(flag) { printf("%d: ",__LINE__); fflush(stdout); perror("error"); exit(errno); } int main(int argc,char *argv[],char *env[]) { pid_t pid; pid = fork(); //pid = vfork(); ERROR(pid == -1); if(pid == 0) { printf("\nChild process is running\n"); printf("\nMy pid = %d ,parent pid = %d\n",getpid(),getppid()); char *arglist[] = {"sleep","3",NULL}; execvp("./process",arglist); printf("process never go to here!\n"); _exit(0); } int stat; pid_t child_pid; child_pid = wait(&stat); printf("child process has exited, pid = %d\n\n",child_pid); if(WIFEXITED(stat)) printf("child exited with code %d\n\n",WEXITSTATUS(stat)); else printf("child exit abnormally\n\n"); return 0; }
执行"make myexec process" 后, 执行结果如下图:
子进程通过execvp()执行process. 父进程通过wait()取得子进程号及其(正常)退出运行时(通过WEXITSTAYUS()取得)的返回值.
--------------------------------------------------------------------------------------------------------------------------------------------------------------
一种通过c代码运行终端命令的方法:
mysystem,c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <errno.h> int main(int argc, char *argv[]) { system("ls --color=tty"); return 0; }
编译链接后运行, 其执行效果与在终端运行"ls --color=tty"命令的效果相同.
时间: 2024-10-12 11:40:16