Thread: Problems with pipe and exec in linux

  1. #1
    Registered User
    Join Date
    Jan 2016
    Posts
    4

    Problems with pipe and exec in linux

    Hi,

    It is my first post so I want say hello everyone ! What brings me here? I have some trouble with my code.

    I want to communicate two programs using pipes.First of all I don't want to use named pipe, just simple dup2(). I have two programs:1) program2.c - want to read from pipes using select (check after 15s if is possibility). I use exec and pass the pipe to argument.
    2) program1.c , do a lot but in short - endless loop, waiting for signal, and after signal write to pipe

    I know that problem is around the pipe because when I don't use pipe - just simple text file - all work fine. What I get? Information from select - "No communicate so far.." Like select no return any result

    I would be grateful for any help

    program1.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <signal.h>
    #include <time.h>
    #include <fcntl.h>
    #include <string.h>
    
    
    sig_atomic_t wyjsc = 0; 
    
    
    int *fd;
    
    
    void czekaj_czas()
    {
       struct sigevent evp;
       struct itimerspec ts2;
       timer_t timer;
       int ret2 ;
    
    
       evp.sigev_value.sival_ptr = &timer;
       evp.sigev_notify = SIGEV_SIGNAL;
       evp.sigev_signo = SIGALRM;
    
    
       ret2 = timer_create(CLOCK_MONOTONIC,&evp,&timer);
       if(ret2)
            perror("Blad funkcji timer_create");
    
    
       ts2.it_interval.tv_sec = 0;
       ts2.it_interval.tv_nsec = 0;
       ts2.it_value.tv_sec = 3;
       ts2.it_value.tv_nsec = 0;
    
    
       if(timer_settime(timer,0,&ts2,NULL))
            perror("timer_settime");
    
    
    }
    
    
    void handler_signal(int signal)
    {
       sigset_t pending; 
       int losowy_czas ;  
       struct timespec ts; 
       int ret; 
       char buf[10]; 
    
    
       int ret3; 
    
    
       ssize_t ret_out;
    
    
       int j = 0; 
    
    
       srand((unsigned int) time(NULL));    
       losowy_czas = rand() % 15 + 5;  
       ts.tv_nsec=losowy_czas*100000000;
       ts.tv_sec=ts.tv_nsec/1000000000;
       ts.tv_nsec-=ts.tv_sec*1000000000;
    
    
       ret = clock_nanosleep(CLOCK_MONOTONIC,0,&ts,NULL); 
    
    
    
    
       switch(signal)
       {
        case SIGUSR1: 
            wyjsc = 1; 
            czekaj_czas();
            break;
        case SIGALRM:
                wyjsc = 0; 
            break; 
        default:
            fprintf(stderr,"Zlapany zly sygnal: %d \n", signal); 
            return; 
      }
    
    
    
    
       if(ret)
        perror("Funkcja zakonczona, signal dostarczony do procesu");    
    
    
    
    
       // fd = open("?", O_RDWR | O_CREAT | O_APPEND); ???
       snprintf(buf, 10, "%ld\n", (long) getpid()); 
       while(wyjsc)
        {
        ret_out = write(fd[0], buf, strlen(buf));
        if(ret_out == -1) 
            perror("blad zapisu do bliku"); 
        }   
    
    
    }
    int main(int argc, char *argv[])
    {
       int i; 
       long val; 
       char *endptr; 
       struct sigaction sa;     
    
    
    
    
    
    
       if(argc != 2)
       {
        fprintf(stderr,"Niepoprawna liczba argumetnow procesu P \n");
        exit(EXIT_FAILURE);
       }    
    
    
       val = strtol(argv[1],&endptr, 0);    
       if(endptr == argv[1])
       {
        fprintf(stderr,"Niepoprawny parametr funkcji ! \n");
        exit(EXIT_FAILURE);
       }
    
    
       fd = (int *)val; // Can I do like that?
    
    
    
    
    
    
    
    
    
    
       sa.sa_handler = &handler_signal;
       sa.sa_flags = SA_RESTART | SA_NODEFER; 
    
    
       //blokowanie wszystkich innych sygnalow
       // :sigfillset(&sa.sa_mask); 
    
    
       if(sigaction(SIGUSR1,&sa,NULL) == -1)
       {
        perror("Nie mozna obsluzyc SIGUSR1");   
       }
    
    
       if(sigaction(SIGALRM,&sa,NULL) == -1)
       {
        perror("Nie mozna obsluzyc SIGALRM");
       }
    
    
       while(1){ }  
    
    
       return;
    }
    program2.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <signal.h>
    #include <time.h>
    #include <fcntl.h>
    #include <string.h>
    
    
    
    
    int main(int argc, char *argv[])
    {
      int i ; 
      pid_t pid; 
      pid_t pid2; 
    
    
      int val;
      char *endptr;  
    
    
      int pipefd[2]; 
    
    
      char parametr[32]; 
    
    
       if(argc != 2)
       {
            fprintf(stderr,"Niepoprawna liczba argumetnow procesu P \n");
            exit(EXIT_FAILURE);
       }
    
    
       val = strtol(argv[1],&endptr, 0);
       if(endptr == argv[1])
       {
            fprintf(stderr,"Niepoprawny parametr funkcji ! \n");
            exit(EXIT_FAILURE);
       }
    
    
    
    
      /* pipe  
          pipe0 - write
          pipe1 - read
      */
      if(pipe(pipefd) == -1)
       {
        perror("pipe");
        exit(EXIT_FAILURE);
       }
    
    
      sprintf(parametr,"%d",pipefd[0]); 
    
    
      printf("%s \n",parametr);
    
    
    
    
       pid = fork() ;
       if(pid < 0)
       {
        perror("fork!"); 
       }  
       else if(pid == 0)
       {
        /* FIRST CHILD ! 
            create all proces in val
        */
        for(i = 0;i<val; i++)
        {
                pid2 = fork(); 
                if(pid2 < 0)
                 {
                    perror("Fork");         
                 }
                 else if(pid2==0)
                 {
                    int ret;
                    /* Child process */     
             // read 
            dup2(pipefd[0],STDIN_FILENO); // write      
            close(pipefd[1]);
            ret = execl("program1","program1", parametr,NULL); 
                if(ret == -1)
                        perror("Execl");
                    }
                 else{
                        wait(NULL);
                 }
        } /* END OF FOR */ 
       }
       else{
        /* PARENT */
        // select //    
        fd_set set;
        struct timeval timeout;
        int sel; 
        char buf;   
    
    
        close(pipefd[0]) ;  
    
    
        FD_ZERO(&set); 
        FD_SET(pipefd[1], &set); // READ
    
    
        timeout.tv_sec = 17; 
        timeout.tv_usec = 0; 
    
    
        sel = select(FD_SETSIZE,&set,NULL,NULL,&timeout);
        if(sel < 0 )
        {
            perror("Blad funkcji select");  
        }
        else if(sel == 0)
        {
            printf("Brak komunikatkow \n");
        }
        else{
            // read from pipe - 
            while(read(pipefd[0], &buf,1) > 0)
                write(STDOUT_FILENO, &buf,1);  
        }
    
    
       } 
    
    
    
    
    }

  2. #2
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    First, this belongs in the Linux sub-forum.

    Second, you install your signal handlers incorrectly, and in your signal handler, you use non-async-signal-safe functions. That means the behaviour of your program is undefined (if a signal is received). The man 7 signal man page contains the list of async-signal-safe functions under that heading; you can use those, and only those, functions in a signal handler.

    Third, you have a lot of code with little idea where the actual problem is. That's a lot of code to wade through.

    Fourth, you don't tell us how the programs are supposed to communicate. Which one writes to each pipe, which one reads from it? Who writes first, so that you avoid the deadlock when all processes are waiting for someone else to write first?

    You should always develop your programs one feature at a time, so that the program compiles without any warnings (using -Wall; personally, I also use -Wall -Wextra -Wno-unused-parameter), and runs correctly. That way you can pinpoint most errors to the part of the code you added last.

  3. #3
    Registered User
    Join Date
    Jan 2016
    Posts
    4
    Ok, thx. I correct the mistakes and I created new topic in good sub-forum.

    Problems with pipe and exec in linux

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. FIFO - Named Pipe - Linux - C
    By hell-student in forum C Programming
    Replies: 5
    Last Post: 12-16-2012, 12:10 PM
  2. Exec and Pipe problem
    By Matteaus in forum C Programming
    Replies: 2
    Last Post: 09-06-2010, 09:02 AM
  3. Replies: 4
    Last Post: 10-14-2009, 04:44 PM
  4. Replies: 3
    Last Post: 06-02-2009, 06:13 PM
  5. exec with linux pipe command
    By rotis23 in forum C Programming
    Replies: 4
    Last Post: 08-22-2002, 08:34 AM

Tags for this Thread