Advertisement
3axap_010

Sender.c

Mar 19th, 2020
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.13 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <termios.h>
  4. #include <signal.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <semaphore.h>
  9. #include <fcntl.h>
  10. #include <sys/stat.h>
  11.  
  12.  
  13. const char* exename = "/home/zakhar/Documents/C/Signals/Receiver";
  14. const char* pattern = "Process";
  15. const int cmd_line_args_count = 3;
  16.  
  17. struct stack
  18. {
  19.     pid_t pid;
  20.     struct stack* next;
  21. };
  22.  
  23. void push(struct stack** head, pid_t pid)
  24. {
  25.     struct stack* new = malloc(sizeof(struct stack));
  26.     new->pid =pid; 
  27.     new->next = *head;
  28.     *head = new;
  29. }
  30.  
  31. int empty(struct stack* head)
  32. {
  33.     return head == NULL;
  34. }
  35.  
  36. pid_t pop(struct stack** head)
  37. {
  38.     if (empty(*head))
  39.     {
  40.         return -1;
  41.     }
  42.  
  43.     struct stack* temp = *head;
  44.     *head = temp->next;
  45.     pid_t pid = temp->pid;
  46.     free(temp);
  47.  
  48.     return pid;
  49. }
  50.  
  51. /* reads from keypress, doesn't echo */
  52. int getch(void)
  53. {
  54.     struct termios oldattr, newattr;
  55.     int ch;
  56.     tcgetattr( STDIN_FILENO, &oldattr );
  57.     newattr = oldattr;
  58.     newattr.c_lflag &= ~( ICANON | ECHO );
  59.     tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
  60.     ch = getchar();
  61.     tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
  62.     return ch;
  63. }
  64.  
  65. char** get_cmd_line_args(int child_count)
  66. {
  67.     char** cmd_line = malloc(sizeof(char*) * cmd_line_args_count);
  68.  
  69.     cmd_line[0] = malloc(sizeof(char) * (strlen(exename) + 1));
  70.     strncpy(cmd_line[0], exename, strlen(exename) + 1);
  71.  
  72.     int lenght = snprintf(NULL, 0, "%d", child_count);
  73.     char* child_count_str = malloc(sizeof(char) * (lenght + 1));
  74.     sprintf(child_count_str, "%d", child_count);
  75.  
  76.     cmd_line[1] = malloc(sizeof(char) * (lenght + strlen(pattern) + 1));
  77.     strncpy(cmd_line[1], pattern, strlen(pattern) + 1);
  78.     strncat(cmd_line[1], child_count_str, strlen(child_count_str));
  79.  
  80.     cmd_line[2] = NULL;
  81.  
  82.     return cmd_line;
  83. }
  84.  
  85. void free_cmd_line(char** cmd_line)
  86. {
  87.     for (int i = 0; i < cmd_line_args_count; i++)
  88.     {
  89.         free(cmd_line[i]);
  90.     }
  91.  
  92.     free(cmd_line);
  93.     cmd_line = NULL;
  94. }
  95.  
  96. pid_t create_process(char** args)
  97. {
  98.     pid_t pid = fork();
  99.  
  100.     if (pid == 0)
  101.     {
  102.         int result = execvp(exename, args);
  103.         if (result == -1)
  104.         {
  105.             fprintf(stderr, "Can't replace a current process\n");
  106.             exit(EXIT_FAILURE);
  107.         }
  108.     }
  109.     else
  110.     {
  111.         if (pid == -1)
  112.         {
  113.             fprintf(stderr, "Can't create a child process\n");
  114.             exit(EXIT_FAILURE);
  115.         }
  116.     }
  117.  
  118.     return pid;
  119. }
  120.  
  121. int main()
  122. {
  123.     char** args = NULL;
  124.     struct stack* head = NULL;
  125.     pid_t pid;
  126.     int child_count = 0;
  127.  
  128.     sem_t* sem = sem_open("semaphore", O_CREAT, S_IRWXO | S_IRWXU, 1);
  129.     if (sem == SEM_FAILED)
  130.     {
  131.         fprintf(stderr, "Can't create a semaphore\n");
  132.         exit(EXIT_FAILURE);
  133.     }
  134.  
  135.     char c;
  136.     while ((c = getch()) != 'q')
  137.     {
  138.         switch (c)
  139.         {
  140.             case '+':
  141.                 args = get_cmd_line_args(child_count++);
  142.                 if ((pid = create_process(args)) != -1)
  143.                 {
  144.                     push(&head, pid);              
  145.                 }
  146.                 free_cmd_line(args);
  147.                 break;
  148.             case '-':
  149.                 if ((pid = pop(&head)) != -1)
  150.                 {
  151.                     child_count--;
  152.                     kill(pid, SIGTERM);
  153.                 }
  154.                 break;
  155.             default:
  156.                 break;
  157.         }
  158.     }
  159.  
  160.     while ((pid = pop(&head)) != -1)
  161.     {
  162.         kill(pid, SIGTERM);
  163.     }
  164.  
  165.     sem_close(sem);
  166.     sem_unlink("semaphore");
  167.  
  168.     exit(EXIT_SUCCESS);
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement