24

I have the following code:

pid_t pid = fork();
if (pid == -1)
{
    // ...
}
else if (pid == 0)
{
    stdin = someopenfile;
    stdout = someotherfile;
    stderr = somethirdopenfile;
    execvp(args[0], args);
    // handle error ...
}
else
{
    // ...
}

The problem is, the input/output of the execvp() call is still the console, rather than the files. Clearly I am doing something wrong, what is the right way to do this?

4

3 回答 3

47

正确的做法是替换文件描述符STDIN_FILENOSTDOUT_FILENOSTDERR_FILENO用打开的文件使用dup2(). 然后,您还应该关闭子进程中的原始文件:

else if (pid == 0)
{
    dup2(fileno(someopenfile), STDIN_FILENO);
    dup2(fileno(someotherfile), STDOUT_FILENO);
    dup2(fileno(somethirdopenfile), STDERR_FILENO);
    fclose(someopenfile);
    fclose(someotheropenfile);
    fclose(somethirdopenfile);
    execvp(args[0], args);
    // handle error ...
}
于 2013-01-27T01:20:05.747 回答
11

看看freopen功能。

我不得不做类似的事情stdout并编写了两个为我工作的函数:

static int fd;
static fpos_t pos;

void switchStdout(const char *newStream)
{
  fflush(stdout);
  fgetpos(stdout, &pos);
  fd = dup(fileno(stdout));
  freopen(newStream, "w", stdout);
}

void revertStdout()
{
  fflush(stdout);
  dup2(fd, fileno(stdout));
  close(fd);
  clearerr(stdout);
  fsetpos(stdout, &pos);
}
于 2013-01-27T01:15:13.073 回答
2

当 stdin , stdout , stderr 是终端时,您可以使用它-

//change stdin,stdout,stderr
    freopen("new_stdin","r",stdin);
    freopen("new_stdout","r",stdout);
    freopen("new_stderr","r",stderr);

    //----do something;

//reset stdin,stdout,stderr
     freopen("/dev/tty","r",stdin);
     freopen("/dev/tty","r",stdout);
     freopen("/dev/tty","r",stderr);
于 2017-03-10T13:21:20.190 回答