Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <sys/types.h>
- #include <termios.h>
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- const char* exename = "/home/zakhar/Documents/C/Signals/Receiver";
- const char* pattern = "Process";
- const int cmd_line_args_count = 3;
- struct stack
- {
- pid_t pid;
- struct stack* next;
- };
- void push(struct stack** head, pid_t pid)
- {
- struct stack* new = malloc(sizeof(struct stack));
- new->pid =pid;
- new->next = *head;
- *head = new;
- }
- int empty(struct stack* head)
- {
- return head == NULL;
- }
- pid_t pop(struct stack** head)
- {
- if (empty(*head))
- {
- return -1;
- }
- struct stack* temp = *head;
- *head = temp->next;
- pid_t pid = temp->pid;
- free(temp);
- return pid;
- }
- /* reads from keypress, doesn't echo */
- int getch(void)
- {
- struct termios oldattr, newattr;
- int ch;
- tcgetattr( STDIN_FILENO, &oldattr );
- newattr = oldattr;
- newattr.c_lflag &= ~( ICANON | ECHO );
- tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
- ch = getchar();
- tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
- return ch;
- }
- char** get_cmd_line_args(int child_count)
- {
- char** cmd_line = malloc(sizeof(char*) * cmd_line_args_count);
- cmd_line[0] = malloc(sizeof(char) * (strlen(exename) + 1));
- strncpy(cmd_line[0], exename, strlen(exename) + 1);
- int lenght = snprintf(NULL, 0, "%d", child_count);
- char* child_count_str = malloc(sizeof(char) * (lenght + 1));
- sprintf(child_count_str, "%d", child_count);
- cmd_line[1] = malloc(sizeof(char) * (lenght + strlen(pattern) + 1));
- strncpy(cmd_line[1], pattern, strlen(pattern) + 1);
- strncat(cmd_line[1], child_count_str, strlen(child_count_str));
- cmd_line[2] = NULL;
- return cmd_line;
- }
- void free_cmd_line(char** cmd_line)
- {
- for (int i = 0; i < cmd_line_args_count; i++)
- {
- free(cmd_line[i]);
- }
- free(cmd_line);
- cmd_line = NULL;
- }
- pid_t create_process(char** args)
- {
- pid_t pid = fork();
- if (pid == 0)
- {
- int result = execvp(exename, args);
- if (result == -1)
- {
- fprintf(stderr, "Can't replace a current process\n");
- exit(EXIT_FAILURE);
- }
- }
- else
- {
- if (pid == -1)
- {
- fprintf(stderr, "Can't create a child process\n");
- exit(EXIT_FAILURE);
- }
- }
- return pid;
- }
- int main()
- {
- char** args = NULL;
- struct stack* head = NULL;
- pid_t pid;
- int child_count = 0;
- sem_t* sem = sem_open("semaphore", O_CREAT, S_IRWXO | S_IRWXU, 1);
- if (sem == SEM_FAILED)
- {
- fprintf(stderr, "Can't create a semaphore\n");
- exit(EXIT_FAILURE);
- }
- char c;
- while ((c = getch()) != 'q')
- {
- switch (c)
- {
- case '+':
- args = get_cmd_line_args(child_count++);
- if ((pid = create_process(args)) != -1)
- {
- push(&head, pid);
- }
- free_cmd_line(args);
- break;
- case '-':
- if ((pid = pop(&head)) != -1)
- {
- child_count--;
- kill(pid, SIGTERM);
- }
- break;
- default:
- break;
- }
- }
- while ((pid = pop(&head)) != -1)
- {
- kill(pid, SIGTERM);
- }
- sem_close(sem);
- sem_unlink("semaphore");
- exit(EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement