back to scratko.xyz
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parallel_progs_by_args.c94
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;
+}