2010-09-28 11 views
0

Sur Linux, j'ai du code C++ où je veux exécuter une autre application. Ce programme génère des données dans le fichier stderr. Je redirige donc le stderr en appelant freopen() avec stderr en tant que paramètre stream. La chose est, je veux rediriger le stderr pour un autre processus qui est exécuté.Qu'advient-il d'ouvrir les descripteurs de fichiers après un appel execv? (C++)

Voici le scénario avec lequel je travaille. Je fork() le processus actuel; dans le processus enfant, je redirige le stderr; alors j'ai execv() pour lancer l'application séparée. Tout d'abord, j'ai un Sentry mis en place pour rediriger la sortie stderr. Voici le code:

class StderrSentry { 
public: 
    StderrSentry() { 
    freopen("NUL", "wt", stderr); 
    } 
    ~StderrSentry() { 
    fclose(stderr); 
    } 
}; 

Puis, plus tard dans le code:

pid_t pid = fork(); 
int retval=-1; 

if(pid < 0) { 
    success = false; 
} 
else if(! pid) { // child process 
    StderrSentry stdErrSentry; // REDIRECTING STDERR HERE! 
    pid_t chid = setsid(); 
    if (chid == -1) { 
    exit(-1); 
    } 
    else { 
    // HERE IS THE execv() call: 
    if(execv(command[0].c_str(), const_cast<char**>(&c_args[0])) < 0) { 
     exit(-1); 
    } 
    } 
} 
// ... else etc... 

Est-ce que la redirection stderr appel fait toujours techniquement valable une fois que le execv() remplace le processus actuel avec celui spécifié?

Ceci se comporte réellement comme je le désire, mais est-ce un coup de chance, ou est-ce la manière de le faire?

Je ne peux pas activer la redirection stderr dans l'application qui est exécutée dans l'execv, car ce n'est pas mon code.

Merci pour toute information à ce sujet.

Répondre

0

La redirection est très valable. L'appel execv modifie l'image de processus, mais les descripteurs de fichier restent intacts.

+0

Merci pour toutes les réponses de tous - ils pourraient tous être marqués comme 'la réponse'. Cela m'aide à être confiant dans ce code, car il doit être publié sous peu. Merci encore. – Raymond

+0

Cela pourrait ne pas être vrai pour tous les types de descripteurs. Si ceux-ci sont marqués avec l'indicateur O_CLOEXEC appelant execv, ils seront fermés. – codewarrior

2

Il est généralement plus sûr de faire ce genre de chose avec les primitives OS fonctionnant sur les descripteurs de fichiers (open, close, dup2) qu'avec freopen et friends, mais oui, cela fonctionne, et comment les shell shell sont mis en œuvre. execve laisse tous les fichiers ouverts, sauf s'ils ont été marqués F_CLOEXEC.

1

Si les descripteurs de fichiers ne possèdent pas l'indicateur O_CLOEXEC (voir man 2 open), ils doivent persister dans exec. Ce drapeau n'est disponible que dans les noyaux 2.6.23 et suivants, donc si vous utilisez une distribution plus ancienne, elle ne sera pas disponible.

+1

O_CLOEXEC comme un indicateur open (2) est relativement nouveau, mais 'fcntl (fd, F_SETFD, FD_CLOEXEC)' a été autour pour des éternités. – zwol

+0

Je suis assez sûr que nos distributions sont assez à jour, mais je n'utilise pas le drapeau de toute façon, et comme je l'ai dit, cela fonctionne. Je voulais juste être certain que le code avait du sens. – Raymond