【进程】(四)exec族函数

本文详细介绍了Linux系统编程中的exec族函数,包括execl、execlp、execv、execvp、execle和execvpe。这些函数用于在当前进程中替换执行新的程序。文章通过实例代码展示了如何使用这些函数,包括参数列表的构建和环境变量的处理,帮助读者理解它们的区别和用法。

1、函数原型

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

execl,execlp参数尾部要以NULL结束
execv,execvp参数数组argv[]要以NULL结束

2、函数说明

exec族成员函数说明
execll 表示list参数列表,其函数寻找可执行文件路径时,不访问环境变量
execlpl 表示list参数列表,execlp将在环境变量中寻找可执行文件
execvv表示char *argv[]指针数组,可将可执行文件所带参数放入数组中集中表示
execvp在execv的基础上,p表示path ,将访问环境变量
execle带e表示该函数取envp[]数组,而不使用当前环境
execvpe带e表示该函数取envp[]数组,而不使用当前环境

3、例程代码

3.1 execl(execlp)

3.1.1 主程序(execl.c)

gcc execl.c -o execl

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>

int main(void)
{
        pid_t pid;
        int cmd;
        while(1)
        {
                printf("waitting client cmd...\r\n");
                scanf("%d", &cmd); //等待用户键入命令,模拟服务端接收客户端发送的请求指令
                if(cmd == 1)
                {
                        printf("client request service\r\n");
                        if((pid = fork()) < 0)
                        {
                                perror("fork failed,Why:");
                        }
                        else if(pid > 0)
                        {
                                wait(NULL);//等待子进程执行完毕
                                printf("run finished.\r\n");
                        }
                        else if(pid ==  0)
                        {
                                printf("fork sucess");
                                /* 调用execl替代子进程,./execl_task为可执行文件所在路径名。
                                 * 当在相对路径找不到可执行文件名时,不访问环境变量。
                                 * execlp用法相同,所指定的路径找不到可执行文件时,将访问全局变量*/
                                if(execl("./execl_task", "execl_task", "arg[1]", "arg[2]", NULL) == -1)
                                {
									perror("execl failed,why:");
								}
                        }
                }else{
                        printf("no client request\r\n");
                }
        }
        exit(0);
}

3.1.2 指定execl目标程序(execl_task)

gcc execl_task.c -o execl_task

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        pid_t pid;
        printf("%d\n", argc);
        if(argc != 3)
        {
                perror("argc is fewer");
                exit(0);
        }
        for(int i=0; i<argc; i++) //打印execl函数传递的参数
        {
                printf("%s ", argv[i]);
        }
        printf("\n");
        exit(0);
}

3.2 execv(execvp)

3.2.1 类比execl(execlp)

execv(execvp)与execl(execlp)的区别在于函数参数不同,execv将可执行文件的目标参数打包成数组,

int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);

3.2.2 主程序(execv.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>

int main(void)
{
        pid_t pid;
        int cmd;
        //打包execv(execvp)所指的可执行文件所带参数
        char *argv[] = {"execl_task", "arg[1]", "arg[2]", NULL};
        while(1)
        {
                printf("waitting client cmd...\r\n");
                scanf("%d", &cmd); //等待用户键入命令,模拟服务端接收客户端发送的请求指令
                if(cmd == 1)
                {
                        printf("client request service\r\n");
                        if((pid = fork()) < 0)
                        {
                                perror("fork failed,Why:");
                        }
                        else if(pid > 0)
                        {
                                wait(NULL);//等待子进程执行完毕
                                printf("run finished.\r\n");
                        }
                        else if(pid ==  0)
                        {
                                printf("fork sucess");
                                /* 调用execl替代子进程,./execl_task为可执行文件所在路径名。
                                 * 当在相对路径找不到可执行文件名时,不访问环境变量。
                                 * execvp用法相同,所指定的路径找不到可执行文件时,将访问全局变量*/
                                if(execv("./execl_task", argv) == -1)
                                {
                                	perror("execv failed,why:");
								}
                        }
                }else{
                        printf("no client request\r\n");
                }
        }
        exit(0);
}

3.2.3 execv目标程序execv_task

gcc execv_task.c -o execv_task

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        pid_t pid;
        printf("%d\n", argc);
        if(argc != 3)
        {
                perror("argc is fewer");
                exit(0);
        }
        for(int i=0; i<argc; i++) //打印execl函数传递的参数
        {
                printf("%s ", argv[i]);
        }
        printf("\n");
        exit(0);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值