static int test_initfree_env(void) { process_t child = process_FREE; process_result_t result; TEST(0 == init_process(&child, &childprocess_environment, 0, &(process_stdio_t)process_stdio_INIT_INHERIT)); TEST(0 == wait_process(&child, &result)); TEST(0 == free_process(&child)); TEST(process_state_TERMINATED == result.state); TEST(0 == result.returncode); return 0 ; ONERR: TEST(0 == free_process(&child)); return EINVAL ; }
/** process_close : 'process -> void <doc> Close the process I/O. </doc> **/ CAMLprim value process_close( value vp ) { val_check_kind(vp,k_process); free_process(vp); //val_kind(vp) = NULL; //val_gc(vp,NULL); return val_null; }
/** process_close : 'process -> void <doc> Close the process I/O. </doc> **/ static value process_close( value vp ) { val_check_kind(vp,k_process); free_process(vp); val_kind(vp) = NULL; val_gc(vp,NULL); return val_null; }
extern OBJ _AWait_Ahc_Awaitpid(OBJ x1,OBJ x2) /* hc_waitpid */ {OBJ r; pid_t tmppid; free_some(x2,1); tmppid=((PROCESS)(x1))->value; free_process(x1,1); r=hc_wait(tmppid,0); return r;}
extern OBJ _AWait_Ahc_Awaitgrp_Anb(OBJ x1,OBJ x2) /* hc_waitgrp_nb */ {OBJ r; pid_t tmppid; free_some(x2,1); tmppid=((PROCESS)(x1))->value; free_process(x1,1); r=hc_wait(-tmppid,WNOHANG); return r;}
static int allocate_resources(process *proc, queue *q_ready, queue *q_process, queue *q_wait) { if (!vector_leq(proc->request_vector, SYSTEM_RES)) { print_state_info(proc); printf("Process requested more resources than the system has available.\n"); if (!empty_queue(q_process)) { int process_index = proc->row_index; free_process(proc); process *new_proc = (process *) dequeue(q_process); new_proc->row_index = process_index; clear_row_vector(allocation_matrix[new_proc->row_index]); clear_row_vector(claim_matrix[new_proc->row_index]); increment_row_vector(new_proc->max_need_vector, claim_matrix[new_proc->row_index]); matrix_difference(claim_matrix, allocation_matrix, difference_matrix); enqueue(q_ready, new_proc); } free_process(proc); return FALSE; } if (!is_valid_request(proc)) { print_state_info(proc); move_to_wait(q_wait, proc); return -1; } if (is_no_deadlock(proc)) { /* the resulting state after allocation is safe therefore allocate the resources this process requires */ increment_row_vector(proc->request_vector, allocation_matrix[proc->row_index]); decrement_row_vector(proc->request_vector, available_vector); matrix_difference(claim_matrix, allocation_matrix, difference_matrix); return 0; } else { /* allocation of resources could potentially lead to a deadlock therefore enqueue this process */ printf("\n>>> DEADLOCK POTENTIALLY AVOIDED <<<\n"); print_state_info(proc); move_to_wait(q_wait, proc); return -1; } }
void free_job(job *j) { if(!j) return; free_job(j->next); free_process(j->process_list); free(j); }
int run_process(int argc, char **argv, int debug) { struct Process * pl = load_process(*argv); if (!pl) return -1; be = pl->be; bd = pl->bd; int r = run_c(argc, argv, debug, pl->main_addr); free_process(pl); return r; }
void erts_do_exit_process(ErlProcess* p, Eterm reason) { #if (DEBUG_OP == 1) char buf[45]; sprintf(buf, "process %d exited with reason %d\n", p->id, reason); debug(buf); #endif p->flags |= F_EXITING; //cancel timer; erts_cancel_timer(&p->timer); //delete potential interrupts delete_interrupt(p->id); //propagate information if(reason != atom_normal) { ErtsLink* link = p->links; Eterm* hp = (Eterm*)pvPortMalloc(4*sizeof(Eterm)); hp[0] = make_arityval(3); hp[1] = atom_EXIT; hp[2] = p->id; hp[3] = reason; Eterm exit_message = make_tuple(hp); while(link != NULL) { ErlProcess* linked = (ErlProcess*)&proc_tab[pid2pix(link->pid)]; if(!(linked->flags & F_EXITING)) { erts_remove_link(&linked->links, p->id); } if(linked->flags & F_TRAP_EXIT && reason != atom_kill) { erts_send_message(p, link->pid, exit_message, 0); } else { if(!(linked->flags & F_EXITING)) { erts_do_exit_process(linked, reason); } } link = link->next; } vPortFree(hp); } //clean flags since they will be reused free_process(p); suspended++; vTaskSuspend(*(p->handle)); continued++; }
/* *** External visible functions *** */ void elect() { // Delete current if terminated (so a terminated process does not wait at the end of list) if (current_process->status == TERMINATED) { terminate_if_last_process(); current_process->previous->next = current_process->next; current_process->next->previous = current_process->previous; struct pcb_s* process_to_delete = current_process; choose_next_process(); free_process(process_to_delete); } else if (current_process->status == BLOCKED) { choose_next_process(); } else { current_process->status = READY; choose_next_process(); } #if DEBUG #if FB fb_print_char('\n'); fb_print_text("The process with PID "); fb_print_int(current_process->pid); fb_print_text(" chosen with priority "); fb_print_int(current_process->priority); fb_print_char('\n'); #else log_str("\n The process with PID "); log_int(current_process->pid); log_str(" chosen with priority "); log_int(current_process->priority); log_str("\n"); #endif #endif if (current_process->status == TERMINATED || current_process->status == BLOCKED) elect(); // Elect the next one, and delete the current one else current_process->status = RUNNING; // Else, this one is now running }
void free_process(t_process *process) { t_process *tmp; while (process != NULL) { free(process->reg); if (process->child != NULL) free_process(process->child); tmp = process; process = process->next; free(tmp); } }
int save_process(const char * process_file, int * e, int * be, char * data, char * bd, int * sym) { struct Process * p = create_process(e, be, data, bd, sym); if (p == NULL) return -1; FILE * f = fopen(process_file, "wb"); fwrite(&p->main_addr, sizeof(p->main_addr), 1, f); fwrite(&p->text_size, sizeof(p->text_size), 1, f); fwrite(&p->data_size, sizeof(p->data_size), 1, f); fwrite(p->be, 1, p->text_size, f); fwrite(p->bd, 1, p->data_size, f); fclose(f); free_process(p); return 0; }
static void free_process(process *p) { if(!p) return; free_process(p->next); if(p->program_name) free(p->program_name); if(p->input_redirection) free(p->input_redirection); if(p->output_redirection) free(p->output_redirection); if(p->argument_list) { int i; for(i=0; p->argument_list[i] != NULL; i++) free(p->argument_list[i]); free(p->argument_list); } free(p); }
int waitpid(int pid) { if(current->proc->flags & PROC_FLAG_DEBUG) { debug("[info]WAITPID(%d)\n", pid); } process_t *proc = get_process(pid); while(proc->state != PROC_STATE_FINISHED) { scheduler_sleep(current, &proc->waiting); schedule(); } int ret = proc->exit_code; free_process(proc); errno = 0; return ret; }
static int deallocate_resources(process *proc, queue *q_ready, queue *q_process, queue *q_wait, int is_end) { if (is_end) { printf("\nSUCCESSFULLY TERMINATED PROCESS WITH PID %u\n", proc->pid); increment_row_vector(allocation_matrix[proc->row_index], available_vector); clear_row_vector(allocation_matrix[proc->row_index]); clear_row_vector(claim_matrix[proc->row_index]); if (load_from_wait(q_wait, q_ready)) { /* attempt to load a process from the wait state */ free_process(proc); return -1; } if (empty_queue(q_process)) { /* no processes in the wait state so attempt to load from process queue */ free_process(proc); return -1; } process *new_proc = (process *) dequeue(q_process); new_proc->row_index = proc->row_index; increment_row_vector(new_proc->max_need_vector, claim_matrix[new_proc->row_index]); matrix_difference(claim_matrix, allocation_matrix, difference_matrix); enqueue(q_ready, new_proc); free_process(proc); return -1; } else if (!vector_leq(proc->release_vector, allocation_matrix[proc->row_index])) { increment_row_vector(allocation_matrix[proc->row_index], available_vector); printf("\nProcess with PID %u ", proc->pid); print_row_vector(proc->release_vector, "attempted to release"); print_row_vector(allocation_matrix[proc->row_index], "but only has allocated"); clear_row_vector(allocation_matrix[proc->row_index]); clear_row_vector(claim_matrix[proc->row_index]); printf("\nABNORMAL TERMINATION OF PROCESS WITH PID %u\n", proc->pid); if (load_from_wait(q_wait, q_ready)) { free_process(proc); return -1; } else { if (empty_queue(q_process)) { free_process(proc); return -1; } process *new_proc = (process *) dequeue(q_process); new_proc->row_index = proc->row_index; increment_row_vector(new_proc->max_need_vector, claim_matrix[new_proc->row_index]); matrix_difference(claim_matrix, allocation_matrix, difference_matrix); enqueue(q_ready, new_proc); free_process(proc); return -1; } } else { /* case were we can deallocate resources and have not reached an "END" instruction */ decrement_row_vector(proc->release_vector, allocation_matrix[proc->row_index]); increment_row_vector(proc->release_vector, available_vector); matrix_difference(claim_matrix, allocation_matrix, difference_matrix); load_from_wait(q_wait, q_ready); /* try to load one of the suspended processes */ return 0; } }
static int widget_update (struct widget *widget, struct widget_config config) { CURL *curl; CURLcode status; char *data; long code; /* connect and handle IMAP responses */ curl = curl_easy_init(); data = malloc(CURL_BUF_SIZE); if (!curl || !data) { return 0; } write_result_t write_result = { .data = data, .pos = 0 }; curl_easy_setopt(curl, CURLOPT_USERNAME, config.username); curl_easy_setopt(curl, CURLOPT_PASSWORD, config.password); curl_easy_setopt(curl, CURLOPT_URL, config.address); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH UNSEEN"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, candybar_curl_write_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); if (config.ssl_verify) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); } status = curl_easy_perform(curl); if (status != CURLE_OK) { LOG_ERR("unable to request data from %s (this error may be temporary): %s", config.address, curl_easy_strerror(status)); return 0; } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if (code != 0) { LOG_ERR("server responded with code %ld", code); return 0; } curl_easy_cleanup(curl); curl_global_cleanup(); data[write_result.pos] = '\0'; /* count unread message IDs */ /* the server responds with a string like "* SEARCH 1 2 3 4" where the numbers are message IDs */ char *str, *saveptr, *delim = " *"; int unread = -1; str = strtok_r(data, delim, &saveptr); while (str != NULL) { str = strtok_r(NULL, delim, &saveptr); unread++; } free(data); widget_data_callback(widget, widget_data_arg_number(unread), widget_data_arg_string(config.username)); return 0; } static const char* next (const char *ch, int space) { while (*ch && !isspace(*ch) == !space) { ++ch; } return ch; } static int parse_cmdline_arguments (const char *password_command, struct Process *proc) { const char *start = next(password_command, 1); if (!*start) { return -1; } const char *end = next(start, 0); if (!*end) { proc->path = strdup(start); } else { proc->path = strndup(start, end - start); } proc->argv = calloc(1024, sizeof(char*)); proc->argv[0] = proc->path; int argv_idx = 1; while ((start = next(end, 1))) { end = next(start, 0); if (!*end) { proc->argv[argv_idx++] = strdup(start); break; } else { proc->argv[argv_idx++] = strndup(start, end - start); } } return 1; } void* widget_main (struct widget *widget) { struct widget_config config = widget_config_defaults; widget_init_config_string(widget->config, "address", config.address); widget_init_config_string(widget->config, "username", config.username); widget_init_config_string(widget->config, "password", config.password); widget_init_config_string(widget->config, "password_command", config.password_command); widget_init_config_boolean(widget->config, "ssl_verify", config.ssl_verify); widget_init_config_integer(widget->config, "refresh_interval", config.refresh_interval); if (!config.username) { LOG_INFO("email_imap: username not set, disabling widget"); return 0; } struct Buffer buffer; memset(&buffer, 0, sizeof(buffer)); if (strlen(config.password_command)) { struct Process proc; memset(&proc, 0, sizeof(proc)); proc.stderr_cb = write_stderr; proc.stdout_cb = write_stdout; proc.user_data = &buffer; if (parse_cmdline_arguments(config.password_command, &proc) == -1) { LOG_ERR("email_imap: cannot parse password_command: \"%s\"", config.password_command); return 0; } const int ret = process(&proc); free_process(&proc); if (ret != 0) { LOG_ERR("email_imap: process error: %s => %d: %s/%s\n", proc.path, ret, proc.error, buffer.stderr_buffer); return 0; } config.password = buffer.stdout_buffer; } widget_epoll_init(widget); while (true) { widget_update(widget, config); widget_epoll_wait_goto(widget, config.refresh_interval, cleanup); } cleanup: widget_epoll_cleanup(widget); widget_clean_exit(widget); free_buffer(&buffer); }
int kwaitpid(pid_t pid, WAIT_STATUS status, int options) { struct process *curr = NULL; int i = 0, fixup = 0; retry: for(i = 0; i < Nr_PRIORITY; ++i) { curr = process_tab[i]; do { if(curr) { if(curr == current_process) { curr = curr->p_next; continue; } if(curr->p_parent != current_process->p_pid) { curr = curr->p_next; continue; } if(pid > 0) { if(curr->p_pid != pid) { curr = curr->p_next; continue; } } else if (pid == 0) { if(curr->p_pgrp != current_process->p_pgrp) { curr = curr->p_next; continue; } } else if (pid != -1) { if(curr->p_pgrp != -pid) { curr = curr->p_next; continue; } } if(curr->p_state == P_STOPPED) { if(!(options & WUNTRACED)) { curr = curr->p_next; continue; } *status = 0x7F; return curr->p_pid; } else if(curr->p_state == P_ZOMBIE) { current_process->p_cutime += curr->p_utime; current_process->p_cstime += curr->p_stime; pid = curr->p_pid; *status = curr->p_exit_code; free_process(curr); return pid; } else { fixup = 1; } curr = curr->p_next; } else { break; } } while(curr != process_tab[i]); } if(fixup) { if(options & WNOHANG) { return 0; } current_process->p_state = P_INTERRUPTIBLE; schedule(); current_process->p_signal &= ~(1 << SIGCHLD); if(!(current_process->p_signal & (1 << SIGCHLD))) { goto retry; } else { return EINTR; } return ECHILD; } }// kwaitpid
int main(int argc, char *argv[]) { char command[32]; int eventsNr, eventId, procId, priority; int i, iteration; TStack **eventsStacks; TQueue *procQ; // Daca nu exista destule argumente la rularea programului, atunci opreste executia if (argc < 3) { printf("Argumente insuficiente!\n"); return -1; } // Seteaza fisierele de intrare si de iesire freopen(argv[1], "r", stdin); freopen(argv[2], "w", stdout); // Citeste numarul de event-uri si creeaza stivele lor fscanf(stdin, "%d", &eventsNr); eventsStacks = calloc(eventsNr, sizeof(TStack*)); for (i = 0; i < eventsNr; i++) { eventsStacks[i] = stack_new(sizeof(TProcess)); } // Creeaza coada de prioritati procQ = queue_new(sizeof(TProcess), compare_process); // Citeste si executa comenzile din fisierul de intrare iteration = 0; while (fscanf(stdin, "%s", command) != EOF) { iteration++; if (strcmp(command, "start") == 0) { fscanf(stdin, "%d", &procId); fscanf(stdin, "%d", &priority); // Creeaza un proces TProcess p; p.id = procId; p.priority = priority; p.iteration = iteration; // Introduce procesul creat in coada de prioritati queue_push(procQ, &p); } else if (strcmp(command, "wait") == 0) { fscanf(stdin, "%d", &eventId); fscanf(stdin, "%d", &procId); // Creaza o stiva auxiliara TStack *aux = stack_new(sizeof(TProcess)); // Muta procesele in stiva auxiliara pana cand procesul // cautat este gasit si mutat in stiva evenimentului TProcess *p; while (!queue_isEmpty(procQ)) { p = queue_pop(procQ); if (p->id == procId) { stack_push(eventsStacks[eventId], p); free_process(p); break; } stack_push(aux, p); free_process(p); } // Muta procesele din stiva auxiliara inapoi in coada // de prioritati while (!stack_isEmpty(aux)) { p = stack_pop(aux); queue_push(procQ, p); free_process(p); } // Distruge stiva auxiliara stack_destroy(&aux, free_process); } else if (strcmp(command, "event") == 0) { fscanf(stdin, "%d", &eventId); // Muta procesele din stiva evenimentului in coada // de prioritati TProcess *p; while (!stack_isEmpty(eventsStacks[eventId])) { p = stack_pop(eventsStacks[eventId]); queue_push(procQ, p); free_process(p); } } else if (strcmp(command, "end") == 0) { fscanf(stdin, "%d", &procId); // Creaza o stiva auxiliara TStack *aux = stack_new(sizeof(TProcess)); // Muta procesele in stiva auxiliara pana cand procesul // cautat este gasit si sters TProcess *p; while (!queue_isEmpty(procQ)) { p = queue_pop(procQ); if (p->id == procId) { free_process(p); break; } stack_push(aux, p); free_process(p); } // Muta procesele din stiva auxiliara inapoi in coada // de prioritati while (!stack_isEmpty(aux)) { p = stack_pop(aux); queue_push(procQ, p); free_process(p); } // Distruge stiva auxiliara stack_destroy(&aux, free_process); } // Afiseaza iteratia printf("%d\n", iteration); // Afiseaza coada de prioritati if (!queue_isEmpty(procQ)) { queue_print(procQ, print_process); } else { printf("\n"); } // Afiseaza stivele for (i = 0; i < eventsNr; i++) { if (!stack_isEmpty(eventsStacks[i])) { printf("%d: ", i); stack_print(eventsStacks[i], print_process); } } printf("\n"); } // Elibereaza memoria queue_destroy(&procQ, free_process); for (i = 0; i < eventsNr; i++) { stack_destroy(&eventsStacks[i], free_process); } free(eventsStacks); return 0; }