static int handle_exec(struct task *task) { debug(DEBUG_EVENT, "+++ process pid=%d exec", task->pid); if (unlikely(options.verbose)) fprintf(stderr, "+++ process pid=%d exec\n", task->pid); if (!options.follow_exec) goto nofollow; if (process_exec(task) < 0) { fprintf(stderr, "couldn't reinitialize process %d after exec\n", task->pid); goto untrace; } return continue_task(task, 0); nofollow: report_nofollow(task); untrace: untrace_proc(task); return RET_DELETED; }
struct service_process *service_process_create(struct service *service) { static unsigned int uid_counter = 0; struct service_process *process; unsigned int uid = ++uid_counter; const char *hostdomain; pid_t pid; bool process_forked; i_assert(service->status_fd[0] != -1); if (service->to_throttle != NULL) { /* throttling service, don't create new processes */ return NULL; } if (service->list->destroying) { /* these services are being destroyed, no point in creating new processes now */ return NULL; } /* look this up before fork()ing so that it gets cached for all the future lookups. */ hostdomain = my_hostdomain(); if (service->type == SERVICE_TYPE_ANVIL && service_anvil_global->pid != 0) { pid = service_anvil_global->pid; uid = service_anvil_global->uid; process_forked = FALSE; } else { pid = fork(); process_forked = TRUE; service->list->fork_counter++; } if (pid < 0) { service_error(service, "fork() failed: %m"); return NULL; } if (pid == 0) { /* child */ service_process_setup_environment(service, uid, hostdomain); service_reopen_inet_listeners(service); service_dup_fds(service); drop_privileges(service); process_exec(service->executable, NULL); } i_assert(hash_table_lookup(service_pids, POINTER_CAST(pid)) == NULL); process = i_new(struct service_process, 1); process->service = service; process->refcount = 1; process->pid = pid; process->uid = uid; if (process_forked) { process->to_status = timeout_add(SERVICE_FIRST_STATUS_TIMEOUT_SECS * 1000, service_process_status_timeout, process); } process->available_count = service->client_limit; service->process_count++; service->process_avail++; DLLIST_PREPEND(&service->processes, process); service_list_ref(service->list); hash_table_insert(service_pids, POINTER_CAST(process->pid), process); if (service->type == SERVICE_TYPE_ANVIL && process_forked) service_anvil_process_created(process); return process; }
/** Runs it all */ void scheduler( ) { u16 temp_proc; // While we have stuff on the queues or list while ( blocked_list || high_head || med_head || low_head ) { if ( blocked_list && !high_head && !med_head && !low_head ) { printf("******************\n"); printf("CURRENT_TIME:\t%llu\n", get_time()); printf("SET_TIME TO: mem[blocked_list]._proc._time:\t%llu\n", mem[blocked_list]._proc._time); printf("******************\n"); set_time( mem[blocked_list]._proc._time ); printf("before deq\n"); printf("mem[blocked_list]._proc._arrid:\t%i\n", mem[blocked_list]._proc._arrid); printf("mem[mem[blocked_list]._proc._next]._proc._arrid:\t%i\n", mem[mem[blocked_list]._proc._next]._proc._arrid); printf("mem[mem[mem[blocked_list]._proc._next]._proc._next]._proc._arrid:\t%i\n", mem[mem[mem[blocked_list]._proc._next]._proc._next]._proc._arrid); printf("get_time():\t%llu\n", get_time()); blocked_deq( ); printf("after deq\n"); } // High priority u8 count = 0; while ( high_head && count < 4 ) { printf("RUNNING HIGH\n"); temp_proc = ready_deq( 1 ); printf("mem[temp_proc]._proc._next:\t%llu\n", mem[temp_proc]._proc._next); if ( mem[temp_proc]._proc._next ) { int x = 1 / 0; } printf("starting execute process with: %i\n", temp_proc); process_exec( temp_proc, get_time( ) + 2500 ); printf("starting blocked in high\n"); blocked_deq( ); printf("done with blocked in high\n"); count++; } // Med priority count = 0; while ( med_head && count < 2 ) { printf("RUNNING MED\n"); temp_proc = ready_deq( 2 ); process_exec( temp_proc, get_time( ) + 2500 ); blocked_deq( ); count++; } // Low priority count = 0; while ( low_head && count < 1 ) { printf("RUNNING LOW\n"); temp_proc = ready_deq( 3 ); process_exec( temp_proc, get_time( ) + 2500 ); blocked_deq( ); count++; } // Try to make other processes with currents u16 result = 1; while ( result && PROC_POINT < MAX_PROCS ) { printf("IN WHILE - get_time():\t%llu\n", get_time()); printf("proc_init[PROC_POINT]._start_time:\t%llu\n", proc_init[PROC_POINT]._start_time); result = new_proc( proc_init[PROC_POINT]._start_time, proc_init[PROC_POINT]._run_time, proc_init[PROC_POINT]._code_size, proc_init[PROC_POINT]._data_size, proc_init[PROC_POINT]._priority ); printf("result:\t%llu\n", result); //printf("get_time():\t%llu\n", get_time()); //printf("proc_init[PROC_POINT]._start_time:\t%llu\n\n\n", proc_init[PROC_POINT]._start_time); // Proc is ready to start, we got something back, put it on the queue if ( result ) { printf("----------------------------------------------\n"); printf("WHILE - New Process Index #:\t%i\n", PROC_POINT); printf("proc_init[PROC_POINT]._start_time:\t%llu\n", proc_init[PROC_POINT]._start_time); printf("----------------------------------------------\n"); PROC_POINT++; ready_enq( result ); } } // Nothing on queues and list but we haven't ran all the processes if ( PROC_POINT < MAX_PROCS && !blocked_list && !high_head && !med_head && !low_head ) { printf("----------------------------------------------\n"); printf("CURRENT TIME BEFORE SET:\t%llu\n", get_time()); set_time( proc_init[PROC_POINT]._start_time ); temp_proc = new_proc( proc_init[PROC_POINT]._start_time, proc_init[PROC_POINT]._run_time, proc_init[PROC_POINT]._code_size, proc_init[PROC_POINT]._data_size, proc_init[PROC_POINT]._priority ); printf("IF - New Process Index #:\t%i\n", PROC_POINT); printf("NEW PROCESSES START TIME:\t%llu\n", proc_init[PROC_POINT]._start_time); printf("CURRENT TIME AFTER SET:\t\t%llu\n", get_time()); printf("----------------------------------------------\n\n\n"); PROC_POINT++; printf("high_head:\t%i\n", high_head); printf("med_head:\t%i\n", med_head); printf("low_head:\t%i\n", low_head); printf("mem[high_head]._proc._next:\t%i\n", mem[high_head]._proc._next); printf("mem[med_head]._proc._next:\t%i\n", mem[med_head]._proc._next); printf("mem[low_head]._proc._next:\t%i\n", mem[low_head]._proc._next); ready_enq( temp_proc ); printf("high_head:\t%i\n", high_head); printf("med_head:\t%i\n", med_head); printf("low_head:\t%i\n", low_head); printf("mem[high_head]._proc._next:\t%i\n", mem[high_head]._proc._next); printf("mem[med_head]._proc._next:\t%i\n", mem[med_head]._proc._next); printf("mem[low_head]._proc._next:\t%i\n", mem[low_head]._proc._next); } } printf("FINISHED EXECUTING\n"); }
static void handle_exec(const char *args, GHashTable *optlist, WI_ITEM_REC *item) { PROCESS_REC *rec; char *target, *level; int notice, signum, interactive, target_nick, target_channel; /* check that there's no unknown options. we allowed them because signals can be used as options, but there should be only one unknown option: the signal name/number. */ signum = cmd_options_get_signal("exec", optlist); if (signum == -2) return; if (*args == '\0') { exec_show_list(); return; } target = NULL; notice = FALSE; if (g_hash_table_lookup(optlist, "in") != NULL) { rec = process_find(g_hash_table_lookup(optlist, "in"), TRUE); if (rec != NULL) { net_sendbuffer_send(rec->out, args, strlen(args)); net_sendbuffer_send(rec->out, "\n", 1); } return; } /* check if args is a process ID or name. if it's ID but not found, complain about it and fail immediately */ rec = process_find(args, *args == '%'); if (*args == '%' && rec == NULL) return; /* common options */ target_channel = target_nick = FALSE; if (g_hash_table_lookup(optlist, "out") != NULL) { /* redirect output to active channel/query */ if (item == NULL) cmd_return_error(CMDERR_NOT_JOINED); target = (char *) window_item_get_target(item); target_channel = IS_CHANNEL(item); target_nick = IS_QUERY(item); } else if (g_hash_table_lookup(optlist, "msg") != NULL) { /* redirect output to /msg <nick> */ target = g_hash_table_lookup(optlist, "msg"); } else if (g_hash_table_lookup(optlist, "notice") != NULL) { target = g_hash_table_lookup(optlist, "notice"); notice = TRUE; } /* options that require process ID/name as argument */ if (rec == NULL && (signum != -1 || g_hash_table_lookup(optlist, "close") != NULL)) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown process name: %s", args); return; } if (g_hash_table_lookup(optlist, "close") != NULL) { /* forcibly close the process */ process_destroy(rec, -1); return; } if (signum != -1) { /* send a signal to process */ kill(rec->pid, signum); return; } interactive = g_hash_table_lookup(optlist, "interactive") != NULL; if (*args == '%') { /* do something to already existing process */ char *name; if (target != NULL) { /* redirect output to target */ g_free_and_null(rec->target); rec->target = g_strdup(target); rec->notice = notice; } name = g_hash_table_lookup(optlist, "name"); if (name != NULL) { /* change window name */ g_free_not_null(rec->name); rec->name = *name == '\0' ? NULL : g_strdup(name); } else if (target == NULL && (rec->target_item == NULL || interactive)) { /* no parameters given, redirect output to the active window */ g_free_and_null(rec->target); rec->target_win = active_win; if (rec->target_item != NULL) exec_wi_destroy(rec->target_item); if (interactive) { rec->target_item = exec_wi_create(active_win, rec); } } return; } /* starting a new process */ rec = g_new0(PROCESS_REC, 1); rec->pid = -1; rec->shell = g_hash_table_lookup(optlist, "nosh") == NULL; process_exec(rec, args); if (rec->pid == -1) { /* pipe() or fork() failed */ g_free(rec); cmd_return_error(CMDERR_ERRNO); } rec->id = process_get_new_id(); rec->target = g_strdup(target); rec->target_win = active_win; rec->target_channel = target_channel; rec->target_nick = target_nick; rec->args = g_strdup(args); rec->notice = notice; rec->silent = g_hash_table_lookup(optlist, "-") != NULL; rec->quiet = g_hash_table_lookup(optlist, "quiet") != NULL; rec->name = g_strdup(g_hash_table_lookup(optlist, "name")); level = g_hash_table_lookup(optlist, "level"); rec->level = level == NULL ? MSGLEVEL_CLIENTCRAP : level2bits(level); rec->read_tag = g_input_add(rec->in, G_INPUT_READ, (GInputFunction) sig_exec_input_reader, rec); processes = g_slist_append(processes, rec); if (rec->target == NULL && interactive) rec->target_item = exec_wi_create(active_win, rec); signal_emit("exec new", 1, rec); }