目前我已经使用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所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)