static int slirp_open(void *data) { struct slirp_data *pri = data; int fds[2], pid, err; err = os_pipe(fds, 1, 1); if (err) return err; err = slirp_tramp(pri->argw.argv, fds[1]); if (err < 0) { printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err); goto out; } pid = err; pri->slave = fds[1]; pri->slip.pos = 0; pri->slip.esc = 0; pri->pid = err; return fds[0]; out: close(fds[0]); close(fds[1]); return err; }
static int change_tramp(char **argv, char *output, int output_len) { int pid, fds[2], err; struct change_pre_exec_data pe_data; err = os_pipe(fds, 1, 0); if (err < 0) { printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n", -err); return err; } pe_data.close_me = fds[0]; pe_data.stdout = fds[1]; pid = run_helper(change_pre_exec, &pe_data, argv); if (pid > 0) /* Avoid hang as we won't get data in failure case. */ read_output(fds[0], output, output_len); close(fds[0]); close(fds[1]); if (pid > 0) helper_wait(pid); return pid; }
int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { int (*tramp)(void *); int new_pid, err; unsigned long stack; if(current->thread.forking) tramp = fork_tramp; else { tramp = new_thread_proc; p->thread.request.u.thread = current->thread.request.u.thread; } err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); if(err < 0){ printk("copy_thread : pipe failed, err = %d\n", -err); return(err); } stack = alloc_stack(0, 0); if(stack == 0){ printk(KERN_ERR "copy_thread : failed to allocate " "temporary stack\n"); return(-ENOMEM); } clone_flags &= CLONE_VM; p->thread.temp_stack = stack; new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp); if(new_pid < 0){ printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", -new_pid); return(new_pid); } if(current->thread.forking){ sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; } p->thread.mode.tt.extern_pid = new_pid; current->thread.request.op = OP_FORK; current->thread.request.u.fork.pid = new_pid; os_usr1_process(os_getpid()); /* Enable the signal and then disable it to ensure that it is handled * here, and nowhere else. */ change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 0); err = 0; return(err); }
static int etap_open(void *data) { struct ethertap_data *pri = data; char *output; int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); if(err) return(err); err = os_pipe(data_fds, 0, 0); if(err < 0){ printk("data os_pipe failed - err = %d\n", -err); return(err); } err = os_pipe(control_fds, 1, 0); if(err < 0){ printk("control os_pipe failed - err = %d\n", -err); return(err); } err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = page_size(); output = um_kmalloc(output_len); read_output(control_fds[0], output, output_len); if(output == NULL) printk("etap_open : failed to allocate output buffer\n"); else { printk("%s", output); kfree(output); } if(err < 0){ printk("etap_tramp failed - err = %d\n", -err); return(err); } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); return(data_fds[0]); }
void set_init_pid(int pid) { int err; init_task.thread.mode.tt.extern_pid = pid; err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1); if(err) panic("Can't create switch pipe for init_task, errno = %d", -err); }
static int slip_tramp(char **argv, int fd) { struct slip_pre_exec_data pe_data; char *output; int status, pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); if(err < 0){ printk("slip_tramp : pipe failed, err = %d\n", -err); goto out; } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; err = run_helper(slip_pre_exec, &pe_data, argv, NULL); if(err < 0) goto out_close; pid = err; output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; goto out_free; } os_close_file(fds[1]); read_output(fds[0], output, output_len); printk("%s", output); CATCH_EINTR(err = waitpid(pid, &status, 0)); if(err < 0) err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ printk("'%s' didn't exit with status 0\n", argv[0]); err = -EINVAL; } else err = 0; os_close_file(fds[0]); out_free: kfree(output); return err; out_close: os_close_file(fds[0]); os_close_file(fds[1]); out: return err; }
static void setup_tracer_winch(void) { int err; err = os_pipe(tracer_winch, 1, 1); if(err < 0){ printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err); return; } signal(SIGWINCH, tracer_winch_handler); }
static int slip_tramp(char **argv, int fd) { struct slip_pre_exec_data pe_data; char *output; int pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); if (err < 0) { printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n", -err); goto out; } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; err = run_helper(slip_pre_exec, &pe_data, argv); if (err < 0) goto out_close; pid = err; output_len = UM_KERN_PAGE_SIZE; output = kmalloc(output_len, UM_GFP_KERNEL); if (output == NULL) { printk(UM_KERN_ERR "slip_tramp : failed to allocate output " "buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; goto out_free; } close(fds[1]); read_output(fds[0], output, output_len); printk("%s", output); err = helper_wait(pid, 0, argv[0]); close(fds[0]); out_free: kfree(output); return err; out_close: close(fds[0]); close(fds[1]); out: return err; }
static int change_tramp(char **argv, char *output, int output_len) { int pid, fds[2], err; struct change_pre_exec_data pe_data; err = os_pipe(fds, 1, 0); if(err){ printk("change_tramp - pipe failed, errno = %d\n", -err); return(err); } pe_data.close_me = fds[0]; pe_data.stdout = fds[1]; pid = run_helper(change_pre_exec, &pe_data, argv, NULL); close(fds[1]); read_output(fds[0], output, output_len); waitpid(pid, NULL, 0); return(pid); }
static int idle_proc(void *cpup) { int cpu = (int) cpup, err; err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1); if (err < 0) panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); os_set_fd_async(cpu_data[cpu].ipi_pipe[0]); wmb(); if (cpu_test_and_set(cpu, cpu_callin_map)) { printk(KERN_ERR "huh, CPU#%d already present??\n", cpu); BUG(); } while (!cpu_isset(cpu, smp_commenced_mask)) cpu_relax(); notify_cpu_starting(cpu); <<<<<<< HEAD
static int slip_tramp(char **argv, int fd) { struct slip_pre_exec_data pe_data; char *output; int status, pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); if(err){ printk("slip_tramp : pipe failed, errno = %d\n", -err); return(err); } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); if(pid < 0) err = pid; else { output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL) printk("slip_tramp : failed to allocate output " "buffer\n"); close(fds[1]); read_output(fds[0], output, output_len); if(output != NULL){ printk("%s", output); kfree(output); } if(waitpid(pid, &status, 0) < 0) err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ printk("'%s' didn't exit with status 0\n", argv[0]); err = EINVAL; } } return(err); }
int start_io_thread(unsigned long sp, int *fd_out) { int pid, fds[2], err; err = os_pipe(fds, 1, 1); if(err < 0){ printk("start_io_thread - os_pipe failed, err = %d\n", -err); goto out; } kernel_fd = fds[0]; *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; } pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM, NULL); if(pid < 0){ err = -errno; printk("start_io_thread - clone failed : errno = %d\n", errno); goto out_close; } return(pid); out_close: os_close_file(fds[0]); os_close_file(fds[1]); kernel_fd = -1; *fd_out = -1; out: return err; }
int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) { struct dog_data data; int in_fds[2], out_fds[2], pid, n, err; char pid_buf[sizeof("nnnnn\0")], c; char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, NULL }; char **args = NULL; err = os_pipe(in_fds, 1, 0); if (err < 0) { printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out; } err = os_pipe(out_fds, 1, 0); if (err < 0) { printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out_close_in; } data.stdin = out_fds[0]; data.stdout = in_fds[1]; data.close_me[0] = out_fds[1]; data.close_me[1] = in_fds[0]; if (sock != NULL) { mconsole_args[2] = sock; args = mconsole_args; } else { /* XXX The os_getpid() is not SMP correct */ sprintf(pid_buf, "%d", os_getpid()); args = pid_args; } pid = run_helper(pre_exec, &data, args); close(out_fds[0]); close(in_fds[1]); if (pid < 0) { err = -pid; printk("harddog_open - run_helper failed, errno = %d\n", -err); goto out_close_out; } n = read(in_fds[0], &c, sizeof(c)); if (n == 0) { printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); err = -EIO; goto out_close_out; } else if (n < 0) { printk("harddog_open - read of watchdog pipe failed, " "err = %d\n", errno); helper_wait(pid); err = n; goto out_close_out; } *in_fd_ret = in_fds[0]; *out_fd_ret = out_fds[1]; return 0; out_close_in: close(in_fds[0]); close(in_fds[1]); out_close_out: close(out_fds[0]); close(out_fds[1]); out: return err; }
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long *stack_out) { struct helper_data data; unsigned long stack, sp; int pid, fds[2], err, n; if((stack_out != NULL) && (*stack_out != 0)) stack = *stack_out; else stack = alloc_stack(0, um_in_interrupt()); if(stack == 0) return(-ENOMEM); err = os_pipe(fds, 1, 0); if(err < 0){ printk("run_helper : pipe failed, err = %d\n", -err); goto out_free; } err = os_set_exec_close(fds[1], 1); if(err < 0){ printk("run_helper : setting FD_CLOEXEC failed, err = %d\n", -err); goto out_close; } sp = stack + page_size() - sizeof(void *); data.pre_exec = pre_exec; data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); if(pid < 0){ printk("run_helper : clone failed, errno = %d\n", errno); err = -errno; goto out_close; } os_close_file(fds[1]); n = os_read_file(fds[0], &err, sizeof(err)); if(n < 0){ printk("run_helper : read on pipe failed, err = %d\n", -n); err = n; goto out_kill; } else if(n != 0){ CATCH_EINTR(n = waitpid(pid, NULL, 0)); pid = -errno; } if(stack_out == NULL) free_stack(stack, 0); else *stack_out = stack; return(pid); out_kill: os_kill_process(pid, 1); out_close: os_close_file(fds[0]); os_close_file(fds[1]); out_free: free_stack(stack, 0); return(err); }