#include<stdio.h>
#include<unistd.h>
// int execl(const char *path, const char *arg, ...);
int main()
{printf("start:\n");execl("/usr/bin/ls","ls","-a",NULL);printf("end!\n");
}
如果没有execl函数,则打印start然后换行后,打印end!;
我们在打印start之后再调用execl函数,它会进行程序替换,将这个程序中所有代码全部替换为第一个参数"/usr/bin/ls"下的程序,然后执行并加上后面我们传入的两个选项;
【注】:如果你要用ls命令所在位置代码去替换的话,不要忘记usr前面的那个反斜杠,代表根目录,如果没有写,它会返回-1,但是这个函数一般不写返回值,所以容易误解;
成功了就不返回,因为返回没用,函数成功执行,后续代码全被替换;
另外就是这个函数的原型是:
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
函数传参中有一个省略号,这个是可变参数列表,表示你可以写多个前面的参数,以NULL结尾就行了。比如我写的:
execl("/usr/bin/ls","ls","-a",NULL);
就有两个参数,可以写更多;
另外我们知道execl函数执行成功会替换程序所有代码,后续代码没有机会执行,那么有机会执行只有一种情况:函数第一个参数提供的地址有问题或者参数不存在....所以我们通常在execl()之后加一个exit(1);
如果执行成功,肯定不会执行到这句exit(1);不成功,就执行这个exit返回即可,我们及时接收返回值判断即可;
那它到底是为了干什么呢?父进程fork()子进程后,让子进程完成一定的任务(比如此代码中的加载steam.exe);父进程利用非阻塞的waitpid();来监测子进程状态,此期间,自己也可以完成一定任务;
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
// int execl(const char *path, const char *arg, ...);
int main()
{printf("start!__________________________\n");pid_t id = fork();//创建子进程if(id==0){printf("I am child process and I will load steam.exe!\n");//给子进程派发任务,让他帮我完成加载steam的任务;//利用execl();加载steam.exe至此;execl("/home/steam.exe",NULL);exit(-1);//加载失败将执行这行代码;父进程通过waitpid()的status可以监测到;}else if(id>0)//这里是父进程的代码;{printf("This is father process and I will wait child process \n");int status = 0;while(1)//不停的监测,也可以用wait()阻塞式;{pid_t res = waitpid(id,&status,0);if(res>0){printf("waitpid succeed! And the child process returns %d \n",(status>>8)&0xFF);break;}else if(res==0){printf("Steam.exe- ing!\n");}else{printf("The waitpid is failed\n");}sleep(2);}else{printf("fork() failed!\n");}printf("end!___________________________\n");
}
关于exec家族的这些函数还有很多,但大同小异;