Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160

    [C] Eseguire popen() senza visualizzare l'output

    Ciao a tutti!

    Sto implementando una piccola shell e devo creare il meccanismo delle pipe. Ho pensato che si potesse usare la funzione popen per ogni comando da eseguire nella pipe. Il problema è che non so quale potrebbe essere un modo per eseguire un comando senza visualizzare il suo output. Cioè deve comportarsi come la pipe di Linux che fa vedere l'output solo dell'ultimo comando nella catena della pipe e quindi degli altri no. Come posso fare?

  2. #2
    Una volta ottenuto l'andle dell'eseguibile..
    codice:
    FILE *handle = _popen( "NomeTuoEseguibile", "rt");
    ... E controllata la sua validità...
    codice:
    	if (handle == NULL)
    		printf("_popen Error ...");
    ... Devi occuparti anche del suo output, dichiarando un buffer ...
    codice:
    	char *message[256];
    ... E metterti in attesa ...
    codice:
    	// Attende finchè fgets non restituisce NULL 
    	// (ovvere quando il programma ha terminato la sua esecuzione)
    	while (fgets(message, sizeof(message), handle))
    	{
    		if( strcmp( message, "Samuele\n") )
    		{
    			// Fai qualcosa
    		}
    	}
    ... Ma potresti anche ignorarne completamente l'output.
    Quando il programma sarà terminato, terminarà anche il ciclo while.
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Aspetta perché non ho capito molto bene. Allora io ho pensato di fare una cosa del genere. Creo una variabile del tipo FILE* fpipe[num_comandi]. Dopo Creo un figlio e poi nel figlio, per ogni comando da eseguire, (quindi facendo per esempio for(i=0; i<num_comandi; ++i) ) lancio la popen di quel comando con il flag w (non conosco la __popen che hai scritto tu). A questo punto cosa dovrei fare? Catturare l'output in un buffer come hai scritto tu? E dopo come faccio a redirezionare questo buffer in input al successivo programma?

  4. #4
    Originariamente inviato da Manugal
    Aspetta perché non ho capito molto bene. Allora io ho pensato di fare una cosa del genere. Creo una variabile del tipo FILE* fpipe[num_comandi].
    Ovvero un array di puntatori a file.
    Dopo Creo un figlio e poi nel figlio, per ogni comando da eseguire, (quindi facendo per esempio for(i=0; i<num_comandi; ++i) ) lancio la popen di quel comando con il flag w
    Ma tu devi inviare ("w") o ricevere ("r") i dati ai tuoi eseguibili ?
    (non conosco la _popen che hai scritto tu).
    Scusa, che compilatore stai utilizzando ?
    Comunque sono la stessa cosa, ed il prototipo delle due funzioni è uguale
    FILE *_popen (const char *command, const char *mode);
    FILE *popen(const char *command, const char *mode);
    A questo punto cosa dovrei fare? Catturare l'output in un buffer come hai scritto tu?
    Si
    E dopo come faccio a redirezionare questo buffer in input al successivo programma?
    Che tipo di output restituiscono i programmi ?
    Ti occupi tu di parsare questo output ?
    Come lo avvii questo programma successivo ?
    Comunque in generale, devi accodare l'output del primo programma alla linea di comando
    che avvia il secondo.
    Se avvii
    Programma1.exe
    che ti restituisce
    "1"
    il successivo programma lo avvierai così
    Programma2.exe 1
    Ovvero risolvi con una strcat (ricordati di aggiungere lo spazio fra ogni parametro)
    A questo punto se mostri il codice, riusciremo a fare un pò più di chiarezza .
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Allora deve funzionare coma la shell di linux. Se io eseguo questo comando:

    ls -l | grep [a-c]*.c

    L'output di ls -l deve andare in input a grep che poi produrra il suo output. Quindi ogni comando deve ricevere l'input dal precedente e inviare l'output al successivo. Come compilatore io uso gcc. Adesso posto un pezzo del codice.

    codice:
    #include "functions.h"
    
    void pipecmds(char **commands, int cmds){
       FILE *fpipe[cmds];
       int fd;
       int i,status;
       pid_t pid;
       if((pid=fork()) < 0){
          perror("fork error");
          exit(FORK_ERR);
       }
       if(pid == 0){
          for(i=0; i<cmds; --i){
             fpipe[i]=popen(commands[i],"w");
             dup2(fileno(fpipe[i]), STDOUT_FILENO);
          }
          for(i=cmds; i>0; --i)
             pclose(fpipe[i]);
       }
       if(pid > 0){
          if (waitpid(pid,&status,0) == -1){
             if(errno!=EINTR){
                perror("waitpid error");
                exit(WAIT_ERR);
             }
             else{
                kill(pid,SIGTERM);
                   do{
                      if (waitpid(pid,&status,0) != -1)
                      break;
                   }while(errno==EINTR);
             }
          }
       }
       return;
    }

  6. #6
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Nessuno?

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Per non far vedere l'output ho redirezionato sulla fpipe l'STDOUT, prima della chiamata alla popen. Ora però come faccio a passare l'output di ogni comando della pipe al successivo? Non ho capito anche se devo usare la popen con il flag r o con il flag w.

  8. #8
    aspetta un momento.

    La popen quando esegue il comando, crea automaticamente un processo figlio con cui esegue il comando e apre una pipe con il tuo processo per comunicare l'output. Il file che ti restituisce non è altro che il lato di lettura della pipe.
    quindi lo standard output è automaticamente rediretto nella pipe e a te basta leggere dal file che ti viene restituito per ottenere lo standard output.

    Puoi redirigere lo standard error del comando sullo standard output accodando alla stringa del comando anche 2<&1. In questo modo anche lo standard error finirà nella pipe.

    Ecco un po di codice di come eseguire il comando.
    Considera che in buf è presente la stringa del comando da eseguire
    codice:
    	comando=strcat(buf," 2>&1");
    	//Esecuzione del comando e invio dei risultati al processo tramite pipe
    	command_file=popen(comando,"r");
           //Lettura dei risultati nella pipe e invio al client
    	printf("\nInvio dei risultati in corso....\n");
    	bytes=fread_unlocked(buf,1,512,command_file);
    Non fare caso a quella funzione fread_unlocked l'avevo usata io in un progetto per l'università.
    Serve per fare letture non bloccanti. Ma nel tuo caso ti basta usare una semplice lettura da file con una read ad esempio

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.