wake-up-neo.net

In C: Wie leiten Sie stdin/stdout/stderr in Dateien um, wenn Sie einen execvp () oder einen ähnlichen Anruf tätigen?

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?

20
Matt

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

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

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);
0
alhelal