• Linux--exec族函数及与fork共用


    exec族函数

    作用:
    我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
    exec函数族:
    execl, execlp, execle, execv, execvp, execvpe

    #include 
    extern char **environ;
    
    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[]);
    /*
    path:可执行文件的路径名字
    file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。
    arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    返回值:
      exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。

    例:
    有绝对路径

    //文件demo.c
    #include 
    #include 
    #include 
    
    int main(void)
    {
        printf("before execl\n");
        if(execl("./bin/echoarg","echoarg","abc",NULL) == -1)
        //文件路径./ ...执行文件echoarg,显示内容abc,空结尾。
        //arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
        {
            printf("execl failed!\n");   
            perror("why");//失败的原因   
        }
        printf("after execl\n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    //文件echoarg.c
    #include 
    
    int main(int argc,char *argv[])
    {
        int i = 0;
        for(i = 0; i < argc; i++)
        {
            printf("argv[%d]: %s\n",i,argv[i]); 
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:

    before execl
    argv[0]: echoarg
    argv[1]: abc

    运行 ls:
    通过whereis ls找到 ls的路径,然后调用:if(execl("/bin/ls","ls",NULL,NULL) == -1)

    运行 ls -l:
    通过whereis ls找到 ls的路径,然后调用:if(execl("/bin/ls","ls","-l",NULL) == -1)

    获取系统时间date:
    通过whereis date找到 date的路径,然后调用:if(execl("/bin/date","date",NULL,NULL) == -1)

    族函数带p的:execlp
    (不加绝对路径)exaclp函数带p,所以能通过环境变量PATH查找到可执行文件ps

    #include 
    #include 
    #include 
    
    int main(void)
    {
        printf("before execlp\n");
        if(execlp("ps","ps","-l",NULL) == -1)
        //通过环境变量PATH查找到可执行文件ps
        {
            printf("execl failed!\n");
        }   
        printf("after execl\n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    环境变量:
    查询环境变量:echo $PATH

    显示当前路径:pwd
    修改环境变量:export PATH=$PATH:pwd显示的路径

    族函数带v的:execvp
    execv带绝对路径

    #include 
    #include 
    #include 
    
    int main(void)
    {
        printf("before execlp\n");
    	char *argv[] = {"ps",NULL,NULL};
        if(execvp("ps",argv) == -1)
        {
            printf("execl failed!\n");
        }   
        printf("after execl\n");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    精彩博文: https://blog.csdn.net/u014530704/article/details/73848573

    **

    exec配合fork使用

    **

    实现功能:当父进程检测到输入为一的时候,创建子进程把配置文件的字段修改掉。

    //changeData文件
    /*
    修改配置文件config.txt
    >  SPEED = 3
    >  LENG = 3 
    >  SCORE = 9 
    >  LEVEL = 5
    >  修改为:
    >  SPEED = 3
    >  LENG = 100 
    >  SCORE = 9 
    >  LEVEL = 5
    */
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc,char **argv)
    {
    	int fdSrc,fdDes;
    	char *readBuf = NULL;
    	
    	if(argc != 2){
    		printf("pararm error\n");
    		exit(-1);
    	}
    	
    	fdSrc = open(config.txt,O_RDWR);//打开文件
    	int size = lseek(fdSrc,0,SEEK_END);
    	lseek(fdSrc,0,SEEK_SET);
    	readBuf = (char *)malloc(sizeof(char)*size + 8);
    	
    	int n_read = read(fdSrc,readBuf,1024);
    	
    	char *p = strstr(readBuf,"LENG=");
    	if(p==NULL){
    		printf("not founf\n");
    		exit(-1);
    	}
    	p = p+strlen("LENG=");
    	*p = "100";
    	
    	lseek(fdSrc,0,SEEK_SET);//移动光标
    	int n_write =write(fdSrc,readBuf,strlen(readBuf));
    
    	close(fdSrc);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    用exec族函数调用changeData文件

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
    	pid_t pid;
    	int data = 10;
    	
    	while(1){
    		printf("please input a data:\n");
    		scanf("%d",&data);
    		if(data == 1){
    			int fdSrc;
    			pid = fork();
    			if(pid > 0){
    				wait(NULL);
    			}
    			if(pid == 0){
    				execl("./changeData","changeData","config.txt",NULL);				
    			}
    		}
    		else{
    			printf("wait ,do nothing!\n");
    		}
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    文件IO总结
    [JavaWeb学习] tomcat简介、安装及项目部署
    /LatestBuild: Operation not permitted
    Android中常用Dialog的使用
    网络重要知识点
    ERP编制物料清单 金蝶
    Cesium点击实体,修改参数实现实体的平移和旋转
    算法分析至栈与队列
    025-第三代软件开发-实现需求长时间未操作返回登录界面
    大数据组件-Flink环境搭建
  • 原文地址:https://blog.csdn.net/weixin_48208102/article/details/132690757