Linux系统编程之进程中的exec族函数

exec族函数的作用
我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
详细参考精彩博文:
exec族函数精彩博文

直接上例子:
echoarg.c

#include <stdio.h>

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;
}

结果:
在这里插入图片描述
这只是一个传参的例子,编译生成一个可执行文件

execl.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    
    
        printf("before execl!\n");

        if(execl("./echoarg","echoarg","abvfd",NULL) == -1)
        {
    
    
                printf("execl failed!\n");
                perror("why");
        }

        printf("after execl!\n");

        return 0;
}

结果:
在这里插入图片描述
既然exec函数族执行的是一个可执行文件,那么linux底下的ls执行也是一个可执行文件,那么我们就用exec函数来调用一下linux底下的相关指令。

ls:

#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    
    
        printf("this is ls\n");

        if(execl("/bin/ls","ls",NULL) == -1)
        {
    
    
                printf("no this file\n");
        }

        printf("after execl\n");
        return 0;
}

结果:
在这里插入图片描述
这样就把指令ls给调用起来了。

ls -al:

#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    
    
        printf("this is ls\n");

        if(execl("/bin/ls","ls","-al",NULL) == -1)
        {
    
    
                printf("no this file\n");
        }

        printf("after execl\n");
        return 0;
}

结果:
在这里插入图片描述
这样也把指令ls -al给调用起来了

那我们来调用一下获取时间的指令date:

#include <stdio.h>
#include <unistd.h>

int main()
{
    
    
        printf("this is Beijing Time:\n");

        if(execl("/bin/date","date",NULL) == -1)
        {
    
    
                printf("faild to open execl!\n");
        }

        printf(".....\n");
        return 0;
}

结果:
date

execlp
execlpexecl的区别就是execl要加绝对路径,而execlp不用加路径,直接写对应的可执行文件即可

ps:

#include <stdio.h>
#include <unistd.h>

int main()
{
    
    
        printf("this is ps\n");

        if(execlp("ps","ps",NULL) == -1)
        {
    
    
                printf("faild to open execl!\n");
                perror("why");
        }

        printf(".....\n");
        return 0;
}

结果:
在这里插入图片描述
execv:
execv函数跟execl不同之处就是后面的参数用一个指针数组来保存起来

ls:

#include <stdio.h>
#include <unistd.h>

int main()
{
    
    
        printf("this is execv!\n");
        char *arv[] = {
    
    "ls","-l",NULL};

        if(execv("/bin/ls",arv))
        {
    
    
                printf("faild to open execv!\n");
                perror("why");
        }

        printf("......\n");
        return 0;
}

execvp:
execv跟execvp的区别也是一个需要加路径,一个不需要加路径

ls -l:

#include <stdio.h>
#include <unistd.h>

int main()
{
    
    
        printf("this is execv!\n");
        char *arv[] = {
    
    "ls","-l",NULL};

        if(execvp("ls",arv))
        {
    
    
                printf("faild to open execv!\n");
                perror("why");
        }

        printf("......\n");
        return 0;
}

2.exec配合fork使用
实现功能,当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉

代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    
    
        pid_t pid;
        int data;
        int fd;
        int n_read;
        char *readBuf = NULL;
        char *pstr = NULL;

        while(1)
        {
    
    
                printf("Please Input a data:\n");
                scanf("%d",&data);

                if(data == 1)
                {
    
    
                        pid = fork();

                        if(pid > 0)
                        {
    
    
                                wait();
                        }
                       else if(pid == 0)
                        {
    
    
                                fd = open("./test.txt",O_RDWR);
                                n_read = lseek(fd,0,SEEK_END);
                                lseek(fd,0,SEEK_SET);

                                readBuf = (char *)malloc(sizeof(char)*n_read + 5);                      
                                read(fd, readBuf, n_read);

                                pstr = strstr(readBuf,"LOIJ=");

                                if(pstr == NULL)
                                {
    
    
                                        printf("fail to change the file!\n ");
                                        exit(-1);
                                }

                                pstr = pstr + strlen("LOIJ=");
                                *pstr = '3';

                                lseek(fd,0,SEEK_SET);
                                write(fd, readBuf, n_read);

                                close(fd);
                        }
                }
                else
                {
    
    
                     printf("Wait,Please Input again!\n");
                }
        }
        return 0;
}

这样写的话其实是很冗余的。
调用exec函数来实现:

include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    
    
        pid_t pid;
        int data;
        int fd;
        int n_read;
        char *readBuf = NULL;
        char *pstr = NULL;

        while(1)
        {
    
    
                printf("Please Input a data:\n");
                scanf("%d",&data);

                if(data == 1)
                {
    
    
                        pid = fork();

                        if(pid > 0)
                        {
    
    
                            wait();
                        }
                        else if(pid == 0)
                        {
    
    
                          if(execl("./changeDate","changeDate","test.txt",NULL) == -1)
                          {
    
    
                               printf("Sorry, fail to change the data!\n");
                          }
                        }
                }
                else
                {
    
    
                        printf("Wait,Please Input again!\n");
                }
        }

        return 0;
}    

生成changeDate可执行文件的代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

char* change(char *read,char *str)
{
    
    
        char *pstr = NULL;
        pstr = strstr(read,str);

        if(pstr == NULL)
        {
    
    
                printf("Sorry ,faild to found\n");
                exit(-1);
        }

        pstr = pstr + strlen(str);
        *pstr = '3';

        return pstr;
}

int main(int argc, char **argv)
{
    
    
        if(argc != 2)
        {
    
    
                printf("parameter error!!\n");
                exit(-1);
        }

        int fd;
        int fd_size;
        char *readBuf = NULL;
        char *pstr = NULL;


        fd = open(argv[1],O_RDWR);
        fd_size = lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);

        readBuf = (char *)malloc(sizeof(char)*fd_size+3);

        read(fd,readBuf,fd_size);

        pstr = change(readBuf,"LOIJ=");
        lseek(fd,0,SEEK_SET);
        write(fd,readBuf,fd_size);

        close(fd);
        return 0;
}

修改前的test.txt:
在这里插入图片描述
修改后的test.txt:
在这里插入图片描述
这只是学习中的点点代码,详细参考开头介绍到的那个精彩博文。

学习笔记,仅供参考

猜你喜欢

转载自blog.csdn.net/weixin_51976284/article/details/124472813