/* the routine we call when we are going to spawn/fork/whatnot a child process from the parent netserver daemon. raj 2011-07-08 */ void spawn_child() { #if defined(WIN32) BOOL b; char *cmdline; int cmdline_length; int cmd_index; PROCESS_INFORMATION pi; STARTUPINFO si; int i; #endif if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } #if defined(HAVE_FORK) /* flush the usual suspects */ fflush(stdin); fflush(stdout); fflush(stderr); fflush(where); signal(SIGCLD,SIG_IGN); switch (fork()) { case -1: fprintf(where, "%s: fork() error %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); case 0: /* we are the child, but not of inetd. we don't know if we are the child of a daemonized parent or not, so we still need to worry about the standard file descriptors. raj 2011-07-11 */ close_listens(listen_list); open_debug_file(); child = 1; netperf_daemon = 0; process_requests(); exit(0); break; default: /* we are the parent, not a great deal to do here, but we may want to reap some children */ #if !defined(HAVE_SETSID) /* Only call "waitpid()" if "setsid()" is not used. */ while(waitpid(-1, NULL, WNOHANG) > 0) { if (debug) { fprintf(where, "%s: reaped a child process\n", __FUNCTION__); } } #endif break; } #elif defined(WIN32) /* create the cmdline array based on strlen(program) + 80 chars */ cmdline_length = strlen(program) + 80; cmdline = malloc(cmdline_length + 1); // +1 for trailing null memset(&si, 0 , sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); /* Pass the server_sock as stdin for the new process. Hopefully this will continue to be created with the OBJ_INHERIT attribute. */ si.hStdInput = (HANDLE)server_sock; si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags = STARTF_USESTDHANDLES; /* Build cmdline for child process */ strcpy(cmdline, program); cmd_index = strlen(cmdline); if (verbosity > 1) { cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -v %d", verbosity); } for (i=0; i < debug; i++) { cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -d"); } cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -I %x", (int)(UINT_PTR)server_sock); /* are these -i settings even necessary? the command line scanning does not seem to do anything with them */ cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -i %x", (int)(UINT_PTR)server_control); cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -i %x", (int)(UINT_PTR)where); b = CreateProcess(NULL, /* Application Name */ cmdline, NULL, /* Process security attributes */ NULL, /* Thread security attributes */ TRUE, /* Inherit handles */ 0, /* Creation flags PROCESS_QUERY_INFORMATION, */ NULL, /* Enviornment */ NULL, /* Current directory */ &si, /* StartupInfo */ &pi); if (!b) { perror("CreateProcessfailure: "); free(cmdline); /* even though we exit :) */ exit(1); } /* We don't need the thread or process handles any more; let them go away on their own timeframe. */ CloseHandle(pi.hThread); CloseHandle(pi.hProcess); /* the caller/parent will close server_sock */ free(cmdline); #else fprintf(where, "%s called on platform which cannot spawn children\n", __FUNCTION__); fflush(where); exit(1); #endif /* HAVE_FORK */ }
int main(int argc, char *argv[]) { initializeSigHandler(); setpgid(0, 0); int i = 0; int ret = 0; pid_t pid; cmpQty = argc - 2; cmp = malloc(sizeof(company*) * cmpQty); map = malloc(sizeof(graph)); sem_id = createSem(SEM_CREAT_KEY, cmpQty + SEM_QTY); setAllSem(sem_id, cmpQty + SEM_QTY, 0); if (initPIDS() == MALLOC_ERROR ) return MALLOC_ERROR; /***PARSER***/ if (cmp == NULL || map == NULL ) return parserError(NULL, NULL, MALLOC_ERROR, NULL); if ((ret = parseFiles(argc, argv, map, cmp)) != EXIT_SUCCESS ) return ret; /***INITIALIZES ARRAYS FOR THE EXECL***/ initializeArray(&semMsg, sem_id); initializeArray(&procQty, ID_QTY + cmpQty); /***MAP AND COMPANIES CREATION***/ if (createIPC(MAIN_ID, cmpQty + ID_QTY) == ERROR ) return ERROR; int map_pid = 0; int io_pid = 0; int mult_pid = 0; if ((pid = fork()) == 0) { execl("io", semMsg, procQty, NULL); exit(1); } else { io_pid = pid; addPid(io_pid); if ((pid = fork()) == 0) { execl("map", semMsg, procQty, NULL); exit(1); } else { map_pid = pid; addPid(map_pid); if ((pid = fork()) == 0) { execl("multitasker", semMsg, procQty, NULL); exit(1); } else { mult_pid = pid; addPid(mult_pid); for (i = 0; i < cmpQty; i++) { if ((pid = fork()) == 0) { char *buf = NULL; int id = CMP_ID + i; initializeArray(&buf, id); execl("company", buf, procQty, semMsg, NULL); } else { addPid(pid); } } } } } upSem(sem_id, MAIN_ID); downSem(sem_id, IO_ID); downSem(sem_id, MULTITASKER_ID); for (i = 0; i < cmpQty; i++) { downSem(sem_id, CMP_ID + i); if (initializeCmp(cmp[i], MAIN_ID, CMP_ID + i) == ERROR ) return ERROR; } downSem(sem_id, MAP_ID); if (initializeMap(map, MAIN_ID, MAP_ID) == ERROR) { return ERROR; } downSem(sem_id, MAP_ID); for (i = 0; i < cmpQty; i++) { wait(0); //Waits for all the companies to finish } kill(mult_pid, SIGTERM); waitpid(mult_pid, 0, 0); kill(map_pid, SIGTERM); waitpid(map_pid, 0, 0); kill(io_pid, SIGTERM); waitpid(io_pid, 0, 0); if (disconnectFromIPC(MAIN_ID) == ERROR) { destroyIPC(MAIN_ID); } destroySem(sem_id); /***FREES***/ freeAll(); return EXIT_SUCCESS; }
/** * Signal handler for the server. */ void handle_sigs(void) { pid_t chld; int chld_status; int i; int do_exit; switch(sig_flag){ case 0: break; /* do nothing*/ case SIGPIPE: /* SIGPIPE might be rarely received on use of exec module; simply ignore it */ LM_WARN("SIGPIPE received and ignored\n"); break; case SIGINT: case SIGTERM: /* we end the program in all these cases */ if (sig_flag==SIGINT) LM_DBG("INT received, program terminates\n"); else LM_DBG("SIGTERM received, program terminates\n"); /* first of all, kill the children also */ kill_all_children(SIGTERM); if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) { LM_ERR("could not install SIGALARM handler\n"); /* continue, the process will die anyway if no * alarm is installed which is exactly what we want */ } alarm(OPENSER_SHUTDOWN_TIME); /* 1 minute close timeout */ while(wait(0) > 0); /* Wait for all the children to terminate */ signal(SIGALRM, sig_alarm_abort); cleanup(1); /* cleanup & show status*/ alarm(0); signal(SIGALRM, SIG_IGN); dprint("Thank you for flying " NAME "\n"); exit(0); break; case SIGUSR1: #ifdef PKG_MALLOC LOG(memlog, "Memory status (pkg):\n"); pkg_status(); #endif #ifdef SHM_MEM LOG(memlog, "Memory status (shm):\n"); shm_status(); #endif break; case SIGCHLD: do_exit = 0; while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) { /* is it a process we know about? */ for( i=0 ; i<counted_processes ; i++ ) if (pt[i].pid==chld) break; if (i==counted_processes) { LM_DBG("unkown child process %d ended. Ignoring\n",chld); continue; } do_exit = 1; /* process the signal */ if (WIFEXITED(chld_status)) LM_INFO("child process %d exited normally," " status=%d\n", chld, WEXITSTATUS(chld_status)); else if (WIFSIGNALED(chld_status)) { LM_INFO("child process %d exited by a signal" " %d\n", chld, WTERMSIG(chld_status)); #ifdef WCOREDUMP LM_INFO("core was %sgenerated\n", WCOREDUMP(chld_status) ? "" : "not " ); #endif }else if (WIFSTOPPED(chld_status)) LM_INFO("child process %d stopped by a" " signal %d\n", chld, WSTOPSIG(chld_status)); } if (!do_exit) break; LM_INFO("terminating due to SIGCHLD\n"); /* exit */ kill_all_children(SIGTERM); if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) { LM_ERR("could not install SIGALARM handler\n"); /* continue, the process will die anyway if no * alarm is installed which is exactly what we want */ } alarm(OPENSER_SHUTDOWN_TIME); /* 1 minute close timeout */ while(wait(0) > 0); /* wait for all the children to terminate*/ signal(SIGALRM, sig_alarm_abort); cleanup(1); /* cleanup & show status*/ alarm(0); signal(SIGALRM, SIG_IGN); LM_DBG("terminating due to SIGCHLD\n"); exit(0); break; case SIGHUP: /* ignoring it*/ LM_DBG("SIGHUP received, ignoring it\n"); break; default: LM_CRIT("unhandled signal %d\n", sig_flag); } sig_flag=0; }
/* Run an external command returning exit status, and optionally filling * provided buffer with STDOUT output up to the size provided. * * Note: XXX: We are not using the timeout parameter at present. We still need * to implement a reliable timeout mechanism. */ static int _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf, const size_t so_buf_sz, const int cflag, const int timeout, const char *substr_search, int *pid_status, const fko_srv_options_t * const opts) { char so_read_buf[IO_READ_BUF_LEN] = {0}; pid_t pid=0; FILE *output; int retval = EXTCMD_SUCCESS_ALL_OUTPUT; int line_ctr = 0, found_str = 0, do_break = 0; char *argv_new[MAX_CMDLINE_ARGS]; /* for validation and/or execvpe() */ int argc_new=0; #if HAVE_EXECVPE int pipe_fd[2]; #endif #if AFL_FUZZING /* Don't allow command execution in AFL fuzzing mode */ return 0; #endif *pid_status = 0; /* Even without execvpe() we examine the command for basic validity * in term of number of args */ memset(argv_new, 0x0, sizeof(argv_new)); if(strtoargv(cmd, argv_new, &argc_new) != 1) { log_msg(LOG_ERR, "run_extcmd(): Error converting cmd str to argv via strtoargv()"); return EXTCMD_ARGV_ERROR; } #if !HAVE_EXECVPE /* if we are not using execvpe() then free up argv_new unconditionally * since was used only for validation */ free_argv(argv_new, &argc_new); #endif #if HAVE_EXECVPE if(opts->verbose > 1) log_msg(LOG_INFO, "run_extcmd() (with execvpe()): running CMD: %s", cmd); if(so_buf != NULL || substr_search != NULL) { if(pipe(pipe_fd) < 0) { log_msg(LOG_ERR, "run_extcmd(): pipe() failed: %s", strerror(errno)); free_argv(argv_new, &argc_new); return EXTCMD_PIPE_ERROR; } } //在子进程中创建CMD。 pid = fork(); if (pid == 0) { if(chdir("/") != 0) exit(EXTCMD_CHDIR_ERROR); if(so_buf != NULL || substr_search != NULL) { close(pipe_fd[0]); dup2(pipe_fd[1], STDOUT_FILENO); if(cflag & WANT_STDERR) dup2(pipe_fd[1], STDERR_FILENO); else close(STDERR_FILENO); } /* Take care of gid/uid settings before running the command. */ if(gid > 0) if(setgid(gid) < 0) exit(EXTCMD_SETGID_ERROR); if(uid > 0) if(setuid(uid) < 0) exit(EXTCMD_SETUID_ERROR); /* don't use env */ execvpe(argv_new[0], argv_new, (char * const *)NULL); } else if(pid == -1) { log_msg(LOG_ERR, "run_extcmd(): fork() failed: %s", strerror(errno)); free_argv(argv_new, &argc_new); return EXTCMD_FORK_ERROR; } /* Only the parent process makes it here */ if(so_buf != NULL || substr_search != NULL) { close(pipe_fd[1]); if ((output = fdopen(pipe_fd[0], "r")) != NULL) { if(so_buf != NULL) memset(so_buf, 0x0, so_buf_sz); while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL) { line_ctr++; copy_or_search(so_read_buf, so_buf, so_buf_sz, substr_search, cflag, &found_str, &do_break); if(do_break) break; } fclose(output); /* Make sure we only have complete lines */ if(!(cflag & ALLOW_PARTIAL_LINES)) truncate_partial_line(so_buf); } else { log_msg(LOG_ERR, "run_extcmd(): could not fdopen() pipe output file descriptor."); free_argv(argv_new, &argc_new); return EXTCMD_OPEN_ERROR; } } free_argv(argv_new, &argc_new); waitpid(pid, pid_status, 0); #else if(opts->verbose > 1) log_msg(LOG_INFO, "run_extcmd() (without execvpe()): running CMD: %s", cmd); if(so_buf == NULL && substr_search == NULL) { /* Since we do not have to capture output, we will fork here (which we * * would have to do anyway if we are running as another user as well). * */ pid = fork(); if(pid == -1) { log_msg(LOG_ERR, "run_extcmd: fork failed: %s", strerror(errno)); return(EXTCMD_FORK_ERROR); } else if (pid == 0) { /* We are the child */ if(chdir("/") != 0) exit(EXTCMD_CHDIR_ERROR); /* Take care of gid/uid settings before running the command. */ if(gid > 0) if(setgid(gid) < 0) exit(EXTCMD_SETGID_ERROR); if(uid > 0) if(setuid(uid) < 0) exit(EXTCMD_SETUID_ERROR); *pid_status = system(cmd); exit(*pid_status); } /* Retval is forced to 0 as we don't care about the exit status of * the child (for now) */ retval = EXTCMD_SUCCESS_ALL_OUTPUT; } else { /* Looking for output use popen and fill the buffer to its limit. */ output = popen(cmd, "r"); if(output == NULL) { log_msg(LOG_ERR, "Got popen error %i: %s", errno, strerror(errno)); retval = EXTCMD_OPEN_ERROR; } else { if(so_buf != NULL) memset(so_buf, 0x0, so_buf_sz); while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL) { line_ctr++; copy_or_search(so_read_buf, so_buf, so_buf_sz, substr_search, cflag, &found_str, &do_break); if(do_break) break; } pclose(output); /* Make sure we only have complete lines */ if(!(cflag & ALLOW_PARTIAL_LINES)) truncate_partial_line(so_buf); } } #endif if(substr_search != NULL) { /* The semantics of the return value changes in search mode to the line * number where the substring match was found, or zero if it wasn't found */ if(found_str) retval = line_ctr; else retval = 0; } else { if(WIFEXITED(*pid_status)) { /* Even if the child exited with an error condition, if we make it here * then the child exited normally as far as the OS is concerned (i.e. didn't * crash or get hit with a signal) */ retval = EXTCMD_SUCCESS_ALL_OUTPUT; } else retval = EXTCMD_EXECUTION_ERROR; } if(opts->verbose > 1) log_msg(LOG_INFO, "run_extcmd(): returning %d, pid_status: %d", retval, WIFEXITED(*pid_status) ? WEXITSTATUS(*pid_status) : *pid_status); return(retval); }
int main(int argc, char *argv[]) { int opt, status; int ret; char *namespaces = NULL; char **args; int flags = 0; uid_t uid = -1; /* valid only if (flags & CLONE_NEWUSER) */ pid_t pid; struct start_arg start_arg = { .args = &args, .uid = &uid, .flags = &flags, }; while ((opt = getopt(argc, argv, "s:u:h")) != -1) { switch (opt) { case 's': namespaces = optarg; break; case 'h': usage(argv[0]); case 'u': uid = lookup_user(optarg); if (uid == -1) return 1; } } if (argv[optind] == NULL) { ERROR("a command to execute in the new namespace is required"); return 1; } args = &argv[optind]; ret = lxc_caps_init(); if (ret) return ret; ret = lxc_fill_namespace_flags(namespaces, &flags); if (ret) usage(argv[0]); if (!(flags & CLONE_NEWUSER) && uid != -1) { ERROR("-u <uid> needs -s USER option"); return 1; } pid = lxc_clone(do_start, &start_arg, flags); if (pid < 0) { ERROR("failed to clone"); return -1; } if (waitpid(pid, &status, 0) < 0) { ERROR("failed to wait for '%d'", pid); return -1; } return lxc_error_set_and_log(pid, status); }
extern int run_parts(char **args, const unsigned char test_mode) { struct dirent **namelist = 0; struct stat st; char *filename; char *arg0 = args[0]; int entries; int i; int exitstatus = 0; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &i; (void) &exitstatus; #endif /* scandir() isn't POSIX, but it makes things easy. */ entries = scandir(arg0, &namelist, valid_name, alphasort); if (entries == -1) { if (test_mode & 2) { return(2); } bb_perror_msg_and_die("failed to open directory %s", arg0); } for (i = 0; i < entries; i++) { filename = concat_path_file(arg0, namelist[i]->d_name); if (stat(filename, &st) < 0) { bb_perror_msg_and_die("failed to stat component %s", filename); } if (S_ISREG(st.st_mode) && !access(filename, X_OK)) { if (test_mode & 1) { puts(filename); } else { /* exec_errno is common vfork variable */ volatile int exec_errno = 0; int result; int pid; if ((pid = vfork()) < 0) { bb_perror_msg_and_die("failed to fork"); } else if (!pid) { args[0] = filename; execv(filename, args); exec_errno = errno; _exit(1); } waitpid(pid, &result, 0); if(exec_errno) { errno = exec_errno; bb_perror_msg_and_die("failed to exec %s", filename); } if (WIFEXITED(result) && WEXITSTATUS(result)) { bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result)); exitstatus = 1; } else if (WIFSIGNALED(result)) { bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result)); exitstatus = 1; } } } else if (!S_ISDIR(st.st_mode)) { bb_error_msg("component %s is not an executable plain file", filename); exitstatus = 1; } free(namelist[i]); free(filename); } free(namelist); return(exitstatus); }
int main(int argc, char** argv) { int prg_argc; char ** prg_argv; progname = argv[0]; if (argc < 3) usage(); int c, opt_index; while ((c = getopt_long(argc, argv, "f:r:", long_options, &opt_index)) != -1) { switch (c) { case 'f': { /* Special case hack for only creating files and not actually executing * the program. */ if (argc != 3) usage(); char* input_fname = optarg; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[1]; klee_init_env(&prg_argc, &prg_argv); replay_create_files(&__exe_fs); return 0; } case 'r': rootdir = optarg; break; } } /* Normal execution path ... */ char* executable = argv[optind]; /* make sure this process has the CAP_SYS_CHROOT capability. */ if (rootdir) ensure_capsyschroot(progname); /* rootdir should be a prefix of executable's path. */ if (rootdir && strstr(executable, rootdir) != executable) { fprintf(stderr, "Error: chroot: root dir should be a parent dir of executable.\n"); exit(1); } /* Verify the executable exists. */ FILE *f = fopen(executable, "r"); if (!f) { fprintf(stderr, "Error: executable %s not found.\n", executable); exit(1); } fclose(f); int idx = 0; for (idx = optind + 1; idx != argc; ++idx) { char* input_fname = argv[idx]; unsigned i; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } obj_index = 0; prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[optind]; klee_init_env(&prg_argc, &prg_argv); if (idx > 2) fprintf(stderr, "\n"); fprintf(stderr, "%s: TEST CASE: %s\n", progname, input_fname); fprintf(stderr, "%s: ARGS: ", progname); for (i=0; i != (unsigned) prg_argc; ++i) { char *s = prg_argv[i]; if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0'; fprintf(stderr, "\"%s\" ", prg_argv[i]); } fprintf(stderr, "\n"); /* Run the test case machinery in a subprocess, eventually this parent process should be a script or something which shells out to the actual execution tool. */ int pid = fork(); if (pid < 0) { perror("fork"); _exit(66); } else if (pid == 0) { /* Create the input files, pipes, etc., and run the process. */ replay_create_files(&__exe_fs); run_monitored(executable, prg_argc, prg_argv); _exit(0); } else { /* Wait for the test case. */ int res, status; do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); if (res < 0) { perror("waitpid"); _exit(66); } } } return 0; }
void trace(pid_t child, std::vector<std::string>& files, std::mutex & mutex) { waitpid(-1, NULL, __WALL); ptrace(PTRACE_ATTACH, child, 0, 0); ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT | PTRACE_O_EXITKILL); pid_t pid = child; while (true) { int status; ptrace(PTRACE_SYSCALL, pid, 0, 0); pid = waitpid(-1, &status, __WALL); if(WIFEXITED(status)) { break; } else if (WIFSTOPPED(status)) { struct user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, 0, ®s); struct regs { #ifdef __x86_64__ unsigned long #endif long err, syscall, arg0; } regs_ = { #ifdef __x86_64__ regs.rax, regs.orig_rax, regs.rdi #else regs.eax, regs.orig_eax, regs.ebx #endif }; if (regs_.err == (unsigned long)-ENOSYS) { //syscall_enter stop if (regs_.syscall == __NR_open) { std::string file_name; long word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL); char * tmp = (char *)&word; while (*tmp != '\0') { file_name.push_back(*tmp); ++tmp; if (tmp == (char *)(&word + 1)) { regs_.arg0 += sizeof(word); word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL); tmp = (char *)&word; } } { std::lock_guard<std::mutex> l(mutex); files.push_back(file_name); } } } else { //syscall_exit stop } } } }
static int do_test (void) { int result = 0; char tmpfname[] = "/tmp/tst-mqueue5-barrier.XXXXXX"; int fd = mkstemp (tmpfname); if (fd == -1) { printf ("cannot open temporary file: %m\n"); return 1; } /* Make sure it is always removed. */ unlink (tmpfname); /* Create one page of data. */ size_t ps = sysconf (_SC_PAGESIZE); char data[ps]; memset (data, '\0', ps); /* Write the data to the file. */ if (write (fd, data, ps) != (ssize_t) ps) { puts ("short write"); return 1; } void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { printf ("mmap failed: %m\n"); return 1; } pthread_barrier_t *b2; b2 = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t)) & ~(__alignof (pthread_barrier_t) - 1)); pthread_barrier_t *b3; b3 = b2 + 1; pthread_barrierattr_t a; if (pthread_barrierattr_init (&a) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed, could not test"); return 0; } if (pthread_barrier_init (b2, &a, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrier_init (b3, &a, 3) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&a) != 0) { puts ("barrierattr_destroy failed"); return 1; } char name[sizeof "/tst-mqueue5-" + sizeof (pid_t) * 3]; snprintf (name, sizeof (name), "/tst-mqueue5-%u", getpid ()); struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 }; mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr); if (q == (mqd_t) -1) { printf ("mq_open failed with: %m\n"); return result; } else add_temp_mq (name); struct sigevent ev; memset (&ev, 0xaa, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) != 0) { printf ("mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } if (mq_notify (q, &ev) == 0) { puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } result |= mqsend (q); if (mq_notify (q, &ev) != 0) { printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } result |= mqrecv (q); if (mq_notify (q, NULL) != 0) { printf ("mq_notify (q, NULL) failed with: %m\n"); result = 1; } if (mq_notify (q, NULL) != 0) { /* Implementation-defined behaviour, so don't fail, just inform. */ printf ("second mq_notify (q, NULL) failed with: %m\n"); } struct sigaction sa = { .sa_sigaction = rtmin_handler, .sa_flags = SA_SIGINFO }; sigemptyset (&sa.sa_mask); sigaction (SIGRTMIN, &sa, NULL); memset (&ev, 0x55, sizeof (ev)); ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = SIGRTMIN; ev.sigev_value.sival_int = 26; if (mq_notify (q, &ev) != 0) { printf ("mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } ev.sigev_value.sival_ptr = &ev; if (mq_notify (q, &ev) == 0) { puts ("second mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("second mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } if (rtmin_cnt != 0) { puts ("SIGRTMIN signal caught too early"); result = 1; } result |= mqsend (q); if (rtmin_cnt != 1) { puts ("SIGRTMIN signal did not arrive"); result = 1; } else if (rtmin_pid != getpid () || rtmin_uid != getuid () || rtmin_code != SI_MESGQ || rtmin_sigval.sival_int != 26) { printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (26)\n", rtmin_pid, getpid (), rtmin_uid, getuid (), rtmin_code, SI_MESGQ, rtmin_sigval.sival_int); result = 1; } ev.sigev_value.sival_int = 75; if (mq_notify (q, &ev) != 0) { printf ("third mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } result |= mqrecv (q); if (mq_notify (q, NULL) != 0) { printf ("mq_notify (q, NULL) failed with: %m\n"); result = 1; } memset (&ev, 0x33, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) != 0) { printf ("fourth mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } pid_t pid = fork (); if (pid == -1) { printf ("fork () failed: %m\n"); mq_unlink (name); return 1; } if (pid == 0) do_child (name, b2, b3, q); /* Child unsuccessfully attempts to mq_notify. */ (void) pthread_barrier_wait (b2); result |= mqsend (q); (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify SIGEV_SIGNAL now. */ result |= mqrecv (q); (void) pthread_barrier_wait (b2); memset (&ev, 0xbb, sizeof (ev)); ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = SIGRTMIN; ev.sigev_value.sival_int = 15; if (mq_notify (q, &ev) == 0) { puts ("fourth mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("fourth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } result |= mqsend (q); if (mq_notify (q, &ev) != 0) { printf ("fifth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } if (rtmin_cnt != 1) { puts ("SIGRTMIN signal caught too early"); result = 1; } result |= mqrecv (q); (void) pthread_barrier_wait (b2); /* Child verifies caught SIGRTMIN signal. */ /* Child calls mq_send (q) which triggers SIGRTMIN signal here. */ (void) pthread_barrier_wait (b2); /* Child mq_open's another mqd_t for the same queue (q2). */ if (rtmin_cnt != 2) { puts ("SIGRTMIN signal did not arrive"); result = 1; } else if (rtmin_pid != pid || rtmin_uid != getuid () || rtmin_code != SI_MESGQ || rtmin_sigval.sival_int != 15) { printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (15)\n", rtmin_pid, pid, rtmin_uid, getuid (), rtmin_code, SI_MESGQ, rtmin_sigval.sival_int); result = 1; } result |= mqrecv (q); (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q2. */ (void) pthread_barrier_wait (b2); memset (&ev, 0xbb, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) == 0) { puts ("fifth mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("fifth mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child calls mq_close on q2, which makes the queue available again for notification. */ mqd_t q3 = mq_open (name, O_RDWR); if (q3 == (mqd_t) -1) { printf ("mq_open q3 in parent failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); memset (&ev, 0x12, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q3, &ev) != 0) { printf ("mq_notify (q3, { SIGEV_NONE }) failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child unsuccessfully attempts to mq_notify { SIGEV_SIGNAL } on q. */ (void) pthread_barrier_wait (b2); if (mq_close (q3) != 0) { printf ("mq_close failed: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify { SIGEV_NONE } on q. */ /* Child successfully calls mq_notify NULL on q. */ (void) pthread_barrier_wait (b2); /* Child creates new thread. */ /* Thread blocks on mqrecv (q). */ /* Child sleeps for 1sec so that thread has time to reach that point. */ /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q. */ (void) pthread_barrier_wait (b2); result |= mqsend (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ (void) pthread_barrier_wait (b3); result |= mqsend (q); (void) pthread_barrier_wait (b3); /* Thread verifies SIGRTMIN has been caught. */ /* Thread calls mq_notify (q, { SIGEV_NONE }) to verify notification is now available for registration. */ /* Thread calls mq_notify (q, NULL). */ (void) pthread_barrier_wait (b3); /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread calls mq_notify (q, NULL). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread opens a new O_RDONLY mqd_t (q4). */ /* Thread calls mq_notify (q4, NULL). */ /* Thread calls mq_close (q4). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread opens a new O_WRONLY mqd_t (q5). */ /* Thread calls mq_notify (q5, NULL). */ /* Thread calls mq_close (q5). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("waitpid failed"); kill (pid, SIGKILL); result = 1; } else if (!WIFEXITED (status) || WEXITSTATUS (status)) { printf ("child failed with status %d\n", status); result = 1; } if (mq_unlink (name) != 0) { printf ("mq_unlink failed: %m\n"); result = 1; } if (mq_close (q) != 0) { printf ("mq_close failed: %m\n"); result = 1; } if (mq_notify (q, NULL) == 0) { puts ("mq_notify on closed mqd_t unexpectedly succeeded"); result = 1; } else if (errno != EBADF) { printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n"); result = 1; } memset (&ev, 0x55, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) == 0) { puts ("mq_notify on closed mqd_t unexpectedly succeeded"); result = 1; } else if (errno != EBADF) { printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n"); result = 1; } return result; }
static void __init check_sysemu(void) { unsigned long regs[MAX_REG_NR]; int pid, n, status, count=0; non_fatal("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; pid = start_ptraced_child(); if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) fatal_perror("check_sysemu : wait failed"); if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) fatal("check_sysemu : expected SIGTRAP, got status = %d\n", status); if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) fatal_perror("check_sysemu : PTRACE_GETREGS failed"); if (PT_SYSCALL_NR(regs) != __NR_getpid) { non_fatal("check_sysemu got system call number %d, " "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); goto fail; } n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); goto fail; } if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; non_fatal("OK\n"); set_using_sysemu(!force_sysemu_disabled); non_fatal("Checking advanced syscall emulation patch for ptrace..."); pid = start_ptraced_child(); if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed"); while (1) { count++; if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) fatal_perror("check_sysemu: wait failed"); if (WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))) { if (!count) { non_fatal("check_sysemu: SYSEMU_SINGLESTEP " "doesn't singlestep"); goto fail; } n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) fatal_perror("check_sysemu : failed to modify " "system call return"); break; } else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; else { non_fatal("check_sysemu: expected SIGTRAP or " "(SIGTRAP | 0x80), got status = %d\n", status); goto fail; } } if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; non_fatal("OK\n"); if (!force_sysemu_disabled) set_using_sysemu(sysemu_supported); return; fail: stop_ptraced_child(pid, 1, 0); fail_stopped: non_fatal("missing\n"); }
static int basic_test(void) { pid_t pid; int fd, sem_id, status, ret = 0; unsigned long i, j, chunk_no = 0, num_chunks = 0; struct write_unit wu; sem_id = semaphore_init(1); if (sem_id < 0) return sem_id; num_chunks = file_size / CHUNK_SIZE; open_rw_flags |= O_DIRECT; open_ro_flags |= O_DIRECT; if (test_flags & BASC_TEST) { fprintf(stdout, "# Prepare file in %lu length.\n", file_size); ret = prep_orig_file_in_chunks(workfile, file_size); if (ret) return ret; } fflush(stderr); fflush(stdout); signal(SIGCHLD, sigchld_handler); fd = open_file(workfile, open_rw_flags); if (fd < 0) return fd; if (test_flags & FIHL_TEST) { fprintf(stdout, "# Reserve a hole by truncating file to %lu.\n", file_size); ret = ftruncate(fd, file_size); if (ret) { ret = errno; fprintf(stderr, "ftruncate faile:%d,%s\n", ret, strerror(ret)); return ret; } } fprintf(stdout, "# Fork %lu processes performing writes.\n", num_children); for (i = 0; i < num_children; i++) { pid = fork(); if (pid < 0) { fprintf(stderr, "Fork process error!\n"); return pid; } if (pid == 0) { srand(getpid()); for (j = 0; j < num_chunks; j++) { if (verbose) fprintf(stdout, " #%d process writes " "#%lu chunk\n", getpid(), chunk_no); if (semaphore_p(sem_id) < 0) { ret = -1; goto child_bail; } if (test_flags & APPD_TEST) chunk_no = j; else chunk_no = get_rand_ul(0, num_chunks - 1); prep_rand_dest_write_unit(&wu, chunk_no); ret = do_write_chunk(fd, wu); if (ret < 0) goto child_bail; ret = log_write(&wu, log); if (ret < 0) goto child_bail; if (semaphore_v(sem_id) < 0) { ret = -1; goto child_bail; } usleep(10000); if (!(test_flags & DSCV_TEST)) continue; /* * Are you ready to crash the machine? */ if ((j > 1) && (j < num_chunks - 1)) { if (get_rand_ul(1, num_chunks) == num_chunks / 2) { if (semaphore_p(sem_id) < 0) { ret = -1; goto child_bail; } fprintf(stdout, "#%d process " "tries to crash the " "box.\n", getpid()); if (system("echo b>/proc/sysrq-trigger") < 0) { fprintf(stderr, "#%d process " "tries to enable sysrq-trigger " "but failed.\n", getpid()); goto child_bail; } } } else if (j == num_chunks - 1) { if (semaphore_p(sem_id) < 0) { ret = -1; goto child_bail; } fprintf(stdout, "#%d process " "tries to crash the " "box.\n", getpid()); if (system("echo b>/proc/sysrq-trigger") < 0) { fprintf(stderr, "#%d process " "tries to enable sysrq-trigger " "but failed.\n", getpid()); goto child_bail; } } } child_bail: if (fd) close(fd); if (ret > 0) ret = 0; exit(ret); } if (pid > 0) child_pid_list[i] = pid; } signal(SIGINT, sigint_handler); signal(SIGTERM, sigterm_handler); for (i = 0; i < num_children; i++) { waitpid(child_pid_list[i], &status, 0); ret = WEXITSTATUS(status); if (ret) { fprintf(stderr, "Child %d exits abnormally with " "RC=%d\n", child_pid_list[i], ret); } } if (fd) close(fd); if (sem_id) semaphore_close(sem_id); return ret; }
RTR3DECL(int) RTProcWaitNoResume(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus) { /* * Validate input. */ if (Process <= 0) { AssertMsgFailed(("Invalid Process=%d\n", Process)); return VERR_INVALID_PARAMETER; } if (fFlags & ~(RTPROCWAIT_FLAGS_NOBLOCK | RTPROCWAIT_FLAGS_BLOCK)) { AssertMsgFailed(("Invalid flags %#x\n", fFlags)); return VERR_INVALID_PARAMETER; } /* * Perform the wait. */ int iStatus = 0; int rc = waitpid(Process, &iStatus, fFlags & RTPROCWAIT_FLAGS_NOBLOCK ? WNOHANG : 0); if (rc > 0) { /* * Fill in the status structure. */ if (pProcStatus) { if (WIFEXITED(iStatus)) { pProcStatus->enmReason = RTPROCEXITREASON_NORMAL; pProcStatus->iStatus = WEXITSTATUS(iStatus); } else if (WIFSIGNALED(iStatus)) { pProcStatus->enmReason = RTPROCEXITREASON_SIGNAL; pProcStatus->iStatus = WTERMSIG(iStatus); } else { Assert(!WIFSTOPPED(iStatus)); pProcStatus->enmReason = RTPROCEXITREASON_ABEND; pProcStatus->iStatus = iStatus; } } return VINF_SUCCESS; } /* * Child running? */ if (!rc) { Assert(fFlags & RTPROCWAIT_FLAGS_NOBLOCK); return VERR_PROCESS_RUNNING; } /* * Figure out which error to return. */ int iErr = errno; if (iErr == ECHILD) return VERR_PROCESS_NOT_FOUND; return RTErrConvertFromErrno(iErr); }
static int execute_normally(command_t c){ switch (c->type) { case AND_COMMAND: { if(execute_normally(c->u.command[0])) { return execute_normally(c->u.command[1]); } else //left side failed return 0; } case SEQUENCE_COMMAND: { int temp_ = 0; if(!execute_normally(c->u.command[0])) { temp_++; } if(!execute_normally(c->u.command[1])) { temp_++; } return !temp_; } case OR_COMMAND: { if(execute_normally(c->u.command[0])) { return 1; } else //left side failed return execute_normally(c->u.command[1]); } case PIPE_COMMAND: { pid_t p1 =fork(); if(p1==0) {//child int fd[2]; if(pipe(fd)<0) error(FAIL, 0, "Failed to create pipe."); //printf("%s | %s\n", left, right); pid_t p = fork(); if(p==0) { //child close(fd[0]); //close fd thats not being used dup2(fd[1], 1); //duplicate fd1 to stdout close(fd[1]); if(!execute_normally(c->u.command[0])) { exit(FAIL); } exit(1); } else { //parent process close(fd[1]); dup2(fd[0], 0); //duplicate fd0 to stdin close(fd[0]); //check for error int status; if(waitpid(p, &status, 0)<0) { exit(FAIL); } if(WEXITSTATUS(status) == FAIL ) { kill(p, SIGKILL); exit(FAIL); } kill(p, SIGKILL); //printf("%s\n", right); //execute command char* term = strtok(*(c->u.command[1]->u.word), " "); char* file = term; char* arr[100]; int i = 0; while(term!=NULL) { arr[i] = term; term = strtok(NULL, " "); i++; } arr[i]=NULL; //sleep(1); execvp(file, arr); error(FAIL, 0, "Failed on pipe command: |%s", *(c->u.command[1]->u.word) ); exit(FAIL); } exit(1); } else { //grandparent //check for error int status; if(waitpid(p1, &status, 0)<0) { return 0; } if(WEXITSTATUS(status) == FAIL ) { kill(p1, SIGKILL); return 0; } kill(p1, SIGKILL); return 1; } } case SIMPLE_COMMAND: { //execute c->u.word which is a char ** return execute(*c->u.word, c->input, c->output); } case SUBSHELL_COMMAND: { pid_t sp = fork(); if(sp == 0){ int fp = -1; if(c->input != NULL) { int fd = open(c->input, O_RDONLY); if(fd < 0) { error(0, 0, "Failed to open file: %s\n", c->input); _exit(FAIL); } dup2(fd, 0); } if(c->output != NULL) { fp = open(c->output, O_WRONLY | O_CREAT | O_TRUNC, 0666); if(fp < 0) { error(0, 0, "Failed to open file: %s\n", c->output); _exit(FAIL); } dup2(fp, 1); } if(0 == execute_normally(c->u.subshell_command)){ _exit(FAIL); } else { _exit(987); } } else{ int status; if(waitpid(sp, &status, 0)<0) return 0; if(WEXITSTATUS(status) == FAIL){ kill(sp, SIGKILL); return 0; } kill(sp, SIGKILL); return 1; } } default: abort (); } // if (c->input) // printf ("<%s", c->input); // if (c->output) // printf (">%s", c->output); return 1; }
int execute(char* command, char* input, char* output) { if(command == NULL) { return 0; } char* term = strtok(command, " "); int orig = dup(1); int fp = -1, fd = -1; if(input != NULL) { fd = open(input, O_RDONLY); if(fd < 0) { close(fd); error(0, 0, "Failed to open file: %s\n", input); return 0; } dup2(fd, 0); } if(output != NULL) { fp = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666); if(fp < 0) { close(fp); error(0, 0, "Failed to open file: %s\n", output); return 0; } dup2(fp, 1); } pid_t p = 0; char temp[5]; strncpy(temp, command,4); temp[4] = '\0'; //check if it is an exec command if(0 != strcmp("exec",temp)){ p = fork(); } if(p==0){ //child char* arr[100]; int i = 0; while(term!=NULL) { if(i == 0 && 0 == strcmp(term, "exec")){ } else{ arr[i] = term; i++; } term = strtok(NULL, " "); } arr[i]=NULL; if(strncmp(arr[0], "false", 5)==0) exit(FAIL); execvp(arr[0], arr); error(FAIL, 0, "Command failed: %s", command); exit(FAIL); } else{ if(input != NULL && fd>0) { dup2(orig, 1); close(fd); } if(output != NULL && fp>0) { dup2(orig, 1); close(fp); } int status; if(waitpid(p, &status, 0)<0) { return 0; } if(WEXITSTATUS(status) == FAIL ) { kill(p, SIGKILL); return 0; } kill(p,SIGKILL); return 1; } return 0; }
int runRedirector(pid_t *pid_return, int *read_fd_return, int *write_fd_return) { int rc, rc2, status; pid_t pid; int filedes1[2], filedes2[2]; sigset_t ss, old_mask; assert(redirector); if(redirector_buffer == NULL) { redirector_buffer = malloc(REDIRECTOR_BUFFER_SIZE); if(redirector_buffer == NULL) return -errno; } rc = pipe(filedes1); if(rc < 0) { rc = -errno; goto fail1; } rc = pipe(filedes2); if(rc < 0) { rc = -errno; goto fail2; } fflush(stdout); fflush(stderr); flushLog(); interestingSignals(&ss); do { rc = sigprocmask(SIG_BLOCK, &ss, &old_mask); } while (rc < 0 && errno == EINTR); if(rc < 0) { rc = -errno; goto fail3; } pid = fork(); if(pid < 0) { rc = -errno; goto fail4; } if(pid > 0) { do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while(rc < 0 && errno == EINTR); if(rc < 0) { rc = -errno; goto fail4; } rc = setNonblocking(filedes1[1], 1); if(rc >= 0) rc = setNonblocking(filedes2[0], 1); if(rc < 0) { rc = -errno; goto fail4; } /* This is completely unnecesary -- if the redirector cannot be started, redirectorStreamHandler1 will get EPIPE straight away --, but it improves error messages somewhat. */ rc = waitpid(pid, &status, WNOHANG); if(rc > 0) { logExitStatus(status); rc = -EREDIRECTOR; goto fail4; } else if(rc < 0) { rc = -errno; goto fail4; } *read_fd_return = filedes2[0]; *write_fd_return = filedes1[1]; *pid_return = pid; /* This comes at the end so that the fail* labels can work */ close(filedes1[0]); close(filedes2[1]); } else { close(filedes1[1]); close(filedes2[0]); uninitEvents(); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if(rc < 0) exit(142); if(filedes1[0] != 0) dup2(filedes1[0], 0); if(filedes2[1] != 1) dup2(filedes2[1], 1); execlp(redirector->string, redirector->string, NULL); exit(142); /* NOTREACHED */ } return 1; fail4: do { rc2 = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while(rc2 < 0 && errno == EINTR); fail3: close(filedes2[0]); close(filedes2[1]); fail2: close(filedes1[0]); close(filedes1[1]); fail1: free(redirector_buffer); redirector_buffer = NULL; return rc; }
int mu_progmailer_send (struct _mu_progmailer *pm, mu_message_t msg) { int status; mu_stream_t stream = NULL; char buffer[512]; size_t len = 0; int rc; mu_header_t hdr; mu_body_t body; int found_nl = 0; int exit_status; if (!pm || !msg) return EINVAL; mu_message_get_header (msg, &hdr); status = mu_header_get_streamref (hdr, &stream); if (status) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("cannot get header stream: %s", mu_strerror (status))); return status; } mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending headers...")); mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); while ((status = mu_stream_readline (stream, buffer, sizeof (buffer), &len)) == 0 && len != 0) { if (mu_c_strncasecmp (buffer, MU_HEADER_FCC, sizeof (MU_HEADER_FCC) - 1)) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_PROT, ("Header: %s", buffer)); if (write (pm->fd, buffer, len) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s", strerror (status))); break; } } found_nl = (len == 1 && buffer[0] == '\n'); } if (!found_nl) { if (write (pm->fd, "\n", 1) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s", strerror (status))); } } mu_stream_destroy (&stream); mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending body...")); mu_message_get_body (msg, &body); status = mu_body_get_streamref (body, &stream); if (status) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("cannot get body stream: %s\n", mu_strerror (status))); return status; } mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); while ((status = mu_stream_read (stream, buffer, sizeof (buffer), &len)) == 0 && len != 0) { if (write (pm->fd, buffer, len) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s\n", strerror (status))); break; } } mu_body_get_streamref (body, &stream); close (pm->fd); rc = waitpid (pm->pid, &exit_status, 0); if (status == 0) { if (rc < 0) { if (errno == ECHILD) status = 0; else { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("waitpid(%lu) failed: %s\n", (unsigned long) pm->pid, strerror (status))); } } else if (WIFEXITED (exit_status)) { exit_status = WEXITSTATUS (exit_status); mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("%s exited with: %d\n", pm->command, exit_status)); status = (exit_status == 0) ? 0 : MU_ERR_PROCESS_EXITED; } else if (WIFSIGNALED (exit_status)) status = MU_ERR_PROCESS_SIGNALED; else status = MU_ERR_PROCESS_UNKNOWN_FAILURE; } pm->pid = -1; return status; }
/* ** Implement an HTTP server daemon. */ HttpRequest* http_server(struct in_addr address, int iPort) { int listener; /* The server socket */ int connection; /* A socket for each connection */ fd_set readfds; /* Set of file descriptors for select() */ socklen_t lenaddr; /* Length of the inaddr structure */ int child; /* PID of the child process */ int nchildren = 0; /* Number of child processes */ struct timeval delay; /* How long to wait inside select() */ struct sockaddr_in inaddr; /* The socket address */ int reuse = 1; int n = 0; char url_prefix[256]; int val; //not used /* catch SIGINT */ (void) signal(SIGINT, sigint); /* catch SIGTERM */ (void) signal(SIGTERM, sigterm); memset(&inaddr, 0, sizeof(inaddr)); inaddr.sin_family = AF_INET; inaddr.sin_addr.s_addr = address.s_addr; inaddr.sin_port = htons(iPort); listener = socket(AF_INET, SOCK_STREAM, 0); fprintf(stderr,"DidiWiki firing up ...\n"); if( listener < 0 ) { fprintf(stderr,"Can't create a socket\n"); exit(1); } #ifdef SO_REUSEADDR setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); #endif while (n < 10) { fprintf(stderr,"Attempting to bind to %s:%i .. ", inet_ntoa(address), iPort); inaddr.sin_port = htons(iPort + n); if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr)) < 0 ) { fprintf(stderr,"Failed! \n"); n++; continue; } fprintf(stderr,"Success! \n"); break; } if (n == 10) { fprintf(stderr,"Can't bind to any ports, giving up.\n"); exit(1); } fprintf(stderr,"DidiWiki Started. Please point your browser at %s:%i\n", inet_ntoa(address), iPort); /* log starting information */ openlog("didiwiki", 0, 0); syslog(LOG_LOCAL0|LOG_INFO, "started with PID %d", getpid()); /* Set DIDIWIKI_URL_PREFIX if not already set - rss uses it */ snprintf(url_prefix, 256, "%s:%i/", inet_ntoa(address), iPort+n); setenv("DIDIWIKI_URL_PREFIX", url_prefix , 0); listen(listener,10); /* Listen undefinitely */ while( 1 ) { if( nchildren>MAX_PARALLEL ) { /* Slow down if connections are arriving too fast */ sleep( nchildren-MAX_PARALLEL ); } delay.tv_sec = 60; delay.tv_usec = 0; FD_ZERO(&readfds); FD_SET( listener, &readfds); if( select( listener+1, &readfds, 0, 0, &delay) ) { lenaddr = sizeof(inaddr); connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr); if( connection>=0 ) { child = fork(); if( child!=0 ) { if( child>0 ) nchildren++; close(connection); } else { /* *child*, connect stdin/out to socket */ /* then return req object for caller to handle */ close(0); val = dup(connection); close(1); val = dup(connection); close(2); val = dup(connection); close(connection); return http_request_new(); } } } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ) nchildren--; } /* NOT REACHED */ exit(1); }
void do_command(int sum,char arglist[100][256]) //执行命令 { int flag =0; //若flag>1,说明命令中含多个>,<,|或格式不正确 int how=0; //记录命令中是否含有>,<,| int background=0; //记录命令中是否有& pid_t pid; int fd; int i; char* file; //记录文件名 char** arg; //记录命令 char** argnext; // 记录管道命令 arg=(char**)malloc(sizeof(char*)*(sum+1)); argnext=(char**)malloc(sizeof(char*)*(sum+1)); for(i=0;i<sum;i++) //将命令取出 arg[i]=arglist[i]; arg[i]=NULL; if(strcmp(arg[0],"cd")==0) //判断是否cd命令 { cd_command(arg); return; } if(strcmp(arg[0],"ls")==0) //给ls命令默认设置为--color=auto { i=0; while(arg[i]!=NULL) i++; if(strcmp(arg[i-1],"&")==0) { arg[i-1]="--color=auto"; arg[i]="&"; arg[i+1]=NULL; } else { arg[i]="--color=auto"; arg[++i]=NULL; } } for(i=0;arg[i]!=NULL;i++) //判断是否含有& { if(strcmp(arg[i],"&")==0) { if(arg[i+1]!=NULL&&strcmp(arg[0],"ls")!=0) { printf("wrong command\n"); return; } else { background=1; arg[i]=NULL; break; } } } for(i=0;arg[i]!=NULL;i++) //判断是否有>,<,| { if(strcmp(arg[i],">")==0) { flag++; how=out_redirect; if(i==0) flag++; if(i==sum-1) flag++; } if(strcmp(arg[i],"<")==0) { flag++; how=in_redirect; if(i==0) flag++; if(i==sum-1) flag++; } if(strcmp(arg[i],"|")==0) { flag++; how=have_pipe; if(i==0) flag++; if(arg[i+1]==NULL) flag++; } } if(flag>1) { printf("wrong command\n"); return; } if(how==out_redirect) { for(i=0;arg[i]!=NULL;i++) if(strcmp(arg[i],">")==0) break; file=arg[i+1]; arg[i]=NULL; } if(how==in_redirect) { for(i=0;arg[i]!=NULL;i++) if(strcmp(arg[i],"<")==0) break; file=arg[i+1]; arg[i]=NULL; } if(how==have_pipe) { for(i=0;arg[i]!=NULL;i++) if(strcmp(arg[i],"|")==0) break; arg[i]=NULL; int j=i+1; for(j;arg[j]!=NULL;j++) argnext[j-i-1]=arg[j]; argnext[j-i-1]=arg[j]; } if((pid=fork())<0) { printf("creat process error \n"); return; } switch(how) { case normal: if(pid==0) { if(!find_command(arg[0])) { printf("未找到'%s'命令\n",arg[0]); exit(1); } execvp(arg[0],arg); exit(0); } break; case out_redirect: if(pid==0) { if(!find_command(arg[0])) { printf("未找到'%s'命令\n",arg[0]); exit(1); } if((fd=open(file,O_RDWR|O_CREAT|O_TRUNC,0644))==-1) { printf("creat file error\n"); exit(1); } if (dup2(fd,1) < 0) { perror("dup2"); } if(execvp(arg[0],arg)==-1) { printf("do command error\n"); exit(1); } exit(0); } break; case in_redirect: if(pid==0) { if(!find_command(arg[0])) { printf("未找到'%s'命令\n",arg[0]); exit(1); } if((fd=open(file,O_RDWR))==-1) { printf("read file error\n"); exit(1); } dup2(fd,0); execvp(arg[0],arg); exit(0); } break; case have_pipe: if(pid==0) { int pid2; int fd2; if((pid2=fork())<0) { printf("fork2 error\n"); exit(1); } if(pid2==0) { if(!find_command(arg[0])) { printf("未找到'%s'命令\n",arg[0]); return; } if((fd2=open("/tmp/temp.txt",O_RDWR|O_CREAT|O_TRUNC,0644))==-1) { printf("open dir error\n"); exit(0); } dup2(fd2,1); execvp(arg[0],arg); exit(0); } if(waitpid(pid2,NULL,0)==-1) printf("wait for child process error\n"); if(!find_command(argnext[0])) { printf("未找到命令'%s'\n",argnext[0]); return; } if((fd=open("/tmp/temp.txt",O_RDONLY))==-1) printf("open file error\n"); dup2(fd,0); execvp(argnext[0],argnext); exit(0); } default: break; } if(background) { printf("[process id %d]\n",pid); return; } else if(waitpid(pid,NULL,0)==-1) { printf("wait for child process error\n"); return; } }
static void run_monitored(char *executable, int argc, char **argv) { int pid; const char *t = getenv("KLEE_REPLAY_TIMEOUT"); if (!t) t = "10000000"; monitored_timeout = atoi(t); if (monitored_timeout==0) { fprintf(stderr, "ERROR: invalid timeout (%s)\n", t); _exit(1); } /* Kill monitored process(es) on SIGINT and SIGTERM */ signal(SIGINT, int_handler); signal(SIGTERM, int_handler); signal(SIGALRM, timeout_handler); pid = fork(); if (pid < 0) { perror("fork"); _exit(66); } else if (pid == 0) { /* This process actually executes the target program. * * Create a new process group for pid, and the process tree it may spawn. We * do this, because later on we might want to kill pid _and_ all processes * spawned by it and its descendants. */ setpgrp(); if (!rootdir) { execv(executable, argv); perror("execv"); _exit(66); } fprintf(stderr, "rootdir: %s\n", rootdir); const char *msg; if ((msg = "chdir", chdir(rootdir) == 0) && (msg = "chroot", chroot(rootdir) == 0)) { msg = "execv"; executable = strip_root_dir(executable, rootdir); argv[0] = strip_root_dir(argv[0], rootdir); execv(executable, argv); } perror(msg); _exit(66); } else { /* Parent process which monitors the child. */ int res, status; time_t start = time(0); sigset_t masked; sigemptyset(&masked); sigaddset(&masked, SIGALRM); monitored_pid = pid; alarm(monitored_timeout); do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); if (res < 0) { perror("waitpid"); _exit(66); } /* Just in case, kill the process group of pid. Since we called setpgrp() for pid, this will not kill us, or any of our ancestors */ kill(-pid, SIGKILL); process_status(status, time(0) - start, 0); } }
int doXferRcp(lsRcpXfer *lsXfer, int option ) { pid_t pid; int rcpp[2], sourceFh; char errMsg[1024]; char szRshDest[MAXLINELEN]; int cc, i, local_errno, n, status; char fname[]="doXferRcp"; if ( (lsXfer->iOptions & O_APPEND) || ( option & SPOOL_BY_LSRCP) ) { if (logclass & (LC_FILE)) ls_syslog(LOG_DEBUG, "%s: using %s to copy '%s' to '%s'", fname, RSHCMD, lsXfer->ppszHostFnames[0], lsXfer->ppszDestFnames[0]); if (pipe(rcpp) < 0) { return -1; } switch(pid = fork()) { case 0: close(rcpp[0]); if (rcpp[1]) { if (logclass & (LC_FILE)) ls_syslog(LOG_DEBUG, "%s: child: re-directing stdout, stderr", fname); close(STDOUT_FILENO); close(STDERR_FILENO); if (dup2(rcpp[1],STDOUT_FILENO) < 0) return -1; if (dup2(rcpp[1],STDERR_FILENO) < 0) return -1; close(rcpp[1]); } if ((sourceFh = open(lsXfer->ppszHostFnames[0], O_RDONLY, 0)) < 0) { return -1; } else { close(STDIN_FILENO); if (dup2(sourceFh,STDIN_FILENO)) return -1; close(sourceFh); } if ( ( option & SPOOL_BY_LSRCP ) ) { sprintf(szRshDest, "cat > %s",lsXfer->ppszDestFnames[0]); } else { sprintf(szRshDest, "cat >>! %s",lsXfer->ppszDestFnames[0]); } execlp(RSHCMD, RSHCMD, lsXfer->szDest, szRshDest, NULL); return -1; break; case -1: if (logclass & (LC_FILE)) ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"fork" ); close(rcpp[0]); close(rcpp[1]); return -1; default: close(rcpp[1]); cc = read(rcpp[0], errMsg, 1024); for (i = cc; cc > 0;) { cc = read(rcpp[0], errMsg+i, 1024-i); if (cc > 0) i += cc; } local_errno = errno; close(rcpp[0]); if (waitpid(pid, 0, 0) < 0 && errno != ECHILD) { return -1; } if (cc < 0) { fprintf(stderr, "%s\n", strerror(local_errno)); return -1; } if (i > 0) { fprintf(stderr, "%s: %s", RSHCMD, errMsg); return -1; } return 0; } } else { if (logclass & (LC_FILE)) ls_syslog(LOG_DEBUG,"doXferRcp(), exec rcp"); switch(pid = fork()) { case 0: execlp("rcp", "rcp","-p", lsXfer->szSourceArg, lsXfer->szDestArg, NULL); ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"execlp" ); exit(-1); break; case -1: if (logclass & (LC_FILE)) ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"fork" ); return -1; break; default: while ( (n = wait(&status)) < 0) { if (errno != EINTR) break; } if (WIFEXITED(status)) { if ( WEXITSTATUS(status) == 0) return 0; } return -1; } return -1; } }
int main(void) { #ifdef _POSIX_MEMORY_PROTECTION char tmpfname[256]; void *pa; size_t size = 1024; int fd; pid_t child; int status; int sig_num; snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_6_1_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf("Error at open(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } unlink(tmpfname); child = fork(); switch (child) { case 0: if (ftruncate(fd, size) == -1) { printf("Error at ftruncate(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } pa = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (pa == MAP_FAILED) { printf("Error at mmap: %s\n", strerror(errno)); return PTS_FAIL; } *(char *)pa = 'b'; return 0; break; case -1: printf("Error at fork(): %s\n", strerror(errno)); return PTS_UNRESOLVED; break; default: break; } waitpid(child, &status, WUNTRACED); close(fd); if (WIFSIGNALED(status)) { sig_num = WTERMSIG(status); printf("Child process terminated by signal %d\n", sig_num); if (sig_num == SIGSEGV) { printf("Got SIGSEGV when writing to the mapped memory, " "without setting PROT_WRITE\n" "Test PASSED\n"); return PTS_PASS; } } if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 0) { printf("Did not got SIGSEGV when writing to the mapped memory," " without setting PROT_WRITE\n" "Test FAILED\n"); return PTS_FAIL; } } printf("Test Unresolved\n"); return PTS_UNRESOLVED; #else printf("Test Unsupported, _POSIX_MEMORY_PROTECTION not defined\n"); return PTS_UNSUPPORTED; #endif }
bool Process::Wait() { pid_t pid = waitpid(m_pid, &m_status, 0); return (pid != m_pid); }
void execute(char *cmdline, char **argv) { char *cmd = cmdline; if(strlen(cmd) > 4) { if(strncmp(cmd, "res=", 4)==0) { point5(cmdline); return; } } if(strlen(cmdline)<=0) return; // 0 for stdout; 1 for redirect; 2 for pipeline int out_type = 0; char *childcmd[2]; childcmd[0] = cmdline; while(*cmdline != '>' && *cmdline != '|' && *cmdline != '$' && *cmdline != '\0' && *cmdline != '\n') { cmdline++; } if(*cmdline=='>') { out_type = 1; *cmdline++ = '\0'; childcmd[1] = cmdline; } else if(*cmdline=='|') { out_type = 2; *cmdline++ = '\0'; childcmd[1] = cmdline; } else if(*cmdline=='$') { if(strncmp(cmdline, "$(", 2)==0) { out_type = 3; *cmdline++ = '\0'; childcmd[1] = cmdline; } } int n = strlen(childcmd[0]) - 1; while(n>0) { if(childcmd[0][n]==' ') { childcmd[0][n]='\0'; } else break; n--; } while(*childcmd[1] != '\0') { if(*childcmd[1]==' ') childcmd[1]++; else break; } parse_cmdline(childcmd[0], argv); int ret = handle_builtin(argv); if(ret==0) return; pid_t childpid; int status, options = 0; childpid = fork(); if (childpid == -1) { perror("Cannot proceed. fork() error"); exit(1); } else if (childpid == 0) { // This is child's process. if(out_type==0) { childexec(argv); } else if(out_type==1) {// output redirection here int fd; close(STDOUT); fd = open(childcmd[1], O_APPEND); if(fd<0) { fd = creat(childcmd[1], 0666); if(fd<0) { perror("create file failed"); exit(-1); } } dup(fd); childexec(argv); close(fd); } else if(out_type==2) {// pipeline here int fd[2]; pipe(&fd[0]); if(fork()!=0) { close(fd[0]); close(STDOUT); dup(fd[1]); childexec(argv); close(fd[1]); } else { close(fd[1]); close(STDIN); dup(fd[0]); parse_cmdline(childcmd[1], argv); childexec(argv); close(fd[0]); } puts("\n"); } else if(out_type==3) { childcmd[1]++; size_t len = strlen(childcmd[1]); childcmd[1][len-1] = '\0'; printf("childcmd[0]:%s\n", childcmd[0]); printf("childcmd[1]:%s\n", childcmd[1]); int fd[2]; pipe(fd); if(fork()!=0) { close(fd[1]); close(STDIN); dup(fd[0]); childexecline(childcmd[0]); close(fd[0]); } else exec_pipelines(childcmd[1], fd,argv); /* parse_cmdline(childcmd[1], argv); int fd[2]; pipe(&fd[0]); if(fork()!=0) { close(fd[0]); close(STDOUT); dup(fd[1]); childexec(argv); close(fd[1]); } else { close(fd[1]); close(STDIN); dup(fd[0]); parse_cmdline(childcmd[0], argv); childexec(argv); close(fd[0]); } */ puts("\n"); } } else { waitpid(childpid, &status, options); if (!WIFEXITED(status)) printf("Parent: child has not terminated normally.\n"); } }
/* Thread function */ void * threaded(void * arg) { int ret, status; pid_t child, ctl; /* Wait main thread has registered the handler */ ret = pthread_mutex_lock(&mtx); if (ret != 0) { UNRESOLVED(ret, "Failed to lock mutex"); } ret = pthread_mutex_unlock(&mtx); if (ret != 0) { UNRESOLVED(ret, "Failed to unlock mutex"); } /* fork */ child = fork(); if (child == -1) { UNRESOLVED(errno, "Failed to fork"); } /* child */ if (child == 0) { if (nerrors) { FAILED("Errors occured in the child"); } /* We're done */ exit(PTS_PASS); } /* Parent joins the child */ ctl = waitpid(child, &status, 0); if (ctl != child) { UNRESOLVED(errno, "Waitpid returned the wrong PID"); } if (!WIFEXITED(status) || (WEXITSTATUS(status) != PTS_PASS)) { FAILED("Child exited abnormally"); } if (nerrors) { FAILED("Errors occured in the parent (only)"); } /* quit */ return NULL; }
int Unix_ShellCommandReturnsZero(char *comm, int useshell) { int status; pid_t pid; if (!useshell) { /* Build argument array */ } if ((pid = fork()) < 0) { FatalError("Failed to fork new process"); } else if (pid == 0) /* child */ { ALARM_PID = -1; if (useshell) { if (execl(SHELL_PATH, "sh", "-c", comm, NULL) == -1) { CfOut(cf_error, "execl", "Command %s failed", comm); exit(1); } } else { char **argv = ArgSplitCommand(comm); if (execv(argv[0], argv) == -1) { CfOut(cf_error, "execv", "Command %s failed", argv[0]); exit(1); } } } else /* parent */ { # ifndef HAVE_WAITPID pid_t wait_result; # endif ALARM_PID = pid; # ifdef HAVE_WAITPID while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { return -1; } } return (WEXITSTATUS(status) == 0); # else while ((wait_result = wait(&status)) != pid) { if (wait_result <= 0) { CfOut(cf_inform, "wait", " !! Wait for child failed\n"); return false; } } if (WIFSIGNALED(status)) { return false; } if (!WIFEXITED(status)) { return false; } return (WEXITSTATUS(status) == 0); # endif } return false; }
int main(int argc, char *argv[]) { int err, c, status; pid_t pid; unsigned char flags[LastOpt]; struct mntent ent; char *dev, *mntpnt, *opts, *cwd; DIR *cur; if (argc < 3) { errno = EINVAL; AuFin(NULL); } memset(flags, 0, sizeof(flags)); flags[Update] = 1; opts = NULL; /* mount(8) always passes the arguments in this order */ dev = argv[1]; mntpnt = argv[2]; while ((c = getopt(argc - 2, argv + 2, "nvo:")) != -1) { switch (c) { case 'n': flags[Update] = 0; break; case 'v': flags[Verbose] = 1; break; case 'o': opts = optarg; break; case '?': case ':': errno = EINVAL; AuFin("internal error"); } } cur = opendir("."); if (!cur) AuFin("."); err = chdir(mntpnt); if (err) AuFin(mntpnt); cwd = getcwd(NULL, 0); /* glibc */ if (!cwd) AuFin("getcwd"); err = fchdir(dirfd(cur)); if (err) AuFin("fchdir"); closedir(cur); /* ignore */ if (opts) test_opts(opts, flags); if (!flags[Bind] && flags[Update]) { err = access(MTab, R_OK | W_OK); if (err) AuFin(MTab); } if (flags[Remount]) { errno = EINVAL; if (flags[Bind]) AuFin("both of remount and bind are specified"); flags[AuFlush] = test_flush(opts); if (flags[AuFlush]) { err = au_plink(cwd, AuPlink_FLUSH, 1, 1); if (err) AuFin(NULL); } } pid = fork(); if (!pid) { /* actual mount operation */ do_mount(dev, mntpnt, argc, argv, flags); return 0; } else if (pid < 0) AuFin("fork"); err = waitpid(pid, &status, 0); if (err < 0) AuFin("child process"); err = !WIFEXITED(status); if (!err) err = WEXITSTATUS(status); if (!err && !flags[Bind]) { if (flags[Update]) err = au_update_mtab(cwd, flags[Remount], flags[Verbose]); else if (flags[Verbose]) { /* withoug blocking plink */ err = au_proc_getmntent(cwd, &ent); if (!err) au_print_ent(&ent); else AuFin("internal error"); } } return err; }
int scan_cd (_main_data * main_data) { pid_t pid; char **argv; char tmp[MAX_COMMAND_LENGTH]; int null_fd, pty_fd, tty_fd; int return_value; GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL); /* Open a pty */ if (openpty (&pty_fd, &tty_fd, NULL, NULL, NULL)) { err_handler (GTK_WINDOW(main_window), PTY_OPEN_ERR, NULL); return -1; } /* Open /dev/null */ if ((null_fd = open ("/dev/null", O_WRONLY)) < 0) { err_handler (GTK_WINDOW(main_window), NULL_OPEN_ERR, NULL); return -1; } /* Create argvs */ sprintf (tmp, "%s -Q", (char *) config_read (CONF_RPR_RIPPER)); if ((argv = create_argv_for_execution_using_shell (tmp)) == NULL) return -1; /* Fork */ if ((pid = fork ()) < 0) { err_handler (GTK_WINDOW(main_window), FORK_ERR, NULL); return -1; } if (pid == 0) { int stderr_fd; /* This code will be excuted in the child process */ /* Save stderr before attaching to the tty */ stderr_fd = dup (2); dup2 (tty_fd, 2); /* Throw away stdout to the black hole */ dup2 (null_fd, 1); /* Execute cdparanoia */ execvp (argv[0], argv); dup2 (stderr_fd, 2); perror (_("Failed to exec cdparanoia :")); _exit (127); } close (null_fd); return_value = process_cd_contents_output (main_data, pty_fd); /* Kill again the zombie */ waitpid (pid, NULL, 0); return return_value; }
EAPI void e_alert_show(int sig) { char *args[4]; pid_t pid; #define E_ALERT_EXE "/enlightenment/utils/enlightenment_alert" args[0] = alloca(strlen(e_prefix_lib_get()) + strlen(E_ALERT_EXE) + 1); strcpy(args[0], e_prefix_lib_get()); strcat(args[0], E_ALERT_EXE); args[1] = alloca(10); snprintf(args[1], 10, "%d", sig); args[2] = alloca(21); snprintf(args[2], 21, "%lu", (long unsigned int)getpid()); args[3] = alloca(21); snprintf(args[3], 21, "%lu", e_alert_composite_win); pid = fork(); if (pid < -1) goto restart_e; if (pid == 0) { /* The child process */ execvp(args[0], args); } else { /* The parent process */ pid_t ret; int status = 0; do { ret = waitpid(pid, &status, 0); if (errno == ECHILD) break ; } while (ret != pid); if (status == 0) goto restart_e; if (!WIFEXITED(status)) goto restart_e; if (WEXITSTATUS(status) == 1) goto restart_e; exit(-11); } restart_e: if (getenv("E_START_MTRACK")) e_util_env_set("MTRACK", "track"); ecore_app_restart(); }
int main (void) { void *context = zmq_init (1); pid_t pid = fork(); if (pid) { void *responder = zmq_socket (context, ZMQ_REP); // Socket to talk to clients zmq_bind (responder, "ipc://xpto.sock"); while (1) { // Wait for next request from client zmq_msg_t request; zmq_msg_init (&request); zmq_recv (responder, &request, 0); char payload[10]; int size = zmq_msg_size(&request); memcpy(payload, zmq_msg_data(&request), size); payload[size] = '\0'; if (strncmp(payload, "quit", 4) == 0) { printf("[%d] Received '%s', sleep a bit\n", getpid(), payload); sleep(4); break; } printf ("[%d] Received '%s'\n", getpid(), payload); zmq_msg_close (&request); // Do some 'work' sleep (1); // Send reply back to client zmq_msg_t reply; zmq_msg_init_size (&reply, 5); memcpy (zmq_msg_data (&reply), "World", 5); zmq_send (responder, &reply, 0); zmq_msg_close (&reply); } // We never get here but if we did, this would be how we end printf("[%d] Parent is cleaning up\n", getpid()); zmq_close (responder); zmq_term (context); printf("[%d] waiting for child\n", getpid()); int status; int rpid = waitpid(pid, &status, 0); printf("[%d] waited for pid %d, got %d status %d\n", getpid(), pid, rpid, status); printf("[%d] Parent is exiting\n", getpid()); } else { context = zmq_init (1); // Socket to talk to server printf ("[%d] Connecting to hello world server...\n", getpid()); void *requester = zmq_socket (context, ZMQ_REQ); zmq_connect (requester, "ipc://xpto.sock"); int request_nbr; zmq_msg_t request; for (request_nbr = 0; request_nbr != 2; request_nbr++) { zmq_msg_init_size (&request, 5); memcpy (zmq_msg_data (&request), "Hello", 5); printf ("[%d] Sending Hello %d...\n", getpid(), request_nbr); zmq_send (requester, &request, 0); zmq_msg_close (&request); zmq_msg_t reply; zmq_msg_init (&reply); zmq_recv (requester, &reply, 0); printf ("[%d] Received World %d\n", getpid(), request_nbr); zmq_msg_close (&reply); } zmq_msg_init_size (&request, 4); memcpy (zmq_msg_data (&request), "quit", 4); printf ("[%d] Sending quit...\n", getpid()); zmq_send (requester, &request, 0); zmq_msg_close (&request); sleep(1); printf("[%d] Child is cleaning up\n", getpid()); zmq_close (requester); zmq_term (context); printf("[%d] Child is exiting()\n", getpid()); exit(0); } return 0; }
/* The main test function. */ int main( int argc, char * argv[] ) { int ret, status; pid_t child, ctl; sem_t * sem_linked, *sem_unlinked; /* Initialize output */ output_init(); sem_linked = sem_open( "/fork_14_1a", O_CREAT, O_RDWR, 0 ); if ( sem_linked == SEM_FAILED ) { UNRESOLVED( errno, "Failed to create the named semaphore" ); } sem_unlinked = sem_open( "/fork_14_1b", O_CREAT, O_RDWR, 0 ); if ( sem_unlinked == SEM_FAILED ) { UNRESOLVED( errno, "Failed to create the named semaphore" ); } ret = sem_unlink( "/fork_14_1b" ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to unlink the semaphore" ); } /* Create the child */ child = fork(); if ( child == ( pid_t ) - 1 ) { UNRESOLVED( errno, "Failed to fork" ); } /* child */ if ( child == ( pid_t ) 0 ) { do { ret = sem_post( sem_linked ); } while ( ( ret != 0 ) && ( errno == EINTR ) ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to post semaphore A" ); } do { ret = sem_post( sem_unlinked ); } while ( ( ret != 0 ) && ( errno == EINTR ) ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to post semaphore B" ); } /* We're done */ exit( PTS_PASS ); } /* Parent joins the child */ ctl = waitpid( child, &status, 0 ); if ( ctl != child ) { UNRESOLVED( errno, "Waitpid returned the wrong PID" ); } if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) { FAILED( "Child exited abnormally" ); } /* Check both semaphores have been posted */ do { ret = sem_trywait( sem_linked ); } while ( ( ret != 0 ) && ( errno == EINTR ) ); if ( ret != 0 ) { if ( errno == EAGAIN ) { FAILED( "Child did not inherit the semaphore A" ); } else { UNRESOLVED( errno, "sem_trywait failed" ); } } do { ret = sem_trywait( sem_unlinked ); } while ( ( ret != 0 ) && ( errno == EINTR ) ); if ( ret != 0 ) { if ( errno == EAGAIN ) { FAILED( "Child did not inherit the semaphore B" ); } else { UNRESOLVED( errno, "sem_trywait failed" ); } } ret = sem_unlink( "/fork_14_1a" ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to unlink semaphore A" ); } ret = sem_close( sem_linked ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to close semaphore A" ); } ret = sem_close( sem_unlinked ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to close semaphore B" ); } /* Test passed */ #if VERBOSE > 0 output( "Test passed\n" ); #endif PASSED; }