/// Call fork() as part of executing a process \p p in a job \j. Execute \p child_action in the /// context of the child. Returns true if fork succeeded, false if fork failed. static bool fork_child_for_process(job_t *j, process_t *p, const io_chain_t &io_chain, bool drain_threads, const char *fork_type, const std::function<void()> &child_action) { pid_t pid = execute_fork(drain_threads); if (pid == 0) { // This is the child process. Setup redirections, print correct output to // stdout and stderr, and then exit. p->pid = getpid(); child_set_group(j, p); setup_child_process(p, io_chain); child_action(); DIE("Child process returned control to fork_child lambda!"); } if (pid < 0) { debug(1, L"Failed to fork %s!\n", fork_type); job_mark_process_as_failed(j, p); return false; } // This is the parent process. Store away information on the child, and // possibly give it control over the terminal. debug(4, L"Fork #%d, pid %d: %s for '%ls'", g_fork_count, pid, fork_type, p->argv0()); p->pid = pid; on_process_created(j, p->pid); set_child_group(j, p->pid); maybe_assign_terminal(j); return true; }
bool SimpleContainer<ChannelType>::tick( void ) { execute_fork(); if ( wakeups.empty() ) { return false; } Event next_event = wakeups.top(); wakeups.pop(); assert( next_event.time >= the_time ); the_time = next_event.time; assert( next_event.addr == 0 ); channel.wakeup(); return true; }
/** * Main function * */ int main(int argc, char* argv[]) { int i, j, cmdargv_len; int rc = 0; int pipeExists = 0; char *formattedInput = NULL; char *userInput = NULL; char **cmdargv = NULL ; char *cdCmd = NULL; char *pipeCmd = NULL; if((userInput = malloc(sizeof(char)*MAX_CMD_LEN)) == NULL) ERROR("Failed malloc\n"); cmdargv_len = sizeof(char*) * MAX_CMD_ARGS; if((cmdargv = (char**) malloc(cmdargv_len)) == NULL) { ERROR("Failed malloc\n"); } else { memset(cmdargv, '\0', sizeof(char*) * MAX_CMD_ARGS); } registerSignalHandler(); while(1) { printf("_dash > "); got_sigint = false; if (fgets(userInput, MAX_CMD_LEN, stdin) == NULL) { if (got_sigint) { printf("\n"); continue; } else { // Ctrl+D return 0; } } // TODO: Sanitize user input! We're currently hoping the user is a // benelovent, sweet human being. HA! if( (formattedInput = malloc(sizeof(userInput))) == NULL ) ERROR("Failed malloc\n"); removeNewLine(userInput, formattedInput); // See if user wants out. if((strcmp("quit", formattedInput) == 0) || (strcmp("exit", formattedInput) == 0) || (strcmp("q", formattedInput) == 0)) { printf("Quitting!\n"); goto cleanup; } // Check to see if user wants to change working directories if( (cdCmd = strstr(formattedInput, "cd ")) != NULL ) { if(changeDir(cdCmd) != 0) ERROR("cd failed."); free(cdCmd); // No need to fork/exec, can just move on. continue; } // Check to see if user wants to pipe commands if( (pipeCmd = strstr(formattedInput, "|")) != NULL ) { pipeExists = 1; // Don't need to free pipeCmd bc freeing formattedInput will take // care of that for us. //free(pipeCmd); } parseUserInput(formattedInput, cmdargv); for(j=0; cmdargv[j] != NULL; j++) printf("%d: cmdargv[%d]: %s\n", __LINE__, j, cmdargv[j]); rc = execute_fork(cmdargv, pipeExists); ASSERT( rc != 0 ); pipeExists = 0; } /* Cleanup! */ cleanup: free(formattedInput); free(userInput); if (cmdargv) { for (i = 0; i < MAX_CMD_ARGS; i++) { free(cmdargv[i]); /* free(NULL) is ok with glibc */ } } free(cmdargv); printf("All finished.\n"); return 0; }