Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] Pipe tra convert e barcode in linux

    Vorrei eseguire una pipe tra il comando barcode e il comando convert in linux. Ho provato con questo codice: barcode:
    Codice PHP:
    if(pbarcode == 0){//sono nel processo figlio per il lancio del comando barcode
                      
    close(pb[1]);//Chiudo in lettura
                      
    dup2(pb[0],0);
                      
    close(pb[0]);
                      
    execlp("barcode""barcode""-b"codice"n""-E""-e""ean""-u""mm""-g""60x25+1+1"NULL);/
                     } 
    codice convert:
    Codice PHP:
    if(pconvert == 0){//sono nel processo figlio per la conversione del file
                                     
    close(pb[0]);//Chiudo in scrittura
                                     
    dup2(pb[1],1);
                                     
    close(pb[1]);
                                     
    execlp("convert","convert",nome2,NULL);
                                     } 
    nome2 è una stringa che contiene il nome del file destinazione.bmp.
    Temo non riesca a essere ricevuto il ps creato da barcode. Vedo infatti l'output a video ma non viene elaborato da convert.
    Avreste qualche suggerimento da darmi?
    Grazie in anticipo.

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    barcode deve scrivere nella pipe e convert leggere, ma tu stai facendo il contrario

    codice:
    if ( pbarcode == 0 ) {
                      close(pb[0]); /* Chiudo in lettura */
                      dup2(pb[1], 1);
                      close(pb[1]);
    
                      execlp("barcode", "barcode", "-b", codice, "n", "-E", "-e", "ean", "-u", "mm", "-g", "60x25+1+1", NULL);
    }
    codice:
    if ( pconvert == 0 ) {
                      close(pb[1]); /* Chiudo in scrittura */
                      dup2(pb[0], 0);
                      close(pb[0]);
                      execlp("convert", "convert", nome2, NULL);
    }
    every day above ground is a good one

  3. #3
    Grazie!

  4. #4
    Ho modificato il listato di ieri utilizzando la popen. Ho però un problema strano nella copia del file .ps. Il file viene creato, quindi fino alla riga
    Codice PHP:
    fps=fopen(nome1,"w"); 
    tutto dovrebbe essere ok. In seguito non viene copiato alcun carattere nel file .ps e il programma termina dando un errore stack smashing detected. Potreste per favore darmi qualche indicazione su come risolverlo?
    Grazie
    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>

    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #define PERM 0777
    #define SIZE 100000
    main(){
        
    char codice[13]; //il barcode è EAN 13
        
    char nome[15],nome1[15],nome2[15];
        
    char ext1[]=".ps";//Stringa per estensione .ps
        
    char ext2[]=".bmp";//Stringa per estensione .bmp
        
    FILE *pb;//Descrittore di file per la pipe convert | barcode
        
    FILE *fps;//Descrittore del file .ps
        
    char rb[]="barcode -b ";
        
    int n;
        
    pid_t pbarcode,pconvert,pelimina;//pid per il processo che lancia il comando barcode e per quello che lancia convert
        
    printf("\nInserire il codice EAN\n");
        
    scanf("%s"codice);
           
    printf("\nInserire il nome del prodotto\n");
        
    scanf("%s"nome);
        
    strcpy(nome1,nome);
        
    strcpy(nome2,nome);
        
    strcat(nome1,ext1);
        
    strcat(nome2,ext2);
        
    strcat(rb,codice);
        
    strcat(rb," n -E -e ean -u mm -g 60x25+1+1");
        if((
    pb=popen(rb,"r"))==NULL){
                         
    printf("Errore popen non riuscita\n");
                         exit(-
    2);
                        }    
               else{
    //Sono nel processo padre
                     
    if(pconvert=fork() < 0){//crea un processo per lanciare il comando convert
                            
    printf("Fork per convert fallita\n");
                            exit(-
    3);
                            }    
                         if(
    pconvert == 0){//sono nel processo figlio per la conversione del file
                              
    fps=fopen(nome1,"w");
                              while((
    n=fgetc(pb)) != EOF ){//Copia dalla pipe al file
                                                    
    fputc(n,fps);
                                                    }
                              
    pclose(pb);
                              
    fclose(fps);
                              }
                              
    char nc[]="convert ";//Stringa comando convert
                                     
    strcat(nc,nome1);
                                     
    strcat(nc," ");
                                     
    strcat(nc,nome2);
                               
    execl("convert",nc,NULL);
              }
        
    waitpid(pconvert,NULL,0);                  
        return 
    0;
        } 

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Non ho modo di provare quel codice perché non ho barcode, ma vedo comunque alcune cose strane... innanzitutto, tra le ultime righe del programma richiami execl(), che è diversa da execlp(): a quest'ultima non hai bisogno di passare il path completo del comando/programma (il sistema lo ricerca automaticamente nelle directory del tuo PATH, come la "p" del nome della funzione ricorda). La execl() invece necessita del path completo del comando, qundi scrivere solo "convert" non va bene...

    Inoltre fai un uso scorretto di popen(): questa funzione non è come una fork(), non devi differenziare tra processo padre e figlio con il costrutto if - then - else... la popen crea un processo eseguendo il comando/programma che le passi, scrive l'output su uno stream di cui restituisce il puntatore come valore di ritorno e chiude subito il processo. Dopo la chiamata popen(), puoi servirti di quello che è stato scritto per compiere altre operazioni.

    Questo è un esempio di utilizzo... il programma richiama ls con popen, l'output viene scritto su un file (lsfile) e questo viene poi ordinato da sort. Ho lasciato execl(), specificando però il path completo del comando.

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <errno.h>
    
    int main(void)
    {
    	int byte;
    	char *output = "lsfile";
    	FILE *my_pipe, *fp;
    	pid_t pid;
    
    	if( ( my_pipe = popen("ls", "r") ) == NULL ) {
    		fprintf(stderr, "An error has occurred with popen(): %s\n", strerror(errno));
    		exit(errno);
    	}
    
    	fp = fopen(output, "w");
    	if ( fp == NULL ) {
    		fclose(my_pipe);
    		fprintf(stderr, "Unable to open %s: %s\n", output, strerror(errno));
    		exit(errno);
    	}
    
    	while ( ( byte = fgetc(my_pipe) ) != EOF ) /* Copia dalla pipe al file */
    		fputc(byte ,fp);
    
    	fclose(fp);
    	fclose(my_pipe);
    
    	/* la creazione di un nuovo processo per eseguire sort non è necessaria */
    
    	pid = fork();
    	if ( pid < 0 ) {
    		fprintf(stderr, "An error has occurred with fork(): %s\n", strerror(errno));
    		exit(errno);
    	}
    	if ( pid == 0 ) {
    		execl("/usr/bin/sort", "sort", output, NULL);
    		fprintf(stderr, "An error has occurred with execlp(): %s\n", strerror(errno));
    		exit(errno);
    	}
    
    	waitpid(pid, NULL, 0);
    
    	return 0;
    }
    every day above ground is a good one

  6. #6
    Ti ringrazio per l'esempio. Adesso ho messo a posto la fork di troppo e anche il file .ps adesso è generato correttamente. Mi rimane però un problema. Pur venendo creato correttamente il file nome1 e pur essendo corretta la riga di comando che arriva alla execlp (ho messo una riga di controllo per verificarla)
    Codice PHP:
    printf("La riga di comando e' %s \n",nc);
    execlp("convert",nc,NULL); 
    il comando convert anzichè convertirmi il file mi mostra il man, come se gli fossero passati dei parametri sbagliati.
    Il listato modificato è questo:
    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>

    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #define PERM 0777
    main(){
        
    char codice[13]; //il barcode è EAN 13
        
    char nome[15],nome1[15],nome2[15];
        
    char ext1[]=".ps";//Stringa per estensione .ps
        
    char ext2[]=".bmp";//Stringa per estensione .bmp
        
    FILE *pb;//Descrittore di file per la pipe convert | barcode
        
    FILE *fps;//Descrittore del file .ps
        
    char rb[]="barcode -b ";
        
    int n;
        
    pid_t pbarcode,pconvert,pelimina;//pid per il processo che lancia il comando barcode e per quello che lancia convert
        
    printf("\nInserire il codice EAN\n");
        
    scanf("%s"codice);
           
    printf("\nInserire il nome del prodotto\n");
        
    scanf("%s"nome);
        
    strcpy(nome1,nome);
        
    strcpy(nome2,nome);
        
    strcat(nome1,ext1);
        
    strcat(nome2,ext2);
        
    strcat(rb,codice);
        
    strcat(rb," n -E -e ean -u mm -g 60x25+1+1");
        
    fps=fopen(nome1,"w");
        if((
    pb=popen(rb,"r"))==NULL){
                         
    printf("Errore popen non riuscita\n");
                         exit(-
    2);
                        }    
                    while((
    n=fgetc(pb)) != EOF ){//Copia dalla pipe al file
                                     
    fputc(n,fps);
                                     }
                              
    pclose(pb);
                              
    fclose(fps);
                              
    //}
                              
    char nc[]="convert ";//Stringa comando convert
                                     
    strcat(nc,nome1);
                                     
    strcat(nc," ");
                                     
    strcat(nc,nome2);
                                  
    printf("La riga di comando e' %s \n",nc);
                               
    execlp("convert",nc,NULL);          
        return 
    0;
        } 
    Ti prego di scusarmi per il disturbo. E' il primo programma nel quale uso le syscall e probabilmente qualcosa mi sfugge nei meccanismi.
    Grazie.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Penso non sia corretto passare a execlp() una stringa che contenga l'intero comando... devi passare gli argomenti separati. Prova con:

    codice:
    execlp("convert", "convert", nome1, nome2, NULL);
    every day above ground is a good one

  8. #8
    Grazie mille!
    Ho appena provato e in effetti il problema della execlp era proprio quello che mi hai indicato.

  9. #9
    Scusa se disturbo ancora. Purtroppo ho un altro problema che non riesco a superare. Ho inserito una serie di fork per consentire al processo padre di proseguire oltre il comando convert e lanciare altri due comandi, uno di cancellazione del file .ps e uno di lancio di gimp. Però il programma non va oltre convert. Non so perchè ma non entra nei processi successivi. Allego il listato:
    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>

    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #define PERM 0777
    main(){
        
    char codice[13]; //il barcode è EAN 13
        
    char nome[15],nome1[15],nome2[15];
        
    char ext1[]=".ps";//Stringa per estensione .ps
        
    char ext2[]=".jpg";//Stringa per estensione .jpg
        
    FILE *pb;//Descrittore di file per la pipe convert | barcode
        
    FILE *fps;//Descrittore del file .ps
        
    char rb[]="barcode -b ";
        
    int n;//Variabile per la lettura caratteri dalla pipe
        
    char e;//Variabile per controllo uscita finale
        
    pid_t pconvert,pelimina,pmostra;//pid per il processo che cancella il file .ps e per il processo che lancia Gimp
        
    printf("\nInserire il codice EAN\n");
        
    scanf("%s"codice);
           
    printf("\nInserire il nome del prodotto\n");
        
    scanf("%s"nome);
        
    strcpy(nome1,nome);
        
    strcpy(nome2,nome);
        
    strcat(nome1,ext1);
        
    strcat(nome2,ext2);
        
    strcat(rb,codice);
        
    strcat(rb," n -E -e ean -u mm -g 60x25+1+1");
        
    fps=fopen(nome1,"w");
        if((
    pb=popen(rb,"r"))==NULL){
                         
    printf("Errore popen non riuscita\n");
                         exit(-
    1);
                        }    
                        while((
    n=fgetc(pb)) != EOF ){//Copia dalla pipe al file
                                              
    fputc(n,fps);
                                             }
                              
    pclose(pb);
                              
    fclose(fps);
        if(
    pconvert=fork() < 0){//crea un processo per lanciare il comando convert e lasciare il processo padre aperto per eseguire i comandi successivi
                        
    printf("Fork per conversione file fallita\n");
                        exit(-
    2);
                        }
        if(
    pconvert == 0){//sono nel processo figlio per la conversione del file
                  
    execlp("convert","convert",nome1,nome2,NULL);
                 }
        else if(
    pconvert>0){
                    
    printf("Sono uscito da convert\n");
                    
    wait(NULL);//sono nel processo padre e aspetto che termini la conversione
                    
    if(pelimina=fork() < 0){//crea un processo per lanciare il comando unlink
                                
    printf("Fork per cancellazione file fallita\n");
                                exit(-
    3);
                               }
                   if(
    pelimina == 0){//sono nel processo figlio per l'eliminazione del file .ps
                               
    printf("Sono entrato in elimina\n");
                               
    unlink(nome1);
                              }
                   else if(
    pelimina>0){
                            
    //Sono nel processo padre che può proseguire indipendentemente dalla cancellazione del file .ps
                            
    if(pmostra=fork() < 0){//crea un processo per lanciare gimp
                                
    printf("Fork per Gimp fallita\n");
                                exit(-
    4);
                                }
                            if(
    pmostra==0){//sono nel processo figlio per il lancio dell'applicazione gimp
                                  
    execlp("gimp","gimp",nome2,NULL);//lancia l'apertura del nuovo file con Gimp
                                 
    }
                            else if(
    pmostra>0){
                                       
    printf("Premere il tasto e per chiudere Gimp e uscire\n");
                                       while(
    != 'e'){
                                       
    scanf("%c",&e);
                                       }
                              
    kill(pmostra,9);
              
    wait(NULL);//Aspetta la fine di tutti i processi figli
        
    return 0;
                            }
        }
        }
        } 
    Grazie in anticipo. Buon ferragosto.

  10. #10
    Scusate se disturbo ancora. Sono riuscito a superare il problema di cui sopra modificando il codice. Ho il problema però che adesso uscendo dal programma ho un errore di stack smashing detected e segmentation fault. La cosa strana è che l'errore me lo da in uscita dopo che tutte le operazioni sono andate a buon fine. Ringrazio in anticipo per i suggerimenti.
    Codice PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>

    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #define PERM 0777
    main(){
        
    char codice[13]; //il barcode è EAN 13
        
    char nome[15],nome1[15],nome2[15];
        
    char ext1[]=".ps";//Stringa per estensione .ps
        
    char ext2[]=".jpg";//Stringa per estensione .jpg
        
    FILE *pb;//Descrittore di file per la pipe convert | barcode
        
    FILE *fps;//Descrittore del file .ps
        
    FILE *fjpg;//Descrittore per il test dell'esistenza del file jpg
        
    char rb[]="barcode -b ";
        
    int n;//Variabile per la lettura caratteri dalla pipe
        
    char e;//Variabile per controllo uscita finale
        
    pid_t pconvert,pmostra;//pid per il processo che converte il file .ps e per il processo che lancia Image Viewer
        
    printf("\nInserire il codice EAN\n");
        
    scanf("%s"codice);
           
    printf("\nInserire il nome del prodotto\n");
        
    scanf("%s"nome);
        
    strcpy(nome1,nome);
        
    strcpy(nome2,nome);
        
    strcat(nome1,ext1);
        
    strcat(nome2,ext2);
        
    strcat(rb,codice);
        
    strcat(rb," n -E -e ean -u mm -g 60x25+1+1");
        
    fps=fopen(nome1,"w");
        if((
    pb=popen(rb,"r"))==NULL){
                         
    printf("Errore popen non riuscita\n");
                         exit(-
    1);
                        }    
                        while((
    n=fgetc(pb)) != EOF ){//Copia dalla pipe al file
                                              
    fputc(n,fps);
                                             }
                              
    pclose(pb);
                              
    fclose(fps);
        
    pconvert=fork();//crea un processo per lanciare il comando convert e lasciare il processo padre aperto per eseguire i comandi successivi
        
    if(pconvert 0){
                  
    printf("Fork per conversione file fallita\n");
                  exit(-
    2);
                }
        if(
    pconvert == 0){//sono nel processo figlio per la conversione del file
                  
    execlp("convert","convert",nome1,nome2,NULL);
                 }
        if(
    pconvert>0){
                   
    wait(NULL);//sono nel processo padre e aspetto che termini la conversione
                   
    unlink(nome1);//Cancello il file .ps
                   
    pmostra=fork();//crea un processo per lanciare Image Viewer
                   
    if(pmostra 0){
                              
    printf("Fork per Image Viewer fallita\n");
                              exit(-
    3);
                           }
                   if(
    pmostra == 0){//sono nel processo figlio per il lancio dell'applicazione gimp
                        
    fjpg=fopen(nome2,"rb");
                        if(
    fjpg == NULL){
                                       
    printf("Errore, conversione a jpg non riuscita\n");
                                       exit(-
    4);
                                        }
                                    
    execlp("gpicview","gpicview",nome2,NULL);//lancia l'apertura del nuovo file con Image Viewer
                                   
    }                    
                   if(
    pmostra>0){
                         
    printf("Premere il tasto e per chiudere Image Viewer e uscire\n");
                         while(
    != 'e'){
                                 
    scanf("%c",&e);
                                }
                              }
                
    kill(pmostra,SIGTERM);//Termina Image Viewer
                
    }
            
    wait(NULL);//Aspetta la fine di tutti i processi figli
            
    return 0;
            } 

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 © 2025 vBulletin Solutions, Inc. All rights reserved.