【linux高级程序设计】(第八章)进程管理与程序开发 2

在进程中运行新代码

execX系列函数可以在当前子进程中运行新程序。当进程调用该系列任意一个函数时,该进程的用户空间资源完全由新程序替代。

这些函数的区别:指示新程序的位置是使用路径还是文件名,若是文件名则在系统的$PATH环境变量所描述的路径中搜索该程序。

                       在使用参数时,是使用参数列表的方式还是使用argv[]数组的方式

函数                     使用文件名使用路径名使用参数表(函数出现字母l)使用argv(函数出现字母v)
execl       
execlp  
execle  
execv  
execvp  
execve  

int execl (__const char *__path, __const char * __arg, ...): 执行path字符串所指向的程序,后面的参数是参数列表。最后必须传入空指针

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int main(int argc, char *argv[])
{
    pid_t pid;
    if((pid = fork()) < 0)
        printf("error\n");
    else if(pid == 0)
    {
        execl("/bin/ls","ls","-l","/home",(char *)0); //子进程执行新函数
    }
    else
        printf("father ok!\n");
    return 0;
}

 

int execle (__const char * __path, __const char *__arg, ...):最后一个参数必须指向一个新的环境变量数组,即新执行程序的环境变量。

#include<unistd.h>
int main(int argc, char *argv[], char *env[])
{
    execl("/bin/ls","ls","-l","/home",(char *)0,env); //子进程执行新函数
    return 0;
}

 

int execlp(__const char * __file, __const char * __arg, ...):在$PATH环境变量中查找文件并执行,最后一个参数必须用空指针NULL

#include<unistd.h>
int main(int argc, char *argv[], char *env[])
{
    execlp("ls","ls","-l","/home",(char *)0); //子进程执行新函数
    return 0;
}

 

int execv (__const char * __path, char * __const __argv[]):第二个参数是数组指针维护的程序参数列表。数组的最后一个成员必须为NULL

#include<unistd.h>
int main()
{
    char * argv[] = {"ls","-l","/home",(char *)0};
    execv("/bin/ls", argv); //子进程执行新函数
    
    return 0;
}

 

int execvp (__const char * file, char * __const __argv[]):使用文件名,第二的参数的最后一个成员必须是NULL

#include<unistd.h>
int main()
{
    char * argv[] = {"ls","-l","/home",(char *)0};
    execvp("ls", argv); //子进程执行新函数
    
    return 0;
}

 

int system (__const char * __command):创建新进程,并运行,直到新进程运行结束后,才继续运行父进程。

#include<stdlib.h>
#include<sys/wait.h>
#include<stdio.h>
int main(int argc, char *argv[])
{
    int status;
    status = system("pwd");
    if(!WIFEXITED(status))
        printf("abnormal exit\n");
    else
        printf("the exit status is %d\n", status);
    return 0;
}

 

执行新代码,对打开文件的处理

原来的文件描述符可以使用,但如果使用了fcntl(fd, F_SETFD, FD_CLOEXEC)即关闭FD_CLOEXEC项,则在执行execX系列函数后关闭原来打开的文件描述符。

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, char * argv[])
{
    int fd, status;
    pid_t pid;
    fd = open("test.txt", O_RDWR|O_APPEND|O_CREAT,0644);
    if(fd == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    //fcntl(fd, F_SETFD,FD_CLOEXEC);    //如果执行此句,将导致错误
    printf("before child process write\n");
    system("cat test.txt");  //查看执行newcode前内容
    if((pid=fork()) == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if(pid == 0)  //子进程
    {
        char buf[128];
        sprintf(buf, "%d", fd);
        execl("./newcode","newcode",buf,(char *)0);
    }
    else
    {
        wait(&status);
        printf("after child_process write\n");
        system("cat test.txt");  //查看内容是否有效
    }
}
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main(int argc, char * argv[])
{
    int i;
    int fd;
    char *ptr = "helloworld\n";
    fd = atoi(argv[1]);
    i = write(fd,ptr,strlen(ptr));
    if(i<=0)
        perror("write");
    close(fd);
}

可见,新代码中可以使用原来的文件描述符。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值