unix高级编程-fork和execve

fork和vfork
vfork是老的实现方法又很多问题
在这里插入图片描述

vfork

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{    
    pid_t pid;
    printf("befor fork pid: %d\n",getpid());
    int a = 10;
    pid = vfork();
    if(pid == -1)
    {
         perror("失败!\n");
         return -1;       
    }
    if(pid > 0){
        printf("parent:pid: %d\n",getpid());    
        printf("parent:a:%d\n",a);    
    }
    else if(pid == 0)
    {    
        printf("child:%d,parent:%d\n",getpid(),getppid());   
        printf("child:a:%d\n",a);                         
    }
    return 0;
    
}

在这里插入图片描述
可以看到这里是有问题的
vfork常和 execve() 一起使用

就像Python中的os.system(cmd)这个函数,我们可以用这个函数来执行我们的shell脚本,单独的shell命令,或者是调用其他的程序,我们的execve()这个函数就和Python中的os.system函数类似,可以调用其他程序的执行,执行shell命令,,调用脚本等等功能。

int execve(const char *filename, char *const argv[], 
           char *const envp[]); 

execve()执行程序由 filename决定。
filename必须是一个二进制的可执行文件,或者是一个脚本以#!格式开头的解释器参数参数。如果是后者,这个解释器必须是一个可执行的有效的路径名,但是不是脚本本身,它将调用解释器作为文件名。

argv是要调用的程序执行的参数序列,也就是我们要调用的程序需要传入的参数。

envp 同样也是参数序列,一般来说他是一种键值对的形式 key=value. 作为我们是新程序的环境。

注意,argv 和envp都必须以null指针结束。 这个参数向量和我们的环境变量都能够被我们的main函数调用,比如说我们可以定义为下面这个形式:

#include <sys/types.h>
#include <unistd.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{    
    pid_t pid;
    printf("befor fork pid: %d\n",getpid());
    
    pid = vfork();
    if(pid == -1)
    {
         perror("失败!\n");
         return -1;       
    }
    if(pid > 0){
        printf("parent:pid: %d\n",getpid());    
        wait(NULL);  //这里不等子进程会变孤儿进程  
    }
    else if(pid == 0)
    {    
        printf("child:%d,parent:%d\n",getpid(),getppid());   
        int r = 0;
        r =  execve("./hello", NULL,NULL);                         
        if(r == -1)
        {    
                     
            perror("失败!\n");
        }
        exit(0);
    }
    return 0;
    
}

hello文件包含的东西

#include <sys/types.h>

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

int main(void)
{    
    printf("你好!");
    return 0;
    
}

在这里插入图片描述
我们调用系统的命令

#include <sys/types.h>
#include <unistd.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{    
    pid_t pid;
    printf("befor fork pid: %d\n",getpid());
    
    pid = vfork();
    if(pid == -1)
    {
         perror("失败!\n");
         return -1;       
    }
    if(pid > 0){
        printf("parent:pid: %d\n",getpid());    
        wait(NULL);  //这里不等子进程会变孤儿进程  
    }
    else if(pid == 0)
    {    
        printf("child:%d,parent:%d\n",getpid(),getppid());   
        int r = 0;
        r =  execve("/bin/ls", NULL,NULL);                         
        if(r == -1)
        {    
                     
            perror("失败!\n");
        }
        exit(0);
    }
    return 0;
    
}

在这里插入图片描述

这里最好还是用fork函数

#include <sys/types.h>
#include <unistd.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{    
    pid_t pid;
    printf("befor fork pid: %d\n",getpid());
    
    pid = fork();
    if(pid == -1)
    {
         perror("失败!\n");
         return -1;       
    }
    if(pid > 0){
        printf("parent:pid: %d\n",getpid());    
        wait(NULL);  //这里不等子进程会变孤儿进程  
    }
    else if(pid == 0)
    {    
        printf("child:%d,parent:%d\n",getpid(),getppid());   
        int r = 0;
        r =  execve("/bin/ls", NULL,NULL);                         
        if(r == -1)
        {    
                     
            perror("失败!\n");
        }
        exit(0);
    }
    return 0;
    
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白帽小丑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值