C – 从父母分娩后重定向stdout
发布时间:2020-12-16 07:14:50 所属栏目:百科 来源:网络整理
导读:我正在编写一个程序来执行另一个程序作为分叉进程,并根据需要将其输出重定向到文件或/ dev / null. 目前我已经使用execvp()分叉并执行了外部程序. 然后从分叉之前创建的线程重定向stdout,因为分叉进程将继承父文件描述符表,允许我在foking之后重定向. 但是,
我正在编写一个程序来执行另一个程序作为分叉进程,并根据需要将其输出重定向到文件或/ dev / null.
目前我已经使用execvp()分叉并执行了外部程序. 但是,我最初可以将stdout重定向到所需的文件,父母和孩子的stdouts都被重定向.但是,如果我尝试将其重定向到另一个文件,则只重定向父项stdout,子项的stdout保持不变. 这是没有所有错误检查位的代码. struct params { const char *p; int fd; int wait; }; #define EXIT_NOEXEC 126 #define EXIT_NOTFOUND 127 #define EXIT_MISC 127 static void dofile(struct params* st); void dupit(const char *p,struct params* st); void* reload_config(void* para); int main(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 = %dn",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("%dn",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 0 1 2 3 4 $cat file2.txt 5 6 7 8 9 最后一点说明.示例程序在fork之前执行第一个dup.我是这样做的,因为这是你的代码的显示方式,也是为了强调问题的前后方面.但在实际代码中,传统的做法是首先执行fork,然后执行dup,最后执行exec.在fork之后完成dup,这样只有子进程受到影响而不是父进程(除非那真的是你想要的). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |