C – 从父母分娩后重定向stdout

C – 从父母分娩后重定向stdout,第1张

概述我正在编写一个程序来执行另一个程序作为分叉进程,并根据需要将其输出重定向到文件或/ dev / null. 目前我已经使用execvp()分叉并执行了外部程序. 然后从分叉之前创建的线程重定向stdout,因为分叉进程将继承父文件描述符表,允许我在foking之后重定向. 但是,我最初可以将stdout重定向到所需的文件,父母和孩子的stdouts都被重定向.但是,如果我尝试将其重定向到另一个文件 我正在编写一个程序来执行另一个程序作为分叉进程,并根据需要将其输出重定向到文件或/ dev / null.

目前我已经使用execvp()分叉并执行了外部程序.
然后从分叉之前创建的线程重定向stdout,因为分叉进程将继承父文件描述符表,允许我在foking之后重定向.

但是,我最初可以将stdout重定向到所需的文件,父母和孩子的stdouts都被重定向.但是,如果我尝试将其重定向到另一个文件,则只重定向父项stdout,子项的stdout保持不变.

这是没有所有错误检查位的代码.

struct params {    const char *p;    int fd;    int wait;};#define EXIT_NOEXEC 126#define EXIT_NOTFOUND   127#define EXIT_MISC   127static voID dofile(struct params* st);voID dupit(const char *p,struct params* st);voID* reload_config(voID* para);intmain(int argc,char *argv[]) {    int exit_status,prog_status;    struct params init;    pID_t prog_pID;    dofile(&init);    prog_pID = fork();    if (prog_pID == 0) {        execvp(*argv,argv);        exit_status = (errno == ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC;        err(exit_status,"%s",argv[0]);        exit(EXIT_FAILURE);    } else {        while (wait(&prog_status) != prog_pID);        return prog_status;    }}static voID dofile(struct params* st) {    const char *p    p = out.txt;    dupit(p,st);}voID dupit(const char *p,struct params* st) {    pthread_t tID;    st->wait = 0;    int err = pthread_create(&(tID),NulL,&reload_config,st);    if (err != 0) {        printf("\ncan't create thread :[%s]",strerror(err));        exit(1);    } else {        while (st->wait == 0) {            sleep(1)        }    }}voID* reload_config(voID* para) {    struct params *passed = (struct params *) para;    int pre_config = 3;     int cur_config = 1;     int saved_stdout = dup(STDOUT_fileNO);    char infile[5];    int devNull = open("/dev/null",O_WRONLY);    int file = open("out.txt",O_WRONLY);    file *config;    config = fopen("config.txt","r");    if (access("config.txt",F_OK) != -1) {        while (1) {            fgets(infile,5,config);            fclose(config);            cur_config = infile[0] - '0';            printf("output from thread,current config = %d\n",cur_config);            if (pre_config != cur_config) {                if (cur_config == 1) {                    if (dup2(file,STDOUT_fileNO) == -1) {                        err(EXIT_MISC,NulL);                    }                } else {                    dup2(devNull,STDOUT_fileNO);                }                pre_config = cur_config;            }            if (passed->wait==0) {                passed->wait = 1;            }            sleep(1);        }    } else {        if (dup2(passed->fd,STDOUT_fileNO) == -1) {            err(EXIT_MISC,NulL);        }    }}

好吧,我改变了一些代码,所以你们会理解,所以有些部分没有意义.但是你得到了基本的想法.

如何在分叉后按照我的意愿重定向孩子的标准输出.

解决方法 既然你问过,这里有一个简单的例子.为简洁起见,我们采取了一些捷径,但希望它会给你一些想法.该程序打开file1并将stdout重定向到该文件.它然后做一个分叉.子进程每1秒向stdout(通过printf)写一个计数器.几秒钟之后,父进程使用IPC(本例中的管道)告诉子进程切换重定向文件.

#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <errno.h>int main(int argc,char **argv){      pID_t pID;    const char *file1 = "file1.txt";    const char *file2 = "file2.txt";    int pipefd[2];    int fd;    int rval;    fd = open(file1,O_WRONLY|O_CREAT|O_Trunc,S_IRWXU);    if (fd == -1) {        perror("file1 open");        exit(-1);    }    /*     * This pipe will be used by parent process to tell child which file     * to redirect to.     */    rval = pipe2(pipefd,O_NONBLOCK);    if (fd == -1) {        perror("pipe");        exit(-1);    }    /* Redirect stdout to the file opened before the fork. */    dup2(fd,STDOUT_fileNO);    pID = fork();    if (pID == -1) {        perror("fork");        exit(-1);    } else if (pID == 0) {        /* Child process. */        int ix;        char redirect_file[100];        close(pipefd[1]);        for (ix = 0; ix < 10; ix++) {            printf("%d\n",ix);            sleep(1);            rval = read(pipefd[0],redirect_file,sizeof(redirect_file));            if (rval > 0) {                /*                 * Parent process has written a filename to the pipe.                 */                 fd = open(redirect_file,S_IRWXU);                if (fd == -1) {                    perror("file2 open");                    exit(-1);                }                /* Ensure prevIoUs output has been written to current file. */                fflush(stdout);                /* Change redirect Now. */                dup2(fd,STDOUT_fileNO);            }        }    } else {        /* Parent process. */        close(pipefd[0]);        /* Wait a little and then tell child to change redirect file. */        sleep(5);        write(pipefd[1],file2,strlen(file2) + 1);        wait();    }}

如果运行此程序,您会发现子输出的一半转到file1(第一次重定向),另一半输出转到file2(第二次重定向).

$cat file1.txt 01234$cat file2.txt 56789

最后一点说明.示例程序在fork之前执行第一个dup.我是这样做的,因为这是你的代码的显示方式,也是为了强调问题的前后方面.但在实际代码中,传统的做法是首先执行fork,然后执行dup,最后执行exec.在fork之后完成dup,这样只有子进程受到影响而不是父进程(除非那真的是你想要的).

总结

以上是内存溢出为你收集整理的C – 从父母分娩后重定向stdout全部内容,希望文章能够帮你解决C – 从父母分娩后重定向stdout所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1228019.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存