Как правильно использовать трубы и сигналы одновременно? - PullRequest
0 голосов
/ 28 января 2019

У меня есть 2 ребенка, и я хочу отправить сигналы от детей к родителю и дать ответ (случайное число, почему? Почему нет ...) именованный канал от родителя каждому ребенку.

Iесть этот код:

  #include <stdlib.h>
    #include <stdio.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <time.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>

    #include <unistd.h>
    #include <string.h>

    #define WRITE(Str) (void)write(1,Str,strlen(Str))
    void handler(int signumber)
    {
        WRITE("Signal arrived\n");
    }

    int main(){
      /*random number */
      srand(time(NULL)); //random number
      int r = rand() % 2; //random number between 0 and 1 
      char original1[]="rdnr: ";
      original1[6]=r+'0';
      r = rand() % 2; 
      char original2[]="rdnr: ";
      original2[6]=r+'0';

      /*pipe, named pipe*/
        int pid,fd,fd2;
        printf("Fifo start!\n");
        int fid=mkfifo("fifo.ftc", S_IRUSR|S_IWUSR ); // creating named pipe file
        int fid2=mkfifo("fifo2.ftc", S_IRUSR|S_IWUSR );

        if (fid==-1)  //error handling
        {
          printf("Error at fid number: %i",errno);
          exit(EXIT_FAILURE);
        }
        if (fid2==-1)  //error handling
        {
          printf("Error at fid2 number: %i",errno);
          exit(EXIT_FAILURE);
        }
        printf("Pipe system OK!\n");

      /*signal*/
      sigset_t sigset;
      sigemptyset(&sigset); //empty signal set
      sigaddset(&sigset,SIGTERM); //SIGTERM is in set
      //sigfillset(&sigset); //each signal is in the set
      sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blocked

      signal(SIGTERM,handler); //signal and handler is connetcted
      signal(SIGUSR1,handler); 

      pid_t child2;
      pid_t child=fork();
      if (child>0)
      {
        child2 = fork();
        if(child2>0){
          printf("Parent, wainting for signal...\n");

      sigsuspend(&sigset);
      sigprocmask(SIG_UNBLOCK,&sigset,NULL);
      int status;
      wait(&status);
      printf("Parent got 2 signal!\n");

      printf("Parent will send 2 random number: %s and %s\n", original1, original2);
      fd=open("fifo.ftc",O_WRONLY);
          write(fd,original1,12);
          close(fd);
      fd2=open("fifo2.ftc",O_WRONLY);
          write(fd2,original2,12);
          close(fd2);
      printf("Parent has sent the numbers!\n");
        }
        else{
          printf("I'm child2.\n");
          printf("child2 signalnr: %i (it is not blocked)\n", SIGUSR1);
          kill(getppid(),SIGUSR1);

          /*get pipe*/
          sleep(5);
          char s[1024]="nothn";  

          printf("got on pipe, in child2: %d!\n",fid);
          fd=open("fifo.ftc",O_RDONLY);
          read(fd,s,sizeof(s));
          printf("got this on pipe, by child2: %s \n",s);
          close(fd);
          // remove fifo.ftc
          unlink("fifo.ftc");
        }
      }
      else
      {
        printf("I'm child1.\n");
        printf("child1 signal nr: %i (it is blocked)\n",SIGTERM);
        sleep(3);
        kill(getppid(),SIGTERM);

        //sleep(5);
        /*get pipe*/
        char s[1024]="nothn";
        printf("Got this on pipe, by child1: %d!\n",fid2);
        fd2=open("fifo2.ftc",O_RDONLY);
        read(fd2,s,sizeof(s));
        printf("got this inpipe fd2: %s by child2 \n",s);
        close(fd2);
        // remove fifo2.ftc
        unlink("fifo2.ftc");
      }
      return 0;
    }

И каналы, и сигналы работают правильно, если я использую их отдельно, но вместе, здесь, нет.

Я получил только это:

Fifo start!
Error at fid number: 17

обработчиками ошибок.

Как правильно использовать каналы и сигналы одновременно?

ОБНОВЛЕНИЕ: Я переосмыслил родителякак было упомянуто в разделе комментариев, теперь вывод, который я вижу:

Fifo start!
Pipe system OK!
Parent, wainting for signal...
I'm child2.
I'm child1.
child1 signal nr: 15 (it is blocked)
child2 signalnr: 10 (it is not blocked)
Handled signal nr: 10
Got this on pipe, by child1: 0!
Handled signal nr: 15
got on pipe, in child2: 0!

Итак, проблема, как я вижу, в том, что дочерний процесс не может ждать конвейеры, как я могурешить эту проблему?

UPDATE2:

Если я удаляю

int status;
wait(&status); 

из родительского объекта, то работает нормально, просто ничто не является гарантией второгоСигнал поступает раньше, чем труба вещей.

1 Ответ

0 голосов
/ 28 января 2019

Одна повторяющаяся ошибка в вашем коде:

char original1[]="rdnr: ";
original1[6]=r+'0';

sizeof original1 равно 7, символ в индексе 6 является нулевым ограничителем строки.Перезаписывая нулевой терминатор с помощью r+'0', вы уничтожаете строковое свойство массива, так что вы больше не можете использовать strlen для него.

Fix:

char original1[] = "rdnr: 0";
original1[sizeof original1 - 2] += r;
...