static void handle_signal(struct signalfd_siginfo *fdsi) { switch (fdsi->ssi_signo) { case SIGINT: /* Try to terminate the child processes, if this * succeeds, we'll get a SIGCHLD for each child * process and eventually terminate ourselves. */ fprintf(stderr, "Sending SIGTERM to child processes.\n"); processes_kill(SIGTERM); break; case SIGUSR1: print_counters(stderr); break; case SIGCHLD: { bench_process_t *p = process_find(fdsi->ssi_pid); assert(p); p->zombie = 1; if (run_state == RUN_STATE_RUNNING) /* Kill all running child processes */ processes_kill(SIGTERM); run_state = processes_running() == 0 ? RUN_STATE_EXIT : RUN_STATE_WAITING; } break; default: /* Ignore other signals */ break; } }
int k_get_process_priority(int process_id) { PCB* pcb = process_find(gp_pcb_queue, process_id); if (pcb != NULL) { return pcb->priority; } return RTX_ERR; }
static process_t *waitqueue_dequeue(pid_t *q) { process_t *p; if(*q == NOPID) return NULL; p = process_find(*q); if(p == NULL) return NULL; *q = p->next; return p; }
/// @brief Queries a child process /// /// Tests if the child process, created by a previous call to the `start` /// operation, is still active. /// /// @return zero if the process is running, ESRCH/ERROR_NOT_FOUND or another /// non-zero error code otherwise int operation_query () { _WIN32_OR_POSIX (HANDLE, pid_t) process; if (verbose) fprintf (stdout, "Querying spawned process\n"); process = process_find (); if (process) { if (verbose) fprintf (stdout, "Process %u is running\n", _WIN32_OR_POSIX (GetProcessId (process), process)); #ifdef _WIN32 CloseHandle (process); #endif /* ifdef _WIN32 */ return 0; } else { if (verbose) fprintf (stdout, "No child process is running\n"); return _WIN32_OR_POSIX (ERROR_NOT_FOUND, ESRCH); } }
static status waitqueue_append(pid_t *q, process_t *p) { p->next = NOPID; for(;;) { /* tail-recursion elided */ if(*q == NOPID) { *q = p->pid; return OK; } else { process_t *qp = process_find(*q); if(qp == NULL) return EINVALID; q = &qp->next; } } }
int i_send_message(void *p_msg) { MSG *msg = (MSG*) p_msg; PCB* pcb = process_find(gp_pcb_queue, msg->rPID); if (pcb == NULL || msg == NULL) { return RTX_ERR; } message_queue_enqueue(pcb->message_queue, p_msg); if (pcb->state == BLOCKED_ON_RECEIVE) { pcb->state = READY; } return RTX_OK; }
int k_delayed_send(int process_id, void *message_envelope, int delay) { PCB* pcb = process_find(gp_pcb_queue, process_id); MSG *msg = (MSG*) message_envelope; if (pcb == NULL || msg == NULL) { return RTX_ERR; } msg->sPID = (int) gp_current_process->id; msg->rPID = process_id; msg->expiry = (U32) delay; message_queue_enqueue(gp_timeout_queue, msg); return RTX_OK; }
int k_send_message(int pid, void *p_msg) { PCB* pcb = process_find(gp_pcb_queue, pid); MSG *msg = (MSG*) p_msg; if (pcb == NULL || msg == NULL) { return RTX_ERR; } msg->sPID = (int) gp_current_process->id; msg->rPID = pid; message_queue_enqueue(pcb->message_queue, p_msg); if (pcb->state == BLOCKED_ON_RECEIVE) { pcb->state = READY; if (pcb->priority < gp_current_process->priority) { k_release_processor(); } } return RTX_OK; }
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); }