bool Action::run_one( GAsyncQueue * queue , gulong wait_ms ) { g_assert( queue ); g_async_queue_ref( queue ); Action * action = 0; if ( wait_ms == 0 ) { action = ( Action * ) g_async_queue_try_pop( queue ); } else { action = ( Action * ) Util::g_async_queue_timeout_pop( queue , wait_ms * 1000 ); } g_async_queue_unref( queue ); if ( action ) { run_internal( action ); delete action; return true; } return false; }
int Action::run_all( GAsyncQueue * queue ) { g_assert( queue ); int result = 0; g_async_queue_ref( queue ); while ( Action * action = ( Action * ) g_async_queue_try_pop( queue ) ) { run_internal( action ); delete action; ++result; } g_async_queue_unref( queue ); return result; }
/*! run this task */ __dllexport void TaskScheduler::Task::run (Thread& thread) { run_internal(thread); }
void idn_testsuite_run(idn_testsuite_t ctx, char *titles[]) { assert(ctx != NULL && titles != NULL); run_internal(ctx, titles); }
void idn_testsuite_runall(idn_testsuite_t ctx) { assert(ctx != NULL); run_internal(ctx, NULL); }
int main(int argc, char *argv[], char *envp[]) { init_arg(argc, argv); char Line[BUF_LEN]; signal_set(); while (1) { if (input(Line) == false) { continue; } if (is_internal(Line)) { run_internal(Line); } else { Process child; if (init_process(Line, &child) == false) { fputs("Can't found init this command!", stderr); continue; } child.pid = fork(); if (child.pid < 0) { perror("fork()"); continue; } if (child.pid) { if (run_mode == IS_DEBUG_MODE) { printf("调试模式:\n新进程PID:%d\n", child.pid); } if (!add_to_PL(&child)) { perror("add_to_PL"); } if (!child.is_daemon) { int status; pid_t pid = wait(&status); del_from_PL(pid); } } //如果该程序后台运行 if ((!child.pid) && child.is_daemon) { pid_t sid = setsid(); if (sid < 0) { perror("setsid"); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } if (!child.pid) { execvp(child.vect[0], child.vect); perror("execvp"); exit(1); } clean_process(&child); } } return 0; }
int main(void) { // Helpful Flags bool IS_NOT_ALONE, IS_ALONE, IS_INTERNAL, IS_EXTERNAL, IS_CD, IS_EXIT; bool IS_PARENT, IS_CHILD, IS_REDIRECTED, IS_FIRST, IS_LAST, IS_MIDDLE; // Pipe Holders int *pipe_left; int *pipe_right; // Holders for dup'd STDIN, OUT in case of redirected internal commands int ORIGINAL_STDIN, ORIGINAL_STDOUT; // Holder for command string from STDIO. char *str; // This gets the current username char *login; login = getlogin(); // This is the current working directory // This will be updated on cd commands run internally char cwd[MAXPATH]; getcwd(cwd, MAXPATH); // pointer to pid holder for children and waiting pid_t child_pid; // for execution & internal/external checking char *command_name; size_t command_length; // parsed command holder + pointer for counting number of commands command *comms = NULL; command *command_walker; char prompt[80]; // for loop iteration variable int i; // This will never be freed until we exit (and then by default). pipe_left = malloc(2*sizeof(int)); pipe_right = malloc(2*sizeof(int)); if ((pipe_left == NULL) || (pipe_right == NULL)) { fprintf(stderr, "%s: Could not allocate holder for potential pipes. Exiting.\n", SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } /** * Curiosity Shell Control Flow * The structure of the program is broken up as follows: * Pipe Creation * Fork Handler * Pipe Cleanup * Redirection (Including for Parent Internal Commands) * Command Run (Child, Parent), Parent Wait (if appropriate) * Reset Temporary Parent Redirection for Internal Commands * Get Next User Input */ while(1){ // Free the previous command free_commands(comms); // Display prompt. sprintf(prompt, "%s:%s> ", login, cwd); str = readline(prompt); if (str == NULL) { exit(EXIT_SUCCESS); } // Save the history. if (str && *str) add_history (str); // Prepare to tokenize command_length = strlen((const char *) str); if (command_length == 0) { comms = NULL; continue; } // Tokenize & parse into discrete commands comms = get_commands(str); if (str != NULL) free(str); // If no commands, create another prompt in the next iteration if (comms == NULL) { continue; } // count number of commands, command_length command_length = 0; command_walker = comms; while (command_walker->argv != NULL) { command_length += 1; command_walker += 1; } // Set IS_ALONE, IS_NOT_ALONE Flags IS_ALONE = false; IS_NOT_ALONE = false; if (command_length == 1) IS_ALONE = true; if (command_length > 1) IS_NOT_ALONE = true; /* Handle Latest Set of Commands */ for (i = 0; i < command_length; i++) { /* Set Flags for THIS command IS_FIRST, IS_MIDDLE, IS_LAST, IS_INTERNAL, IS_EXTERNAL, IS_CD, IS_EXIT */ command_name = comms[i].argv[0]; IS_FIRST = false; IS_MIDDLE = false; IS_LAST = false; if (i == 0) { IS_FIRST = true; } if (i == (command_length-1)) { IS_LAST = true; } if ((!IS_FIRST) && (!IS_LAST)) { IS_MIDDLE = true; } IS_INTERNAL = false; IS_EXTERNAL = true; IS_CD = false; IS_EXIT = false; if (strcmp((const char *)command_name, (const char *) "cd") == 0) { IS_CD = true; } if (strcmp((const char *)command_name, (const char *) "exit") == 0) { IS_EXIT = true; } if (IS_CD || IS_EXIT) { IS_INTERNAL = true; } if (IS_INTERNAL) { IS_EXTERNAL = false; } /* Pipe & Fork Handler (fork_yourself), Set IS_PARENT, IS_CHILD in fork_yourself, and use its return value to determine error */ if (IS_FIRST && IS_ALONE) { // No piping // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // No pipe handling } else if (IS_FIRST && IS_NOT_ALONE) { // pipe to pipe_right, check for pipe errors & return to prompt // if errors found. if (!pipe_creation_handler(&pipe_left, &pipe_right, 1)) { fprintf(stderr, "%s: Right-pipe creation error for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closes pipe_right_write // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_right[1]); } // child closes pipe_right_read // child duplicates pipe_right_write to stdout, then closes it. // errors reported by close are inconsequential if (IS_CHILD) { close(pipe_right[0]); if (dup2(pipe_right[1], STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_right[1]); } } else if (IS_LAST && IS_NOT_ALONE) { // swap pipe_left/pipe_right // no piping pipe_creation_handler(&pipe_left, &pipe_right, 0); // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closees pipe_left_read // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_left[0]); } // child duplicates pipe_left_read to its stdin, then closes it // errors reported by close are inconsequential if (IS_CHILD) { if (dup2(pipe_left[0], STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_left[0]); } } else if (IS_MIDDLE && IS_NOT_ALONE) { // swap pipe_left/pipe_right pipe_creation_handler(&pipe_left, &pipe_right, 0); // pipe to pipe_right, check for pipe errors & return to prompt if // errors found. if (!pipe_creation_handler(&pipe_left, &pipe_right, 1)) { fprintf(stderr, "%s: Right-pipe creation error for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closes pipe_left_read and pipe_right_write // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_left[0]); close(pipe_right[1]); } // child closes pipe_right_read, duplicates pipe_left_read to stdin, // pipe_right_write to stdout, then closes both. // errors reported by close are inconsequential if (IS_CHILD) { close(pipe_right[0]); if (dup2(pipe_left[0], STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } if (dup2(pipe_right[1], STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_left[0]); close(pipe_right[1]); } } else { // Unknown case. fprintf(stderr, "%s: Unexpected pipe handling case for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } /* Redirection Handler Set IS_REDIRECTED flag Save STDIN/STDOUT/STDERR for later restoration This implementation possibly racks up "erroneous file handlers" unless dup() removes those on error. */ IS_REDIRECTED = false; if (IS_PARENT && IS_INTERNAL) { if (comms[i].ifile != NULL) { IS_REDIRECTED = true; ORIGINAL_STDIN = dup(STDIN_FILENO); if (ORIGINAL_STDIN == -1) { perror(SHELL_ERROR_IDENTIFIER); break; } } if (comms[i].ofile != NULL) { IS_REDIRECTED = true; ORIGINAL_STDOUT = dup(STDOUT_FILENO); if (ORIGINAL_STDOUT == -1) { perror(SHELL_ERROR_IDENTIFIER); break; } } // Not necessary as we do not handle STDERR redirection // ORIGINAL_STDERR = dup(STDERR_FILENO); // if (ORIGINAL_STDERR == -1) { // perror(SHELL_ERROR_IDENTIFIER); // break; // } if (!redirection(comms[i].ifile, comms[i].ofile, comms[i].append)) { break; } } else if (IS_CHILD) { IS_REDIRECTED = true; if (!redirection(comms[i].ifile, comms[i].ofile, comms[i].append)) { break; } } /* Run/Wait Handler */ if(IS_CHILD && IS_INTERNAL){ if(!run_internal(IS_CD, IS_EXIT, cwd, comms[i].argv, comms[i].argc)){ exit(EXIT_FAILURE); } else{ exit(EXIT_SUCCESS); } } if(IS_CHILD && IS_EXTERNAL){ execute(comms[i].argv); } if(IS_PARENT && IS_INTERNAL && IS_ALONE){ run_internal(IS_CD, IS_EXIT, cwd, comms[i].argv, comms[i].argc); } if(IS_PARENT && IS_INTERNAL && IS_NOT_ALONE){ if(!(waiting(child_pid))){ break; } } if(IS_PARENT && IS_EXTERNAL){ if(!(waiting(child_pid))){ break; } } /* Parent STDIO Reset In case of Single Internal Command with Redirection */ /* On failure, MUST EXIT as user can no longer target STDIN or see our STDOUT, possibly. */ if (IS_PARENT && IS_INTERNAL && IS_ALONE && IS_REDIRECTED) { if (comms[i].ifile != NULL) { if (dup2(ORIGINAL_STDIN, STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(ORIGINAL_STDIN); } if (comms[i].ofile != NULL) { if (dup2(ORIGINAL_STDOUT, STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(ORIGINAL_STDOUT); } // Do not need to handle STDERR, we do not support it's redirection } } } exit(EXIT_SUCCESS); }