diff options
author | scratko <m@scratko.xyz> | 2024-05-24 01:37:07 +0300 |
---|---|---|
committer | scratko <m@scratko.xyz> | 2024-05-24 01:37:07 +0300 |
commit | 23df85221e08fe5dc1f0eb6df3c48f299f243895 (patch) | |
tree | 8e4ca27a52392cc010d1de4ccc789fcbe31d0dc5 /parallel_progs_by_args.c | |
download | parallel-progs-by-args-23df85221e08fe5dc1f0eb6df3c48f299f243895.tar.gz parallel-progs-by-args-23df85221e08fe5dc1f0eb6df3c48f299f243895.tar.bz2 parallel-progs-by-args-23df85221e08fe5dc1f0eb6df3c48f299f243895.zip |
Initial commit
Diffstat (limited to 'parallel_progs_by_args.c')
-rw-r--r-- | parallel_progs_by_args.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/parallel_progs_by_args.c b/parallel_progs_by_args.c new file mode 100644 index 0000000..97505ab --- /dev/null +++ b/parallel_progs_by_args.c @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> +#include <string.h> + +struct item { + char *prog_name; + int pid; + struct item *next; +}; + +static int check_delimiter(char *arg) +{ + return !strncmp(arg, ";;", 3); +} + +static void fill_in_item(char *arg, int pid, struct item **list) +{ + struct item *tmp_item = malloc(sizeof(struct item)); + tmp_item->pid = pid; + tmp_item->prog_name = arg; + tmp_item->next = *list; + *list = tmp_item; +} + +static void make_new_fork(char **begin_pos, struct item **list, + int *process_counter) +{ + int pid = fork(); + if(pid == -1) { + perror("fork error"); + exit(1); + } + if(pid) { + fill_in_item(*begin_pos, pid, list); + ++*process_counter; + } + else { + execvp(*begin_pos, begin_pos); + perror(*begin_pos); + exit(1); + } +} + +static char* find_name_by_pid(int pid, struct item *list) +{ + while(list) { + if(list->pid == pid) + return list->prog_name; + list = list->next; + } + return NULL; +} + +static void clear_list(struct item *list) +{ + struct item *tmp; + while(list) { + tmp = list; + list = list->next; + free(tmp); + } +} + +int main(int argc, char **argv) +{ + int status, pid, process_counter; + struct item *list = NULL; + process_counter = 0; + char **begin_pos, **end_pos; + if(argc == 1) { + fprintf(stderr, "too few arguments\n"); + return 1; + } + ++argv; + for(begin_pos = argv, end_pos = begin_pos + 1; *end_pos != NULL; ) { + if(check_delimiter(*end_pos)) { + *end_pos = NULL; + make_new_fork(begin_pos, &list, &process_counter); + begin_pos = end_pos + 1; + end_pos = begin_pos + 1; + } else + ++end_pos; + } + make_new_fork(begin_pos, &list, &process_counter); + for( ; process_counter; --process_counter) { + pid = wait(&status); + if(WIFEXITED(status) && WEXITSTATUS(status) == 0) + printf("%s\n", find_name_by_pid(pid, list)); + } + clear_list(list); + return 0; +} |