web-dev-qa-db-ja.com

Cでは、execvp()または同様の呼び出しを行うときにstdin / stdout / stderrをどのようにファイルにリダイレクトしますか?

私は次のコードを持っています:

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

問題は、execvp()呼び出しの入出力がファイルではなくコンソールのままであることです。明らかに私は何か間違ったことをしていますが、これを行う正しい方法は何ですか?

21
Matt

正しい方法は、dup2()を使用して、ファイル記述子STDIN_FILENOSTDOUT_FILENO、およびSTDERR_FILENOを開いたファイルに置き換えることです。また、子プロセスの元のファイルを閉じる必要があります。

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 ...
}
42
caf

freopen 関数を見てください。

私はstdoutで同様のことをしなければならず、私のために仕事をする2つの関数を書きました。

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);
}
7
Jack

これは、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);
0
alhelal