int main(void) { /* Setup */ identifier = (int *)calloc_safe(1, sizeof(int)); *identifier = PARENT_IDENTIFIER; process_number = -1; /* Open file for reading */ FILE *input_file = fopen_safe("input.txt", "r"); /* Create necessary pipes */ create_pipes(); /* Fork children processes */ pid_t main_id = getpid(); // main_id contains parent process ID create_mappers(main_id); if (getpid() == main_id) // more efficient to include this statement create_reducers(main_id); /* Close proper pipe ends */ close_pipe_ends(); /* Parse the input file. Processes handle properly. */ parse_file(input_file); // free heap ptrs return 0; }
tmp_pipes(int nb_pipes): tmpdir_(create_tmp_dir()), pipes_(create_pipes(tmpdir_, nb_pipes)) { for(auto it = pipes_.cbegin(); it != pipes_.cend(); ++it) pipes_paths_.push_back(it->c_str()); }
void initialize_overhead(iter_t iterations, void* cookie) { int i; int procs; int* p; struct _state* pState = (struct _state*)cookie; if (iterations) return; pState->pids = NULL; pState->p = (int**)malloc(pState->procs * (sizeof(int*) + 2 * sizeof(int))); pState->data = (pState->process_size > 0) ? malloc(pState->process_size) : NULL; if (!pState->p || (pState->process_size > 0 && !pState->data)) { perror("malloc"); exit(1); } p = (int*)&pState->p[pState->procs]; for (i = 0; i < pState->procs; ++i) { pState->p[i] = p; p += 2; } if (pState->data) bzero(pState->data, pState->process_size); procs = create_pipes(pState->p, pState->procs); if (procs < pState->procs) { cleanup_overhead(0, cookie); exit(1); } }
int run_job(JOB* job) { int i, **pipes = NULL; if (job == NULL || job->cmd == NULL) return -1; if (job->ncmd > 1) { pipes = create_pipes(job->ncmd-1); if (pipes == NULL) return -1; } job->run_count = job->ncmd; job_list_push(job); job->pgid = 0; for (i = 0; i < job->ncmd; i++) { int input, output; if (i == 0) { if (job->inputfd != -1) input = job->inputfd; else input = 0; } else input = pipes[i-1][0]; if (i == job->ncmd-1) { if (job->outputfd != -1) output = job->outputfd; else output = 1; } else output = pipes[i][1]; job->pid[i] = run_cmd(job->cmd[i], input, output, pipes, job->ncmd-1, job->pgid); if (job->pid[i] <= 0) job->run_count--; /* Built-in commands and failed executions are not running processes */ else if (job->pgid == 0) { job->pgid = job->pid[i]; job->lastmodified = time(NULL); /* A new job is a 'recently modified job' to fg/bg default */ } } destroy_pipes(&pipes, job->ncmd-1); if (job->blocking) fg_wait(job); return 0; }
int shim_do_pipe2 (int * filedes, int flags) { if (!filedes) return -EINVAL; int ret = 0; struct shim_handle * hdl1 = get_new_handle(); struct shim_handle * hdl2 = get_new_handle(); if (!hdl1 || !hdl2) { ret = -ENOMEM; goto out; } hdl1->type = TYPE_PIPE; set_handle_fs(hdl1, &pipe_builtin_fs); hdl1->flags = O_RDONLY; hdl1->acc_mode = MAY_READ; hdl2->type = TYPE_PIPE; set_handle_fs(hdl2, &pipe_builtin_fs); hdl2->flags = O_WRONLY; hdl2->acc_mode = MAY_WRITE; if ((ret = create_pipes(&hdl1->info.pipe.pipeid, &hdl1->pal_handle, &hdl2->pal_handle, &hdl1->uri, flags)) < 0) goto out; qstrcopy(&hdl2->uri, &hdl2->uri); flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0; int vfd1 = set_new_fd_handle(hdl1, flags, NULL); int vfd2 = set_new_fd_handle(hdl2, flags, NULL); if (vfd1 < 0 || vfd2 < 0) { if (vfd1 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL); if (tmp) close_handle(tmp); } if (vfd2 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL); if (tmp) close_handle(tmp); } goto out; } filedes[0] = vfd1; filedes[1] = vfd2; out: if (hdl1) put_handle(hdl1); if (hdl2) put_handle(hdl2); return ret; }
int prepa_pipes(t_cmd *cmd, int i) { while (cmd[i].token != NULL && cmd[i].token[0] != ';') { if ((strcmp(cmd[i].token, "|") == 0)) create_pipes(cmd, i); else if ((strcmp(cmd[i].token, "||") == 0)) cmd[i].fdout = 1; else if ((strcmp(cmd[i].token, "&&") == 0)) cmd[i].fdout = 1; i++; } if (cmd[i].type == 0) cmd[i].fdout = 1; return (0); }
static foreign_t process_create(term_t exe, term_t options) { p_options info; int rc = FALSE; memset(&info, 0, sizeof(info)); if ( !get_exe(exe, &info) ) goto out; if ( !parse_options(options, &info) ) goto out; if ( !create_pipes(&info) ) goto out; rc = do_create_process(&info); out: free_options(&info); return rc; }
// This method rapresents the conversation function to be passed to the PAM library int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *data) { char *buf = (char *) calloc(PAM_MAX_RESP_SIZE, sizeof(char)); char nomepipe[1024]; int i; if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); if ((*resp = calloc(num_msg, sizeof **resp)) == NULL) return (PAM_BUF_ERR); for (i = 0; i < num_msg; ++i) { create_pipes(); resp[i]->resp_retcode = 0; resp[i]->resp = NULL; // Watch the type of the message and acts accordingly switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID); write_file(&nomepipe[0], "PROMPT_ECHO_OFF", 0); break; case PAM_PROMPT_ECHO_ON: sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID); write_file(&nomepipe[0], "PROMPT_ECHO_ON", 0); break; case PAM_ERROR_MSG: sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID); write_file(&nomepipe[0], "ERROR_MSG", 0); break; case PAM_TEXT_INFO: sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID); write_file(&nomepipe[0], "TEXT_INFO", 0); break; default: goto fail; } sprintf(nomepipe, "%s%s_testo", PREFIX, sessionID); write_file(&nomepipe[0], msg[i]->msg, 0); // If the message type needs a response from the user, reads it sprintf(nomepipe, "%s%s_risposta", PREFIX, sessionID); if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON) { read_file(&nomepipe[0], &buf); resp[i]->resp = strdup(buf); if (resp[i]->resp == NULL) goto fail; } // TODO AB printf("get response: %s.\n", buf); remove(&nomepipe[0]); } return (PAM_SUCCESS); fail: while (i) free(resp[--i]); free(*resp); *resp = NULL; return (PAM_CONV_ERR); }
int main(int ac, char **av) { int i, max_procs; double overhead = 0; if (ac < 2) { usage: printf("Usage: %s [-s kbytes] processes [processes ...]\n", av[0]); exit(1); } /* * Need 4 byte ints. */ if (sizeof(int) != 4) { fprintf(stderr, "Fix sumit() in ctx.c.\n"); exit(1); } /* * If they specified a context size, get it. */ if (!strcmp(av[1], "-s")) { if (ac < 4) { goto usage; } process_size = atoi(av[2]) * 1024; if (process_size > 0) { data = (int *)calloc(1, max(process_size, CHUNK)); BENCHO(sumit(CHUNK), sumit(0), 0); overhead = gettime(); overhead /= get_n(); overhead *= process_size; overhead /= CHUNK; } ac -= 2; av += 2; } #if defined(sgi) && defined(PIN) ncpus = sysmp(MP_NPROCS); sysmp(MP_MUSTRUN, 0); #endif for (max_procs = atoi(av[1]), i = 1; i < ac; ++i) { int procs = atoi(av[i]); if (max_procs < procs) max_procs = procs; } max_procs = create_pipes(p, max_procs); overhead += pipe_cost(p, max_procs); max_procs = create_daemons(p, pids, max_procs); fprintf(stderr, "\n\"size=%dk ovr=%.2f\n", process_size/1024, overhead); for (i = 1; i < ac; ++i) { double time; int procs = atoi(av[i]); if (procs > max_procs) continue; BENCH(ctx(procs, max_procs), 0); time = usecs_spent(); time /= get_n(); time /= procs; time /= TRIPS; time -= overhead; fprintf(stderr, "%d %.2f\n", procs, time); } /* * Close the pipes and kill the children. */ killem(max_procs); for (i = 0; i < max_procs; ++i) { close(p[i][0]); close(p[i][1]); if (i > 0) { wait(0); } } return (0); }
int main(int argc, const char* argv[]) { int status, bg_pipes[2], num_pipes, flags; struct sigaction act_bg_term, act_int_old, act_int_new; /* Define handler for SIGINT (ignore) */ act_int_new.sa_handler = SIG_IGN; act_int_new.sa_flags = 0; if (sigaction(SIGINT, &act_int_new, &act_int_old)) perror("Failed to change handler for SIGINT"); /* Define handler for detecting background process termination */ if (SIGNAL_DETECTION == 1) { if (sigaction(SIGUSR1, NULL, &act_bg_term)) perror("Failed to get handler for SIGUSR1"); act_bg_term.sa_handler = sig_bg_handler; act_bg_term.sa_flags = SA_RESTART; if (sigaction(SIGUSR1, &act_bg_term, NULL)) perror("Failed to set handler for SIGUSR1"); } /* Create pipe for printing background process info */ num_pipes = 1; create_pipes(bg_pipes, num_pipes); /* Configure pipe to be non-blocking on read end */ flags = fcntl(bg_pipes[0], F_GETFL, 0); fcntl(bg_pipes[0], F_SETFL, flags | O_NONBLOCK); while (1) { char input[80], cmd[80]; int i; /* Wait for all defunct children */ /* Continue even if no child has exited */ if (!(SIGNAL_DETECTION == 1)) while (waitpid(-1, &status, WNOHANG | WUNTRACED) > 0); /* Print prompt */ if (!print_prompt()) continue; /* Exit if error occurs */ if (!fgets(input, 80, stdin)) { perror("Failed to get input"); continue; } /* Remove newline, if present */ i = strlen(input) - 1; if (input[i] == '\n') input[i] = '\0'; /* Read given commands */ i = 0; /* Input index */ i = read_cmd(cmd, input, i); if (strcmp(cmd, "exit") == 0) break; else if (strcmp(cmd, "cd") == 0) cd(input, cmd, i); else if (strcmp(cmd, "checkEnv") == 0) check_env(input, i); else if (cmd[0] == '\0') {} /* Just print process info */ else general_cmd(input, &act_int_old, bg_pipes); /* Print accumulated process information */ print_process_info(bg_pipes); } /* Close pipe for printing background process info */ close_pipes(bg_pipes, num_pipes); exit_shell(); return 0; }
int general_cmd(char* input, const struct sigaction* act_int_old, const int* bg_pipes) { int pipes[2]; /* File descriptors from piping */ int fds[4]; /* File descriptors to dupe */ int background_process; /* Whether to run in the background */ int status; /* Wait status */ int i; /* Command index */ int j = 1; /* Loop index */ int num_pipes = 1; /* Number of pipes to create */ char* args[80]; /* All arguments to the command */ char arg[80]; /* One argument to command */ char cmd[80]; /* The command to be executed */ unsigned long exec_time; /* Execution time */ pid_t pid; /* PID of child */ struct timeval time_before; /* Time before execution of command */ struct timeval time_after; /* Time after execution of command */ create_pipes(pipes, num_pipes); fds[0] = -1; fds[1] = -1; fds[2] = -1; fds[3] = -1; /* Read the entire command string */ background_process = 0; for (i = 0; ; ++i) { /* Check if the process should run in the background */ if (input[i] == '&') { background_process = 1; input[i] = '\0'; break; } else if (input[i] == '\0') { break; } } /* Read the command */ i = read_cmd(cmd, input, 0); /* First argument in list must be file name */ args[0] = cmd; /* Read arguments to the command */ while (input[i] != '\0') { i = read_cmd(arg, input, i); args[j] = arg; ++j; } /* Argument list to execvp is NULL terminated */ args[j] = (char*) NULL; pid = fork(); /* Create new child process that handles execution */ /* Child process */ if (pid == 0) { /* Save current stdout file descriptor */ if (background_process) { /* Write termination info to process info pipe */ if (dup2(bg_pipes[1], WRITE) < 0) { perror("Failed to duplicate file descriptor for writing"); return 0; } /* Write err info to process info process pipe */ if (dup2(bg_pipes[1], ERROR) < 0) { perror("Failed to duplicate file descriptor for errors"); return 0; } /* Close file descriptor */ if (close(bg_pipes[1])) { perror("Failed to delete file descriptor"); return 0; } } /* Restore normal interrupt behaviour */ if (sigaction(SIGINT, act_int_old, NULL)) perror("Failed to change handler for SIGINT in child"); /* Measure execution time */ gettimeofday(&time_before, NULL); if (!fork_exec_cmd(cmd, pipes, fds, args, num_pipes, 0)) { perror(cmd); return 0; } if ((pid = wait(&status)) < 0) { perror("Failed to wait for executing process"); return 0; } /* Calculate execution time */ gettimeofday(&time_after, NULL); exec_time = 1000 * (time_after.tv_sec - time_before.tv_sec) + (time_after.tv_usec - time_before.tv_usec) / 1000; printf("(pid: %d) %s finished executing in %lu ms.\n", pid, cmd, exec_time); /* Notify parent of termination */ if (SIGNAL_DETECTION == 1 && background_process) { if (kill(getppid(), SIGUSR1)) { perror("Failed to notify parent of termination"); return 0; } } _exit(0); /* exit() unreliable */ } /* Error */ else if (pid < 0) { perror("Failed to fork child process"); exit(1); } /* Parent process */ else { /* The parent process comes here after forking */ if (!background_process) { if (waitpid(pid, &status, 0) < 0) { perror("Failed to wait for process"); return 0; } } } /* Let the parent processes close all pipes */ close_pipes(pipes, num_pipes); return 1; }
int check_env(const char* input, int i) { int pipes[6]; /* File descriptors from piping */ int fds[4]; /* File descriptors to dupe */ int status; /* Wait status */ int j = 1; /* Loop index */ int num_pipes = 2; /* Number of pipes to create */ char* args[80]; /* All arguments to grep */ char* pager = getenv("PAGER"); /* PAGER enviroment variable */ char cmd[80]; /* One grep parameter */ /* Read arguments to grep */ while (input[i] != '\0') { i = read_cmd(cmd, input, i); args[j] = cmd; ++j; } /* If arguments were given, one pipe is needed for grep */ if (j > 1) num_pipes = 3; /* Create all pipes beforehand */ create_pipes(pipes, num_pipes); /* Argument list to execvp is NULL terminated */ args[j] = (char*) NULL; /* First argument in list must be file name */ args[0] = cmd; /* pipe fds: (0, 1) [2, 3, 4, 5, 6, 7] */ /* PIPE READ WRITE */ /* 1 2 3 */ /* 2 4 5 */ /* 3 6 7 */ /* PROC READ WRITE */ /* 1 0 3 */ /* 2 2 5 */ /* 3 4 7 */ /* 4 6 1 */ /* Pipe and execute printenv */ fds[0] = -1; fds[1] = -1; fds[2] = 1; fds[3] = WRITE; if (!fork_exec_cmd("printenv", pipes, fds, NULL, num_pipes, 0)) { perror("Failed to execute printenv"); return 0; } /* Only pipe and excute grep if arguments were given */ fds[0] = 0; fds[1] = READ; fds[2] = 3; fds[3] = WRITE; if (num_pipes == 3) { if (!fork_exec_cmd("grep", pipes, fds, args, num_pipes, 0)) { perror("Failed to to execute grep"); return 0; } } /* Pipe and execute sort */ if (num_pipes == 3) { fds[0] = 2; fds[1] = READ; fds[2] = 5; fds[3] = WRITE; } if (!fork_exec_cmd("sort", pipes, fds, NULL, num_pipes, 0)) { perror("Failed to to execute sort"); return 0; } /* Try to pipe and execute with PAGER environment variable */ fds[0] = (num_pipes == 3) ? 4 : 2; fds[1] = READ; fds[2] = -1; fds[3] = -1; if (pager) { if (!fork_exec_cmd(pager, pipes, fds, NULL, num_pipes, 0)) { perror("Failed to to execute checkEnv with environment pager"); return 0; } } /* Try to pipe and execute with pager `less`, then `more` */ else { if (!fork_exec_cmd("more", pipes, fds, NULL, num_pipes, 1)) { perror("Failed to to execute checkEnv with default pagers"); return 0; } } /* Let the parent processes close all pipes */ close_pipes(pipes, num_pipes); /* Let the parent processes wait for all children */ for (j = 0; j < num_pipes + 1; ++j) { /* Wait for the processes to finish */ if (wait(&status) < 0) { perror("Failed to wait for process"); return 0; } } return 1; }
static int start_mbrola(const char *voice_path) { int error, p_stdin[2], p_stdout[2], p_stderr[2]; ssize_t written; char charbuf[20]; if (mbr_state != MBR_INACTIVE) { err("mbrola init request when already initialized"); return -1; } error = create_pipes(p_stdin, p_stdout, p_stderr); if (error) return -1; mbr_pid = fork(); if (mbr_pid == -1) { error = errno; close_pipes(p_stdin, p_stdout, p_stderr); err("fork(): %s", strerror(error)); return -1; } if (mbr_pid == 0) { int i; if (dup2(p_stdin[0], 0) == -1 || dup2(p_stdout[1], 1) == -1 || dup2(p_stderr[1], 2) == -1) { snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "dup2(): %s\n", strerror(errno)); written = write(p_stderr[1], mbr_errorbuf, strlen(mbr_errorbuf)); (void)written; // suppress 'variable not used' warning _exit(1); } for (i = p_stderr[1]; i > 2; i--) close(i); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); snprintf(charbuf, sizeof(charbuf), "%g", mbr_volume); execlp("mbrola", "mbrola", "-e", "-v", charbuf, voice_path, "-", "-.wav", (char *)NULL); /* if execution reaches this point then the exec() failed */ snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "mbrola: %s\n", strerror(errno)); written = write(2, mbr_errorbuf, strlen(mbr_errorbuf)); (void)written; // suppress 'variable not used' warning _exit(1); } snprintf(charbuf, sizeof(charbuf), "/proc/%d/stat", mbr_pid); mbr_proc_stat = open(charbuf, O_RDONLY); if (mbr_proc_stat == -1) { error = errno; close_pipes(p_stdin, p_stdout, p_stderr); waitpid(mbr_pid, NULL, 0); mbr_pid = 0; err("/proc is unaccessible: %s", strerror(error)); return -1; } signal(SIGPIPE, SIG_IGN); if (fcntl(p_stdin[1], F_SETFL, O_NONBLOCK) == -1 || fcntl(p_stdout[0], F_SETFL, O_NONBLOCK) == -1 || fcntl(p_stderr[0], F_SETFL, O_NONBLOCK) == -1) { error = errno; close_pipes(p_stdin, p_stdout, p_stderr); waitpid(mbr_pid, NULL, 0); mbr_pid = 0; err("fcntl(): %s", strerror(error)); return -1; } mbr_cmd_fd = p_stdin[1]; mbr_audio_fd = p_stdout[0]; mbr_error_fd = p_stderr[0]; close(p_stdin[0]); close(p_stdout[1]); close(p_stderr[1]); mbr_state = MBR_IDLE; return 0; }
int shim_do_socketpair (int domain, int type, int protocol, int * sv) { if (domain != AF_UNIX) return -EAFNOSUPPORT; if (type != SOCK_STREAM) return -EPROTONOSUPPORT; if (!sv) return -EINVAL; int ret = 0; struct shim_handle * hdl1 = get_new_handle(); struct shim_handle * hdl2 = get_new_handle(); if (!hdl1 || !hdl2) { ret = -ENOMEM; goto out; } struct shim_sock_handle * sock1 = &hdl1->info.sock; struct shim_sock_handle * sock2 = &hdl2->info.sock; hdl1->type = TYPE_SOCK; set_handle_fs(hdl1, &socket_builtin_fs); hdl1->flags = O_RDONLY; hdl1->acc_mode = MAY_READ|MAY_WRITE; sock1->domain = domain; sock1->sock_type = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC); sock1->protocol = protocol; sock1->sock_state = SOCK_ACCEPTED; hdl2->type = TYPE_SOCK; set_handle_fs(hdl2, &socket_builtin_fs); hdl1->flags = O_WRONLY; hdl2->acc_mode = MAY_READ|MAY_WRITE; sock2->domain = domain; sock2->sock_type = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC); sock2->protocol = protocol; sock2->sock_state = SOCK_CONNECTED; if ((ret = create_pipes(&sock1->addr.un.pipeid, &hdl1->pal_handle, &hdl2->pal_handle, &hdl1->uri, type & SOCK_NONBLOCK ? O_NONBLOCK : 0)) < 0) goto out; sock2->addr.un.pipeid = sock1->addr.un.pipeid; qstrcopy(&hdl2->uri, &hdl1->uri); int flags = type & SOCK_CLOEXEC ? FD_CLOEXEC : 0; int vfd1 = set_new_fd_handle(hdl1, flags, NULL); int vfd2 = set_new_fd_handle(hdl2, flags, NULL); if (vfd1 < 0 || vfd2 < 0) { if (vfd1 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL); if (tmp) close_handle(tmp); } if (vfd2 >= 0) { struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL); if (tmp) close_handle(tmp); } goto out; } sv[0] = vfd1; sv[1] = vfd2; out: if (hdl1) put_handle(hdl1); if (hdl2) put_handle(hdl2); return ret; }