Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3334 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Envoyer sur stdin, récupérer stdout, d'un processus crée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Envoyer sur stdin, récupérer stdout, d'un processus crée

n°903908
andOceans
AMGOD
Posté le 21-11-2004 à 11:38:36  profilanswer
 

Bonjour.
 
J'aimerai savoir comment faire pour envoyer des données dans un processus créé, et comment récupérer sa sortie (sans arrêter le processus j'entends).
 
Il s'agit d'une application client/serveur, côté client, il demande la création d'un processus, ie: CreateProcess bc par exemple, le serveur doit alors créer le processus de son côté et renvoyer "OK pid" (ou identifiant quoi). A partir de là, le client peut envoyer des données à son processus "SendInput <identifiant du proc> les données", et quand il désirera voir la sortie standard du proc "GetOutput <identifiant>" qui affichera côté client toute la sortie déjà effectuée par le processus (le processus étant toujours en exécution).
 
La majeure partie a été réalisé, mais là, je bloque sur la gestion de l'entrée/sortie standard du processus. (il faudra d'ailleurs aussi que je puisse récup' le code de retour du processus si le client le désire).
 
J'ai essayé de forker + exec à la main, de dup[2], mais sans succès. Après, j'ai vu la fonction pipe(), mais avec le fork et autre dup, je m'emmèlais un peu, enfin, j'ai vu popen() qui a l'air sympathique (réalise tout) mais je me demande si elle convient pour ce que je veux faire. (comme un popen ne peut être que "r" ou "w" exclusivement, je devrais en créer alors deux, un "r" pour GetOutput, un "w" pour SendInput, mais je n'ai qu'un processus à exécuter :|)
 
Quelqu'un aurait une idée générale pour réaliser ceci ?
 
Merci.
 
Edit: Je précise que plusieurs processus peuvent être créés (d'où l'id distinct pour chaque).


Message édité par andOceans le 21-11-2004 à 11:58:24
mood
Publicité
Posté le 21-11-2004 à 11:38:36  profilanswer
 

n°904027
Taz
bisounours-codeur
Posté le 21-11-2004 à 14:18:19  profilanswer
 

si communication père-files -> pipe
sinon IPC classique : SHM, tube nommés, socket

n°904099
andOceans
AMGOD
Posté le 21-11-2004 à 14:40:25  profilanswer
 

Et bien, avec les pipes, ça donne ça :
 

Code :
  1. typedef struct {
  2.   pid_t pid;
  3.   int rc;
  4.   int fd[2];
  5. } processinfo_t;
  6. #define IN  1
  7. #define OUT 0
  8. void send_input(pid_t pid, const char *input) {
  9.   ...
  10.   write(processes[index].fd[IN], input, strlen(input) + 1); 
  11. }
  12. char *get_output(pid_t pid) {
  13.   ...
  14.   read(processes[index].fd[OUT], buffer, sizeof buffer); 
  15.   return buffer;
  16. }
  17. pid_t create_process(const char *app) {
  18.     ...
  19.     proc = fork();
  20.     if (proc > 0) { return procinfo->pid = proc; }
  21.     if (proc == 0) {
  22.       if (execlp("tr", "tr", "[:upper:]", "[:lower:]", NULL) < 0)
  23. return 0;
  24.     }
  25.     ...
  26. }


 
Une sortie :
 


>> CreateProcess bla
## OK 3248
>> SendInput 3248 BlA
## OK
>> GetOutput 3248
## OK BlA <<<< je voudrais "OK bla"


 
Il manque l'étape du <je passe dans le processus>. Mais je n'arrive pas à savoir comment la mettre. J'ai essayé des dup2(foo.fd[IN], STDIN_FILENO) mais je n'ai jamais le résultat escompté.

n°913430
andOceans
AMGOD
Posté le 03-12-2004 à 00:17:44  profilanswer
 

Alors alors.. j'ai crée en fait deux tubes (in, et out), chacun unidirectionnel, un pour père -> fils, l'autre, fils -> père. Dans la création du processus côté serveur, j'ai maintenant :
 

Code :
  1. if (proc == 0) {
  2.       /* L'envoi sur stdin fonctionne */
  3.       dup2(procinfo->in[READ], STDIN_FILENO);
  4.       close(procinfo->in[READ]);
  5.       close(procinfo->in[WRITE]);
  6.       /* Ne fonctionne pas !! =(
  7.       dup2(procinfo->out[WRITE], STDOUT_FILENO);
  8.       close(procinfo->out[READ]);
  9.       close(procinfo->out[WRITE]); */
  10.       execlp("tr", "tr", "[:upper:]", "[:lower:]", NULL);
  11.       return 0;
  12. }


La redirection du stdout ne fonctionne toujours pas. Quand j'appelle GetOutput, qui exécute ## n = read(processes[index].out[READ], buffer, sizeof buffer); ##, le client bloque. Pourtant, il a dû y avoir une sortie car auparavant, j'envoie quelque chose via un SendInput ... (celui ci fonctionne, j'ai testé en commentant le "ne fonctionne pas", et côté serveur, ca affiche bien le texte passé par le client en lower)
 
Help =(

n°914629
andOceans
AMGOD
Posté le 04-12-2004 à 13:30:58  profilanswer
 

Le plus bizarre, c'est que si je mets ça :  

Code :
  1. if (proc == 0) {
  2.       dup2(procinfo->in[READ], STDIN_FILENO);
  3.       close(procinfo->in[READ]);
  4.       close(procinfo->in[WRITE]);
  5.       dup2(procinfo->out[WRITE], STDOUT_FILENO);
  6.      
  7.       /* les deux agissent pareillement et fonctionnent */
  8.       write(STDOUT_FILENO, "foobar", strlen("foobar" ) + 1);
  9.       write(procinfo->out[WRITE], "foobar", strlen("foobar" ) + 1);
  10.       execlp("tr", "tr", "[:upper:]", "[:lower:]", NULL);
  11.       return 0;
  12.     }


Les deux writes fonctionnent ! (ie: je peux récupérer "foobarfoobar" quand je fais un GetOutput) Logiquement, tr écrivant sur STDOUT_FILENO aussi, devrait remplir le pipe, or, ça bloque, donc je suppose qu'il ne le remplit pas.. (close on exec est bien à 0 pour les descripteurs)

n°914759
andOceans
AMGOD
Posté le 04-12-2004 à 16:03:54  profilanswer
 

En fait, il s'agit d'un problème de flush.

Code :
  1. if (proc == 0) {
  2.       dup2(procinfo->in[READ], STDIN_FILENO);
  3.       close(procinfo->in[READ]);
  4.       close(procinfo->in[WRITE]);
  5.       dup2(procinfo->out[WRITE], STDOUT_FILENO);
  6.       close(procinfo->out[READ]);
  7.       close(procinfo->out[WRITE]);
  8.       printf("Blablabla" );
  9.       /*fflush(stdout);*/
  10.       execlp("tr", "tr", "[:upper:]", "[:lower:]", NULL);
  11.       return 0;
  12.     }


Sans le fflush, si je crée un processus et que je lis directement sa sortie, le client bloque; avec le fflush, je récupère "Blablabla". Il faudrait donc que le stdout du processus execlp soit fflushé à chaque entrée, comme stderr je crois. (sans pour autant les fusionner avec des dups, j'aimerai avoir le stderr à part également si c'est possible :\)
 
J'ai été voir du côté de fnctl, mais rien ne concernant mon problème amha. Comment faire ?


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Envoyer sur stdin, récupérer stdout, d'un processus crée

 

Sujets relatifs
[PHP] Recuperer des valeurs = 0 apres un post [Resolu][SQL]recuperer premier enregistrement
<input type="file"> mais sans envoyer le fichier ... possible ?Récupérer le login de .htaccess
[delphi] recuperer les index d'une tableRécupérer les cookies lors d'une connection http
recupérer chiffres dans une chaine[C]Intercepter les donnees ecrites par un processus
[JAVA ou C++]Récupérer de la video à partir d'une carte pinnacleenvoyer variable d'un formulaire en cliquant sur une image
Plus de sujets relatifs à : Envoyer sur stdin, récupérer stdout, d'un processus crée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR