Ich habe folgenden 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
{
// ...
}
Das Problem ist, dass die Eingabe/Ausgabe des Aufrufs execvp()
immer noch die Konsole ist und nicht die Dateien. Klar mache ich etwas falsch. Was ist der richtige Weg, dies zu tun?
Der richtige Weg ist es, die Dateideskriptoren STDIN_FILENO
, STDOUT_FILENO
und STDERR_FILENO
durch die geöffneten Dateien mit dup2()
zu ersetzen. Sie sollten dann auch die Originaldateien im untergeordneten Prozess schließen:
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 ...
}
Schauen Sie sich die freopen
- Funktion an.
Ich musste etwas Ähnliches mit stdout
machen und schrieb zwei Funktionen, die die Arbeit für mich erledigen:
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);
}
Sie können dies verwenden, wenn stdin, stdout, stderr termin-
//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);