狂自私

导航

使用exec函数将当前的信息输入到文件中

先来看看exec函数:

exec函数族    

fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

将当前进程的.text、.data替换为所要加载的程序的.text、.data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳。

其实有六种以exec开头的函数,统称exec函数:

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 execve(const char *path, char *const argv[], char *const envp[]);

execlp函数

加载一个进程,借助PATH环境变量    

int execlp(const char *file, const char *arg, ...);        成功:无返回;失败:-1

参数1:要加载的程序的名字。该函数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没有参数1则出错返回。

该函数通常用来调用系统程序。如:ls、date、cp、cat等命令。

 

如你所见,exec函数实际上时一族函数:有6个。解决标题的问题这几个都可以用,但是我使用execlp函数。

先来看看它的用法:

它的原型:int execlp(const char *file, const char *arg, …);

这是一个变参函数。第一个参数是可执行文件的名称,可以不用指定文件目录,他会自动在当前的环境变量中查找,适用于使用系统可执行文件来创建一个进程这样的场合。相信知道exec函数的人应该知道它是用来干嘛的吧?如果不知道,请自行www.baidu.com或www.google.com。一个示例:execlp("ls", "ls", "-l", "-f", NULL);        使用程序名在PATH中搜索。用NULL作为哨兵

所以,我们可以利用它在使程序执行本身的过程中执行其他可执行文件。查看当前进程的命令:ps   aux    然后要将它输入到文件中去,怎么办呢?重定向! ps  aux > out.txt    但是我们能直接在程序中这么写么?答案是不能。为什么?因为>是转义字符。(别嫌我啰嗦,大部分人基础都不咋地,我也是。基础好的话也不会来写这个来加强记忆了。)所以,我们实际上要这样做:execlp("ps","ps","aux","\>","o_ret",NULL);  o_ret是一个自定义文件描述符。

懂了吗?但是,我要说但是!这不行!为什么?来,我们来看看,execlp("ps","ps","aux","\>","o_ret",NULL);如果我们是在shell环境中执行这个函数所做的事,那我们是这样执行的:ps  aux > o_ret   请问,请问,o_ret是什么?shell环境知道么?他不知道!所以,命令执行失败。

那么怎么办?没事,有办法,知道dup2函数么?(不能读成dup2(er),应该是dup(to))他将一个文件描述符复制给另一个文件描述符。大家应该知道一句话,在Linux中,一切皆文件。那么标准输入输出流,标准错误流是不是文件?是,并且他们三一直占用这文件描述符的前三。我不是说他们的使用频率,我是说他们的地位,我们用户自定义的文件描述符最牛逼也就只能排在3号位置,前面的0,1,2是他们的天下。

如果,如果我们用dup2函数将o_ret复制给stdout,会发生什么?是的,原先默认输出到屏幕上的东西都会输出到o_ret指向的文件中去。我们还用去重定向么?不用,还要去使用转义字符么?不用。

说了这么些,如果认真看,应该是会有一些明悟的。接下来上代码:

#include <cstdio>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

 

int main()

{

    int o_ret, e_ret, c_ret;

    o_ret = open("process_information.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);//创建文件,若存在,截断;权限644

    if (-1 == o_ret)

    {

        perror("file ");

        exit(1);

    }

    dup2(o_ret, STDOUT_FILENO);

 

    e_ret = execlp("ps", "ps", "aux", nullptr);

    //第一个ps是让函数去找这个可执行文件,第二个ps是argv[0]参数,这里我是这么理解的,函数找到ps文件后,开辟一个shell空间,然后使用后面的参数来执行。

    //可参考:https://baike.baidu.com/item/execlp

    if (-1 == e_ret)

    {

        perror("execlp() ");

        //exit(1); 执行到这儿了,如果退出,打开的文件怎么办?

    }

 

    c_ret = close(o_ret);

    if (-1 == c_ret)

    {

        puts("close file failure");

    }

    printf("c_ret = %d\n", c_ret);

 

    printf("hello from processInformation_printf_file!\n");

    return 0;

}

posted on 2018-04-05 20:44  狂自私  阅读(906)  评论(0编辑  收藏  举报