В C как вы перенаправляете stdin/stdout/stderr в файлы при выполнении execvp() или аналогичного вызова?
У меня есть следующий код:
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()
по-прежнему является консолью, а не файлами. Ясно, что я делаю что-то неправильно, что это правильный способ сделать это?
Ответы
Ответ 1
Правильный способ сделать это - заменить дескрипторы файла STDIN_FILENO
, STDOUT_FILENO
и STDERR_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 ...
}
Ответ 2
Посмотрите 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);
}
Ответ 3
Вы можете использовать это, когда 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);