Blocage de la version de execvp (Windows)

Cette question est exactement le contraire de la version non bloquante de system ()

Je veux remplacer le processus actuel par un autre (pas en créer un autre).

Je veux démarrer (par exemple) le notepadnotepad , mais de manière bloquante (je ne veux pas recevoir l’invite tant que le notepadnotepad n’est pas fermé.

Dans le shell Windows, je fais juste

 cmd /c notepad 

(le notepadnotepad détache automatiquement de l’invite s’il n’est pas préfixé par cmd /c )

En C, en utilisant le system je fais juste

 system("notepad"); 

Mais cela se passe dans les coulisses. Je veux remplacer le processus actuel par le notepadnotepad et je veux qu’il soit bloquant.

J’ai essayé:

 #include  #include  int main(int argc,char **argv) { char * const args[] = {"cmd","/c","notepad",NULL}; execvp(args[0],args); } 

notepadnotepad s’exécute, mais la console retourne immédiatement à l’invite. (non bloquant). Je veux le bloquer et je ne veux pas utiliser fork car cela créerait un autre processus: je veux remplacer le processus actuel.

(J’ai essayé avec un exécutable de blocage personnalisé, et il ne bloque pas non plus. Donc, l’exemple de cmd /c notepad est aussi bon que n’importe quel autre)

Donc, si je lance cet exécutable que je viens de construire à partir d’un processus parent:

  • Je ne veux pas que le processus retourne au processus parent jusqu’à la fin du processus du notepadnotepad
  • Je veux pouvoir obtenir le résultat de la commande (le notepadnotepad n’est pas un bon exemple dans ce cas)
  • Je ne veux pas créer de processus supplémentaire (cela fait partie d’une application de multitraitement massive, nous ne pouvons pas nous permettre de créer deux processus, nous devons garder un processus pour chaque exécution).

Est-ce même possible?

Ce que vous voulez n’est pas tout à fait clair – le processus actuel ne peut pas attendre le processus enfant s’il est remplacé par son exécutable via une fonction execv*() .

Un remplacement possible de system() – sous Windows – est _spawnvp() :

 intptr_t _spawnvp( int mode, const char *cmdname, const char *const *argv ); 

Juste utiliser

 int rc = _spawnvp( _P_WAIT, command, args ); 

(Je suppose que la raison pour laquelle cette fonctionnalité exacte n’est pas disponible sur les systèmes POSIX est qu’elle est facilement implémentée sur POSIX via fork() , exec*() et une variante de wait() . Les équivalents Windows de ces derniers sont un peu plus complexes. )

Lorsque vous utilisez les fonctions Windows _spawn*() faire attention aux noms de fichiers contenant des espaces. J’ai eu quelques problèmes réels en passant de tels noms de fichiers via cette fonction et je devais les citer.