unix高级编程-fork和execve

简介: 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;
}
相关文章
|
5月前
|
Unix Shell API
组合思维:Unix 哲学到底给现代编程带来哪些重要启示?
Unix哲学提供了一套简洁而强大的设计理念,这些理念在现代编程中依然具有重要的指导意义。通过模块化设计、组合工具、避免过早优化以及注重可复用性和可扩展性,开发者可以构建出更高效、更健壮的软件系统。希望本文能够帮助读者深入理解Unix哲学,并在实际开发中应用这些宝贵的设计原则。
86 25
|
9月前
|
算法 Unix 数据安全/隐私保护
Python编程--UNIX口令破解机
Python编程--UNIX口令破解机
81 1
Unix环境高级编程(第三版)中apue.h头文件及其依赖安装教程
Unix环境高级编程(第三版)中apue.h头文件及其依赖安装教程
284 0
|
Ubuntu Unix Shell
unix高级编程-fork之后父子进程共享文件
unix高级编程-fork之后父子进程共享文件
105 0
|
Unix Linux
unix高级编程-僵尸进程和孤儿进程
unix高级编程-僵尸进程和孤儿进程
94 0
|
Unix
《unix环境高级编程》 读书笔记 (9)
目录: http://blog.csdn.net/alex_my/article/details/39346381 signals 1 signal concepts 信号是一种软中断,可以由以下情形触发: -1: 用户按下某些终端键,例如ctrl + D -2: 硬件异常,例如除数为0,无效的内存引用 -3:kill(2), kill(1) -4:
1005 0
|
Unix C++
《unix环境高级编程》 读书笔记 (6)
目录: http://blog.csdn.net/alex_my/article/details/39346381 process environment 1 exit, _exit, _Exit and atexit 在解释前三个之前先说说这个: #include &lt;stdlib.h&gt; i
1086 0
|
机器学习/深度学习 Unix
《unix环境高级编程》 读书笔记 (7)
目录: http://blog.csdn.net/alex_my/article/details/39346381 process control 1 process identifiers 每一个进程都有一个唯一的非负整型做为标识符。 #include &lt;unistd.h&gt; pid_t getpid(); pid_t getppi
1117 0
|
Unix
《unix环境高级编程》 读书笔记 (8)
目录: http://blog.csdn.net/alex_my/article/details/39346381 process control 1 exec functions #include &lt;unistd.h&gt; extern char** environ; int execl(const char* path, const c
1205 0
|
Unix Shell 测试技术
《unix环境高级编程》 读书笔记 (4)
目录: http://blog.csdn.net/alex_my/article/details/39346381 system data files and infomation 1 password file 终端上输入cat /etc/passwd 可以看见很多相关信息。 也可以通过以下函数: #inc
1140 0