int executer(char *line) { /* Insert your code to execute the command line * identically to the standard execution scheme: * parsecmd, then fork+execvp, for a single command. * pipe and i/o redirection are not required. */ //printf("Not implemented: can not execute %s\n", line); struct cmdline *l; l = parsecmd( & line); if (l->err) { /* Syntax error, read another command */ printf("error: %s\n", l->err); return 1; } pid_t process = create_processes(l->seq, l->in, l->out, l->bg); if(!l->bg){ while(1){ waitpid(process, NULL, 0); if(waitpid(process, NULL, 0) == -1){ break; } } //waitpid(process, NULL, 0); } /* Remove this line when using parsecmd as it will free it */ //free(line); return 0; }
int main(int argc, char *argv[]) { char *filename = NULL, *pattern = NULL; int lines = 0,n_Proc; parse_argv(argc, argv, &filename, &pattern, &lines,&n_Proc); install_signal_handler(); init_process_table(&n_Proc,lines); create_processes(lines, n_Proc, filename, pattern); wait_processes(); printf("\n[MANAGER] Program termination (all the processes terminated).\n"); free_resources(); return EXIT_SUCCESS; }
int main(int argc, char* argv[], char* envp[]) { char buffer[128]; while(1) { char commands[CMD_NUM][CMD_SIZE]; printf("%c ", '%'); fflush(stdout); if(fgets(buffer, sizeof(buffer), stdin) == NULL || !(strcmp(buffer, "quit\n"))) break; buffer[strcspn(buffer, "\n")] = 0; create_processes(buffer, commands, envp); } return 0; }
/* * Create processes tree using fork. * * Argument Description * --------------------------------------------------------------------------- * remaining_levels number of sublevels in the tree under the process * currently creating create_process. When =0, the * function immediately return (recursive call stop cond.) * created_children array in which store created children pids, in order * to permit further automated tests * creator_idx index of calling process in the local tree hierarchy * => tree is stored in a heap-fashion in a linear array */ int create_processes(int remaining_levels, pid_t* created_children, int creator_idx) { // local variables pid_t pid = 1; int i = 0; int res = 0; int created_idx; // if remaining_levels is 0, stop forking if (remaining_levels <= 0) { return -1; } // loop for creating the subprocesses for (i = 0; i<NB_DIRECT_CHILDS_PER_PROCESS; i++) { pid = fork(); created_idx = NB_DIRECT_CHILDS_PER_PROCESS*creator_idx + i + 1; if (pid > 0) { created_children[created_idx-1] = pid; } else if (pid == 0) { return(create_processes(remaining_levels-1, created_children, created_idx)); } } if (remaining_levels < NB_LEVELS) { return -1; } else { return 0; } }
/* * Main testing function. */ int main(void) { // declare local variables size_t num_children_expected = compute_num_children_expected(); size_t num_children_obtained; pid_t* pid_list_expected; pid_t* pid_list_obtained = (pid_t*)malloc(num_children_expected * sizeof(pid_t)); long res; int i; int j; int is_found; int shared_mem_identifier; // initialize shared memory, allowing processes to communicate in order to automatize test printf("initializing shared memory... "); shared_mem_identifier = shmget(IPC_PRIVATE, num_children_expected * sizeof(pid_t), IPC_CREAT | 0666); if (shared_mem_identifier < 0) { printf(" ERROR\nQuitting NOW !\n"); exit(-1); } else { pid_list_expected = shmat(shared_mem_identifier, (void*)0, 0); if (pid_list_expected == (pid_t*)(-1)) { printf(" ERROR\nQuitting NOW !\n"); exit(-1); } else { printf(" OK !\n"); } } // create processes printf("creating processes... "); fflush(stdout); if (create_processes(NB_LEVELS, pid_list_expected, 0) == 0) { // Only the main thread will execute the following of the program, all children threads // returns from create_process with a value != 0 usleep(1000000); printf("OK !\n"); // Print details printf("----------------------------------------\n"); printf("| PROCESS TREE |\n"); printf("----------------------------------------\n"); printf(" > Here is the generated subprocesses tree, as computed during forks.\n"); printf(" > root (main)\n"); print_real_tree(pid_list_expected, num_children_expected, 0, 1); // Gather the list from syscall printf("\n----------------------------------------\n"); printf("| EXECUTE SYSCALL |\n"); printf("----------------------------------------\n"); printf("making the syscall to obtain the list...\n"); res = get_child_pids(pid_list_obtained, num_children_expected, &num_children_obtained); printf("list is ready !\n\n"); // Print details printf("\n----------------------------------------\n"); printf("| RESULTS |\n"); printf("----------------------------------------\n"); // Check return status of the syscall switch (res) { case 0: printf(" [ OK ] syscall returned 0\n"); break; case -ENOBUFS: printf(" [ WARN ] syscall returned -ENOBUFS\n"); break; case -EFAULT: printf(" [ ERR ] syscall returned -EFAULT\n"); printf("=> EXITING NOW !\n"); exit(-1); default: printf(" [ ERR ] syscall returned an unexpected value (%d)\n", res); printf("=> EXITING NOW !\n"); exit(-1); } // Check correspondance between expectation and reality for num_children if (num_children_obtained == num_children_expected) { printf(" [ OK ] %d threads were created, got %d as num_children\n", num_children_expected, num_children_obtained); } else if (num_children_obtained < num_children_expected) { printf(" [ ERR ] %d threads were created, only %d were retrieved\n", num_children_expected, num_children_obtained); printf("=> EXITING NOW !\n"); exit(-1); } else // (num_children_obtained > num_children_expected) { printf(" [ ERR ] %d threads were created, but %d were retrieved\n", num_children_expected, num_children_obtained); printf("=> EXITING NOW !\n"); exit(-1); } // Check correspondance between lists of process ids printf(" ======== list of children PIDs retrieved :\n"); for (i=0; i<num_children_obtained; i++) { is_found = 0; for (j=0; j<num_children_expected && is_found==0; j++) { if (pid_list_obtained[i] == pid_list_expected[j]) { printf(" [ OK ] process with PID %d has been found by syscall\n", pid_list_obtained[i]); is_found = 1; pid_list_expected[j] = 0; } } if (is_found == 0) { printf(" [ ERR ] process with PID %d has been found by syscall but is not a child of current process\n", pid_list_obtained[i]); printf("=> EXITING NOW !\n"); exit(-1); } } printf(" ======== end of list.\n"); for (i=0; i<num_children_expected; i++) { if (pid_list_expected[i] != 0) { printf(" [ ERR ] process with PID %d is a child of current process but was not found by syscall\n", pid_list_expected[i]); printf("=> EXITING NOW !\n"); exit(-1); } } printf(" [ OK ] EVERYTHING IS OK, TEST SUCCESSFULLY COMPLETED !\n\n"); // destroy shared memory printf("destroying shared memory... "); if (shmdt(pid_list_expected) == -1) { printf(" ERROR\nNow quitting, be aware that the shared memory space is still existing in RAM !\n"); exit(-1); } else { shmctl(shared_mem_identifier, IPC_RMID, NULL); printf(" OK !\n"); } // exiting free(pid_list_obtained); exit(0); } else { // Wait executed by children threads, in order to maintain them alive // during the test is performed by main thread usleep(5000000); } }
/*----------------------------------------------------------------------------- * FUNCTION: main * * DATE: January 25, 2010 * * REVISIONS: * * DESIGNER: Steffen L. Norgren <*****@*****.**> * * PROGRAMMER: Steffen L. Norgren <*****@*****.**> * * INTERFACE: int main(int argc, char **argv) * argc - argument count * argv - array of arguments * * RETURNS: Result on success or failure. * * NOTES: Main entry point into the application. Parses command line options * and sets up conditions to create new child processes. * *----------------------------------------------------------------------------*/ int main (int argc, char **argv) { PRIME_OPTIONS *opts; int c, option_index = 0; static struct option long_options[] = { {"processes" , required_argument , 0, 'p'}, {"output" , required_argument , 0, 'o'}, {"start" , required_argument , 0, 's'}, {"block" , required_argument , 0, 'b'}, {"help" , no_argument , 0, 'h'}, {0, 0, 0, 0} }; opts = malloc(sizeof(PRIME_OPTIONS)); /* Set Defaults */ opts->output = _OPTS_OUTPUT; opts->processes = _OPTS_PROCESSES; opts->start = _OPTS_START; opts->block = _OPTS_BLOCK; while (1) { c = getopt_long(argc, argv, "p:o:s:b:h", long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* If the option set a flag, do nothing */ if (long_options[option_index].flag != 0) break; break; case 'p': if (atoi(optarg) > 0) opts->processes = atoi(optarg); break; case 'o': opts->output = optarg; break; case 's': if (atoi(optarg) > 0) opts->start = atoi(optarg); break; case 'b': if (atoi(optarg) > 0) opts->block = atoi(optarg); break; case 'h': print_usage(argv[0], _OPTS_HELP); break; default: print_usage(argv[0], _OPTS_ERROR); break; } } /* Print current settings */ print_settings(argc, opts); /* Start the child processes */ create_processes(opts); /* Start reading from the pipe and writing to the file */ printf("Parent pid %d writing output to file %s\n", getpid(), opts->output); write_from_pipe(opts); printf("Parent pid %d finished writing to file %s\n", getpid(), opts->output); free(opts); exit(_PARENT_EXIT); }