J'ai le code suivant:
pid_t pid = fork();
if (pid == -1)
{
// ...
}
else if (pid == 0)
{
stdin = someopenfile;
stdout = someotherfile;
stderr = somethirdopenfile;
execvp(args[0], args);
// handle error ...
}
else
{
// ...
}
Le problème est que l'entrée/sortie de l'appel execvp()
est toujours la console, plutôt que les fichiers. Clairement, je fais quelque chose de mal, quelle est la bonne façon de faire cela?
La bonne façon de procéder consiste à remplacer les descripteurs de fichier STDIN_FILENO
, STDOUT_FILENO
et STDERR_FILENO
par les fichiers ouverts à l'aide de dup2()
. Vous devez également fermer les fichiers d'origine dans le processus enfant:
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 ...
}
Jetez un coup d’œil à freopen
function.
J'ai dû faire quelque chose de similaire avec stdout
et écrit deux fonctions qui font le travail pour moi:
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);
}
Vous pouvez l’utiliser lorsque stdin, stdout, stderr sont terminales.
//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);