void process_pull_msg(zmq_msg_t * payload_msg) { char * type = NULL; json_t * payload = json_loadb(zmq_msg_data(payload_msg), zmq_msg_size(payload_msg), 0, NULL); if(payload == NULL) return; if(get_values(payload, "type", JSON_STRING, 1, &type, NULL) != 0) { json_decref(payload); return; } if(strcmp(type, "command") == 0) process_cmd(payload); else if(strcmp(type, "host_check_processed") == 0 || strcmp(type, "service_check_processed") == 0) process_status(payload); else if(strcmp(type, "acknowledgement") == 0) process_acknowledgement(payload); else if(strcmp(type, "comment_add") == 0) process_comment(payload); else if(strcmp(type, "downtime_add") == 0) process_downtime(payload); else if(strcmp(type, "state_data") == 0) process_bulkstate(payload); return; }
static int ps(int argc, char **argv) { process_t *process; int i, processes; process = malloc(MAX_PROCESSES * sizeof(*process)); if (process == NULL) { printf("%s: out of memory\n", argv[0]); return 1; } processes = process_status(process, MAX_PROCESSES); printf("TID SIZE STIME CTIME COMMAND\n"); for (i = 0; i < processes; i++) { printf("%3x %4x %7d %7d %s\n", process[i].pid, process[i].size, process[i].stime, process[i].ctime, process[i].command); } free(process); return 0; }
int process_run(char **argv, const int keep_fds[], size_t n_keep_fds, const int null_fds[], size_t n_null_fds, int *status) { struct process *p; int retval; COVERAGE_INC(process_run); retval = process_start(argv, keep_fds, n_keep_fds, null_fds, n_null_fds, &p); if (retval) { *status = 0; return retval; } while (!process_exited(p)) { process_wait(p); poll_block(); } *status = process_status(p); process_destroy(p); return 0; }
static int create_pipe(const char *fname, exe_disk_file_t *dfile, const char *tmpdir) { //struct stat64 *s = dfile->stat; unsigned flen = dfile->size; char* contents = dfile->contents; // XXX what is direction ? need more data pid_t pid; int fds[2]; int res = pipe(fds); if (res < 0) { perror("pipe"); exit(1); } pid = fork(); if (pid < 0) { perror("fork"); exit(1); } else if (pid == 0) { close(fds[1]); return fds[0]; } else { unsigned pos = 0; int status; fprintf(stderr, "note: pipe master: starting\n"); close(fds[0]); while (pos < flen) { int res = write(fds[1], &contents[pos], flen - pos); if (res<0) { if (errno != EINTR) break; } else if (res) { pos += res; } } if (wait_for_timeout_or_exit(pid, "pipe master", &status)) goto pipe_exit; fprintf(stderr, "note: pipe master: closing & waiting\n"); close(fds[1]); while (1) { int res = waitpid(pid, &status, 0); if (res < 0) { if (errno != EINTR) break; } else { break; } } pipe_exit: close(fds[1]); fprintf(stderr, "note: pipe master: done\n"); process_status(status, 0, "PTY MASTER"); } }
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(); execv(executable, argv); perror("execv"); _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); } }
bool KeyValueStorage::get(const std::string &key, std::string &data) { if (!db) return false; #if USE_LEVELDB auto status = db->Get(read_options, key, &data); return process_status(status); #else return true; #endif }
bool KeyValueStorage::put(const std::string &key, const std::string &data) { if (!db) return false; #if USE_LEVELDB auto status = db->Put(write_options, key, data); return process_status(status); #else return true; #endif }
bool KeyValueStorage::open() { #if USE_LEVELDB leveldb::Options options; options.create_if_missing = true; auto status = leveldb::DB::Open(options, fullpath, &db); verbosestream << "KeyValueStorage::open() db_name=" << db_name << " status=" << status.ok() << " error=" << status.ToString() << std::endl; return process_status(status, true); #else return true; #endif }
bool KeyValueStorage::del(const std::string &key) { if (!db) return false; #if USE_LEVELDB //std::lock_guard<Mutex> lock(mutex); auto status = db->Delete(write_options, key); return process_status(status); #else return true; #endif }
static void * process_command_thread(void * other) { struct fuse_client * c = other; int ret=0; char tosend[sizeof(struct afp_server_response) + MAX_CLIENT_RESPONSE]; struct afp_server_response response; switch(c->incoming_string[0]) { case AFP_SERVER_COMMAND_MOUNT: ret=process_mount(c); break; case AFP_SERVER_COMMAND_STATUS: ret=process_status(c); break; case AFP_SERVER_COMMAND_UNMOUNT: ret=process_unmount(c); break; case AFP_SERVER_COMMAND_SUSPEND: ret=process_suspend(c); break; case AFP_SERVER_COMMAND_RESUME: ret=process_resume(c); break; case AFP_SERVER_COMMAND_PING: ret=process_ping(c); break; case AFP_SERVER_COMMAND_EXIT: ret=process_exit(c); break; default: log_for_client((void *)c,AFPFSD,LOG_ERR,"Unknown command\n"); } /* Send response */ response.result=ret; response.len=strlen(c->client_string); bcopy(&response,tosend,sizeof(response)); bcopy(c->client_string,tosend+sizeof(response),response.len); ret=write(c->fd,tosend,sizeof(response)+response.len); if (ret<0) { perror("Writing"); } if ((!c) || (c->fd==0)) return NULL; rm_fd_and_signal(c->fd); close(c->fd); remove_client(c); return NULL; }
static int ast_forall_execute( struct ast_forloop *f, time_t stoptime, const char *name, int argc, char **argv ) { int i; int pid; int result; struct multi_fork_status *s; s = xxmalloc(sizeof(*s)*argc); pid = multi_fork(argc,s,stoptime,f->for_line); if(pid>=0) { random_init(); if(stoptime && (time(0)>stoptime)) _exit(1); ftsh_error(FTSH_ERROR_STRUCTURE,f->for_line,"%s=%s starting",name,argv[pid]); result = buffer_save(name,argv[pid]); if(!result) _exit(1); result = ast_group_execute(f->body,stoptime); if(result) { _exit(0); } else { _exit(1); } } else { for(i=0;i<argc;i++) { char str[LINE_MAX]; if(s[i].state==MULTI_FORK_STATE_GRAVE) { snprintf(str,sizeof(str),"%s=%s",name,argv[i]); process_status(str,s[i].pid,s[i].status,f->for_line); } } free(s); if(pid==MULTI_FORK_SUCCESS) { return 1; } else { return 0; } } }
static int ast_do_external( int line, int argc, char **argv, int fds[3], time_t stoptime ) { timed_exec_t tresult; int status; int result; pid_t pid; tresult = timed_exec(line,argv[0],argv,fds,&pid,&status,stoptime); if(tresult==TIMED_EXEC_TIMEOUT) { ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] ran out of time",argv[0],pid); result = 0; } else if(tresult==TIMED_EXEC_NOEXEC) { ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] couldn't be executed: %s",argv[0],pid,strerror(errno)); result = 0; } else { result = process_status(argv[0],pid,status,line); } return result; }
int main(int argc, char *argv[]) { process_t *process; int i, processes; process = malloc(MAX_PROCESSES * sizeof(*process)); if (process == NULL) { printf("%s: out of memory\n", argv[0]); return 1; } processes = process_status(process, MAX_PROCESSES); printf("%3s %8s %6s %10s %6s %-10s\n", "TID", "STATE", "SIZE", "STIME", "CTIME", "COMMAND"); for (i = 0; i < processes; i++) { printf("%3d %8s %6d %10d %6d %-10s\n", process[i].pid, process_state_show(process[i].state), process[i].size, process[i].stime, process[i].ctime, process[i].command); } free(process); return 0; }
/* TLS: making a conservative guess at which system calls need to be mutexed. I'm doing it whenever I see the process table altered or affected, so this is the data structure that its protecting. At some point, the SET_FILEPTRs should be protected against other threads closing that stream. Perhaps for such things a thread-specific stream table should be used. */ xsbBool sys_system(CTXTdeclc int callno) { // int pid; Integer pid; switch (callno) { case PLAIN_SYSTEM_CALL: /* dumb system call: no communication with XSB */ /* this call is superseded by shell and isn't used */ ctop_int(CTXTc 3, system(ptoc_string(CTXTc 2))); return TRUE; case SLEEP_FOR_SECS: #ifdef WIN_NT Sleep((int)iso_ptoc_int_arg(CTXTc 2,"sleep/1",1) * 1000); #else sleep(iso_ptoc_int_arg(CTXTc 2,"sleep/1",1)); #endif return TRUE; case GET_TMP_FILENAME: ctop_string(CTXTc 2,tempnam(NULL,NULL)); return TRUE; case IS_PLAIN_FILE: case IS_DIRECTORY: case STAT_FILE_TIME: case STAT_FILE_SIZE: return file_stat(CTXTc callno, ptoc_longstring(CTXTc 2)); case EXEC: { #ifdef HAVE_EXECVP /* execs a new process in place of XSB */ char *params[MAX_SUBPROC_PARAMS+2]; prolog_term cmdspec_term; int index = 0; cmdspec_term = reg_term(CTXTc 2); if (islist(cmdspec_term)) { prolog_term temp, head; char *string_head=NULL; if (isnil(cmdspec_term)) xsb_abort("[exec] Arg 1 must not be an empty list."); temp = cmdspec_term; do { head = p2p_car(temp); temp = p2p_cdr(temp); if (isstring(head)) string_head = string_val(head); else xsb_abort("[exec] non-string argument passed in list."); params[index++] = string_head; if (index > MAX_SUBPROC_PARAMS) xsb_abort("[exec] Too many arguments."); } while (!isnil(temp)); params[index] = NULL; } else if (isstring(cmdspec_term)) { char *string = string_val(cmdspec_term); split_command_arguments(string, params, "exec"); } else xsb_abort("[exec] 1st argument should be term or list of strings."); if (execvp(params[0], params)) xsb_abort("[exec] Exec call failed."); #else xsb_abort("[exec] builtin not supported in this architecture."); #endif } case SHELL: /* smart system call: like SPAWN_PROCESS, but returns error code instead of PID. Uses system() rather than execvp. Advantage: can pass arbitrary shell command. */ case SPAWN_PROCESS: { /* spawn new process, reroute stdin/out/err to XSB */ /* +CallNo=2, +ProcAndArgsList, -StreamToProc, -StreamFromProc, -StreamFromProcStderr, -Pid */ static int pipe_to_proc[2], pipe_from_proc[2], pipe_from_stderr[2]; int toproc_stream=-1, fromproc_stream=-1, fromproc_stderr_stream=-1; int pid_or_status; FILE *toprocess_fptr=NULL, *fromprocess_fptr=NULL, *fromproc_stderr_fptr=NULL; char *params[MAX_SUBPROC_PARAMS+2]; /* one for progname--0th member, one for NULL termination*/ prolog_term cmdspec_term, cmdlist_temp_term; prolog_term cmd_or_arg_term; xsbBool toproc_needed=FALSE, fromproc_needed=FALSE, fromstderr_needed=FALSE; char *cmd_or_arg=NULL, *shell_cmd=NULL; int idx = 0, tbl_pos; char *callname=NULL; xsbBool params_are_in_a_list=FALSE; SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (callno == SPAWN_PROCESS) callname = "spawn_process/5"; else callname = "shell/[1,2,5]"; cmdspec_term = reg_term(CTXTc 2); if (islist(cmdspec_term)) params_are_in_a_list = TRUE; else if (isstring(cmdspec_term)) shell_cmd = string_val(cmdspec_term); else if (isref(cmdspec_term)) xsb_instantiation_error(CTXTc callname,1); else xsb_type_error(CTXTc "atom or list e.g. [command, arg, ...]",cmdspec_term,callname,1); // xsb_abort("[%s] Arg 1 must be an atom or a list [command, arg, ...]", // callname); /* the user can indicate that he doesn't want either of the streams created by putting an atom in the corresponding argument position */ if (isref(reg_term(CTXTc 3))) toproc_needed = TRUE; if (isref(reg_term(CTXTc 4))) fromproc_needed = TRUE; if (isref(reg_term(CTXTc 5))) fromstderr_needed = TRUE; /* if any of the arg streams is already used by XSB, then don't create pipes --- use these streams instead. */ if (isointeger(reg_term(CTXTc 3))) { SET_FILEPTR(toprocess_fptr, oint_val(reg_term(CTXTc 3))); } if (isointeger(reg_term(CTXTc 4))) { SET_FILEPTR(fromprocess_fptr, oint_val(reg_term(CTXTc 4))); } if (isointeger(reg_term(CTXTc 5))) { SET_FILEPTR(fromproc_stderr_fptr, oint_val(reg_term(CTXTc 5))); } if (!isref(reg_term(CTXTc 6))) xsb_type_error(CTXTc "variable (to return process id)",reg_term(CTXTc 6),callname,5); // xsb_abort("[%s] Arg 5 (process id) must be a variable", callname); if (params_are_in_a_list) { /* fill in the params[] array */ if (isnil(cmdspec_term)) xsb_abort("[%s] Arg 1 must not be an empty list", callname); cmdlist_temp_term = cmdspec_term; do { cmd_or_arg_term = p2p_car(cmdlist_temp_term); cmdlist_temp_term = p2p_cdr(cmdlist_temp_term); if (isstring(cmd_or_arg_term)) { cmd_or_arg = string_val(cmd_or_arg_term); } else xsb_abort("[%s] Non string list member in the Arg", callname); params[idx++] = cmd_or_arg; if (idx > MAX_SUBPROC_PARAMS) xsb_abort("[%s] Too many arguments passed to subprocess", callname); } while (!isnil(cmdlist_temp_term)); params[idx] = NULL; /* null termination */ } else { /* params are in a string */ if (callno == SPAWN_PROCESS) split_command_arguments(shell_cmd, params, callname); else { /* if callno==SHELL => call system() => don't split shell_cmd */ params[0] = shell_cmd; params[1] = NULL; } } /* -1 means: no space left */ if ((tbl_pos = get_free_process_cell()) < 0) { xsb_warn(CTXTc "Can't create subprocess because XSB process table is full"); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } /* params[0] is the progname */ pid_or_status = xsb_spawn(CTXTc params[0], params, callno, (toproc_needed ? pipe_to_proc : NULL), (fromproc_needed ? pipe_from_proc : NULL), (fromstderr_needed ? pipe_from_stderr : NULL), toprocess_fptr, fromprocess_fptr, fromproc_stderr_fptr); if (pid_or_status < 0) { xsb_warn(CTXTc "[%s] Subprocess creation failed, Error: %d, errno: %d, Cmd: %s", callname,pid_or_status,errno,params[0]); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } if (toproc_needed) { toprocess_fptr = fdopen(pipe_to_proc[1], "w"); toproc_stream = xsb_intern_fileptr(CTXTc toprocess_fptr,callname,"pipe","w",CURRENT_CHARSET); ctop_int(CTXTc 3, toproc_stream); } if (fromproc_needed) { fromprocess_fptr = fdopen(pipe_from_proc[0], "r"); fromproc_stream = xsb_intern_fileptr(CTXTc fromprocess_fptr,callname,"pipe","r",CURRENT_CHARSET); ctop_int(CTXTc 4, fromproc_stream); } if (fromstderr_needed) { fromproc_stderr_fptr = fdopen(pipe_from_stderr[0], "r"); fromproc_stderr_stream = xsb_intern_fileptr(CTXTc fromproc_stderr_fptr,callname,"pipe","r",CURRENT_CHARSET); ctop_int(CTXTc 5, fromproc_stderr_stream); } ctop_int(CTXTc 6, pid_or_status); xsb_process_table.process[tbl_pos].pid = pid_or_status; xsb_process_table.process[tbl_pos].to_stream = toproc_stream; xsb_process_table.process[tbl_pos].from_stream = fromproc_stream; xsb_process_table.process[tbl_pos].stderr_stream = fromproc_stderr_stream; concat_array(CTXTc params, " ", xsb_process_table.process[tbl_pos].cmdline,MAX_CMD_LEN); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } case GET_PROCESS_TABLE: { /* sys_system(3, X). X is bound to the list of the form [process(Pid,To,From,Stderr,Cmdline), ...] */ int i; prolog_term table_term_tail, listHead; prolog_term table_term=reg_term(CTXTc 2); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!isref(table_term)) xsb_abort("[GET_PROCESS_TABLE] Arg 1 must be a variable"); table_term_tail = table_term; for (i=0; i<MAX_SUBPROC_NUMBER; i++) { if (!FREE_PROC_TABLE_CELL(xsb_process_table.process[i].pid)) { c2p_list(CTXTc table_term_tail); /* make it into a list */ listHead = p2p_car(table_term_tail); c2p_functor(CTXTc "process", 5, listHead); c2p_int(CTXTc xsb_process_table.process[i].pid, p2p_arg(listHead,1)); c2p_int(CTXTc xsb_process_table.process[i].to_stream, p2p_arg(listHead,2)); c2p_int(CTXTc xsb_process_table.process[i].from_stream, p2p_arg(listHead,3)); c2p_int(CTXTc xsb_process_table.process[i].stderr_stream, p2p_arg(listHead,4)); c2p_string(CTXTc xsb_process_table.process[i].cmdline, p2p_arg(listHead,5)); table_term_tail = p2p_cdr(table_term_tail); } } c2p_nil(CTXTc table_term_tail); /* bind tail to nil */ SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return p2p_unify(CTXTc table_term, reg_term(CTXTc 2)); } case PROCESS_STATUS: { prolog_term pid_term=reg_term(CTXTc 2), status_term=reg_term(CTXTc 3); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!(isointeger(pid_term))) xsb_abort("[PROCESS_STATUS] Arg 1 (process id) must be an integer"); pid = (int)oint_val(pid_term); if (!isref(status_term)) xsb_abort("[PROCESS_STATUS] Arg 2 (process status) must be a variable"); switch (process_status(pid)) { case RUNNING: c2p_string(CTXTc "running", status_term); break; case STOPPED: c2p_string(CTXTc "stopped", status_term); break; case EXITED_NORMALLY: c2p_string(CTXTc "exited_normally", status_term); break; case EXITED_ABNORMALLY: c2p_string(CTXTc "exited_abnormally", status_term); break; case ABORTED: c2p_string(CTXTc "aborted", status_term); break; case INVALID: c2p_string(CTXTc "invalid", status_term); break; default: c2p_string(CTXTc "unknown", status_term); } SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } case PROCESS_CONTROL: { /* sys_system(PROCESS_CONTROL, +Pid, +Signal). Signal: wait, kill */ int status; prolog_term pid_term=reg_term(CTXTc 2), signal_term=reg_term(CTXTc 3); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!(isointeger(pid_term))) xsb_abort("[PROCESS_CONTROL] Arg 1 (process id) must be an integer"); pid = (int)oint_val(pid_term); if (isstring(signal_term) && strcmp(string_val(signal_term), "kill")==0) { if (KILL_FAILED(pid)) { SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } #ifdef WIN_NT CloseHandle((HANDLE) pid); #endif SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } if (isconstr(signal_term) && strcmp(p2c_functor(signal_term),"wait") == 0 && p2c_arity(signal_term)==1) { int exit_status; if (WAIT(pid, status) < 0) { SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } #ifdef WIN_NT exit_status = status; #else if (WIFEXITED(status)) exit_status = WEXITSTATUS(status); else exit_status = -1; #endif p2p_unify(CTXTc p2p_arg(signal_term,1), makeint(exit_status)); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } xsb_warn(CTXTc "[PROCESS_CONTROL] Arg 2: Invalid signal specification. Must be `kill' or `wait(Var)'"); return FALSE; } case LIST_DIRECTORY: { /* assume all type- and mode-checking is done in Prolog */ prolog_term handle = reg_term(CTXTc 2); /* ref for handle */ char *dir_name = ptoc_longstring(CTXTc 3); /* +directory name */ prolog_term filename = reg_term(CTXTc 4); /* reference for name of file */ if (is_var(handle)) return xsb_find_first_file(CTXTc handle,dir_name,filename); else return xsb_find_next_file(CTXTc handle,dir_name,filename); } default: xsb_abort("[SYS_SYSTEM] Wrong call number (an XSB bug)"); } /* end case */ return TRUE; }
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(); /* Heming: set LD_PRELOAD so that we can intercept all critical libcv function calls. */ char interceptLibPath[1024]; memset(interceptLibPath, 0, sizeof(interceptLibPath)); snprintf(interceptLibPath, sizeof(interceptLibPath), "%s/%s", getenv("DIRECT_SYM_ROOT"), "instruments/dyn-intercept-calls/dyn-intercept-calls.so"); setenv("LD_PRELOAD", interceptLibPath, 1); fprintf(stderr, "\n$LD_PRELOAD=%s\n\n", getenv("LD_PRELOAD")); execv(executable, argv); perror("execv"); _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); } }
static int create_char_dev(const char *fname, exe_disk_file_t *dfile, const char *tmpdir) { struct stat64 *s = dfile->stat; unsigned flen = dfile->size; char* contents = dfile->contents; // Assume tty, kinda broken, need an actual device id or something struct termios term, *ts=&term; struct winsize win = { 24, 80, 0, 0 }; /* Just copied from my system, munged to match what fields uclibc thinks are there. */ ts->c_iflag = 27906; ts->c_oflag = 5; ts->c_cflag = 1215; ts->c_lflag = 35287; ts->c_line = 0; ts->c_cc[0] = '\x03'; ts->c_cc[1] = '\x1c'; ts->c_cc[2] = '\x7f'; ts->c_cc[3] = '\x15'; ts->c_cc[4] = '\x04'; ts->c_cc[5] = '\x00'; ts->c_cc[6] = '\x01'; ts->c_cc[7] = '\xff'; ts->c_cc[8] = '\x11'; ts->c_cc[9] = '\x13'; ts->c_cc[10] = '\x1a'; ts->c_cc[11] = '\xff'; ts->c_cc[12] = '\x12'; ts->c_cc[13] = '\x0f'; ts->c_cc[14] = '\x17'; ts->c_cc[15] = '\x16'; ts->c_cc[16] = '\xff'; ts->c_cc[17] = '\x0'; ts->c_cc[18] = '\x0'; { char name[1024]; int amaster, aslave; int res = openpty(&amaster, &aslave, name, &term, &win); if (res < 0) { perror("openpty"); exit(1); } if (symlink(name, fname) == -1) { fprintf(stderr, "unable to create sym link to tty\n"); perror("symlink"); } // pty will not be world writeable s->st_mode &= ~02; pid_t pid = fork(); if (pid < 0) { perror("fork failed\n"); exit(1); } else if (pid == 0) { close(amaster); fprintf(stderr, "note: pty slave: setting raw mode\n"); { struct termio mode; int res = ioctl(aslave, TCGETA, &mode); assert(!res); mode.c_iflag = IGNBRK; mode.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONLRET); mode.c_lflag = 0; mode.c_cc[VMIN] = 1; mode.c_cc[VTIME] = 0; res = ioctl(aslave, TCSETA, &mode); assert(res == 0); } return aslave; } else { unsigned pos = 0; int status; fprintf(stderr, "note: pty master: starting\n"); close(aslave); while (pos < flen) { int res = write(amaster, &contents[pos], flen - pos); if (res<0) { if (errno != EINTR) { fprintf(stderr, "note: pty master: write error\n"); perror("errno"); break; } } else if (res) { fprintf(stderr, "note: pty master: wrote: %d (of %d)\n", res, flen); pos += res; } } if (wait_for_timeout_or_exit(pid, "pty master", &status)) goto pty_exit; fprintf(stderr, "note: pty master: closing & waiting\n"); close(amaster); while (1) { int res = waitpid(pid, &status, 0); if (res < 0) { if (errno != EINTR) break; } else { break; } } pty_exit: close(amaster); fprintf(stderr, "note: pty master: done\n"); process_status(status, 0, "PTY MASTER"); } } }
/* Starts the process whose arguments are given in the null-terminated array * 'argv' and waits for it to exit. On success returns 0 and stores the * process exit value (suitable for passing to process_status_msg()) in * '*status'. On failure, returns a positive errno value and stores 0 in * '*status'. * * If 'stdout_log' is nonnull, then the subprocess's output to stdout (up to a * limit of PROCESS_MAX_CAPTURE bytes) is captured in a memory buffer, which * when this function returns 0 is stored as a null-terminated string in * '*stdout_log'. The caller is responsible for freeing '*stdout_log' (by * passing it to free()). When this function returns an error, '*stdout_log' * is set to NULL. * * If 'stderr_log' is nonnull, then it is treated like 'stdout_log' except * that it captures the subprocess's output to stderr. */ int process_run_capture(char **argv, char **stdout_log, char **stderr_log, int *status) { struct stream s_stdout, s_stderr; sigset_t oldsigs; pid_t pid; int error; COVERAGE_INC(process_run_capture); if (stdout_log) { *stdout_log = NULL; } if (stderr_log) { *stderr_log = NULL; } *status = 0; error = process_prestart(argv); if (error) { return error; } error = stream_open(&s_stdout); if (error) { return error; } error = stream_open(&s_stderr); if (error) { stream_close(&s_stdout); return error; } block_sigchld(&oldsigs); pid = fork(); if (pid < 0) { int error = errno; unblock_sigchld(&oldsigs); VLOG_WARN("fork failed: %s", strerror(error)); stream_close(&s_stdout); stream_close(&s_stderr); *status = 0; return error; } else if (pid) { /* Running in parent process. */ struct process *p; p = process_register(argv[0], pid); unblock_sigchld(&oldsigs); close(s_stdout.fds[1]); close(s_stderr.fds[1]); while (!process_exited(p)) { stream_read(&s_stdout); stream_read(&s_stderr); stream_wait(&s_stdout); stream_wait(&s_stderr); process_wait(p); poll_block(); } stream_read(&s_stdout); stream_read(&s_stderr); if (stdout_log) { *stdout_log = ds_steal_cstr(&s_stdout.log); } if (stderr_log) { *stderr_log = ds_steal_cstr(&s_stderr.log); } stream_close(&s_stdout); stream_close(&s_stderr); *status = process_status(p); process_destroy(p); return 0; } else { /* Running in child process. */ int max_fds; int i; fatal_signal_fork(); unblock_sigchld(&oldsigs); dup2(get_null_fd(), 0); dup2(s_stdout.fds[1], 1); dup2(s_stderr.fds[1], 2); max_fds = get_max_fds(); for (i = 3; i < max_fds; i++) { close(i); } execvp(argv[0], argv); fprintf(stderr, "execvp(\"%s\") failed: %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } }
/* read process statuses */ static void read_status(int num, status_t *s) { char status[20]; char buf[80]; FILE *fp; while (num--) { sprintf(status, "%s/status", s->pid); /* read the command line from 'cmdline' in PID dir */ fp = fopen(status, "r"); if (!fp) { strncpy(s->pid, "EXIT", sizeof(s->pid)); continue; } /* get and process the information */ fgets(buf, sizeof(buf), fp); process_status(buf, "Name", s->name, sizeof(s->name)); fgets(buf, sizeof(buf), fp); process_status(buf, "State", s->state, sizeof(s->state)); fgets(buf, sizeof(buf), fp); if(process_status(buf, "Tgid", NULL, 0)) fgets(buf, sizeof(buf), fp); process_status(buf, "Pid", NULL, 0); fgets(buf, sizeof(buf), fp); process_status(buf, "PPid", s->ppid, sizeof(s->ppid)); fgets(buf, sizeof(buf), fp); if(process_status(buf, "TracerPid", NULL, 0)) fgets(buf, sizeof(buf), fp); process_status(buf, "Uid", s->uid, sizeof(s->uid)); fgets(buf, sizeof(buf), fp); process_status(buf, "Gid", NULL, 0); fgets(buf, sizeof(buf), fp); if(process_status(buf, "FDSize", NULL, 0)) fgets(buf, sizeof(buf), fp); process_status(buf, "Groups", NULL, 0); fgets(buf, sizeof(buf), fp); /* only user space processes have command line * and memory statistics */ if (s->cmd[0]) { process_status(buf, "VmSize", s->size, sizeof(s->size)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmLck", s->lck, sizeof(s->lck)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmRSS", s->rss, sizeof(s->rss)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmData", s->data, sizeof(s->data)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmStk", s->stk, sizeof(s->stk)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmExe", s->exe, sizeof(s->exe)); fgets(buf, sizeof(buf), fp); process_status(buf, "VmLib", s->lib, sizeof(s->lib)); } fclose(fp); /* next process */ s++; } }
int main(int argc, char *argv[]) { char *unixctl_path = NULL; char *run_command = NULL; struct unixctl_server *unixctl; struct ovsdb_jsonrpc_server *jsonrpc; struct shash remotes; struct ovsdb_error *error; struct ovsdb_file *file; struct ovsdb *db; struct process *run_process; char *file_name; bool exiting; int retval; proctitle_init(argc, argv); set_program_name(argv[0]); signal(SIGPIPE, SIG_IGN); process_init(); parse_options(argc, argv, &file_name, &remotes, &unixctl_path, &run_command); die_if_already_running(); daemonize_start(); error = ovsdb_file_open(file_name, false, &db, &file); if (error) { ovs_fatal(0, "%s", ovsdb_error_to_string(error)); } jsonrpc = ovsdb_jsonrpc_server_create(db); reconfigure_from_db(jsonrpc, db, &remotes); retval = unixctl_server_create(unixctl_path, &unixctl); if (retval) { exit(EXIT_FAILURE); } if (run_command) { char *run_argv[4]; run_argv[0] = "/bin/sh"; run_argv[1] = "-c"; run_argv[2] = run_command; run_argv[3] = NULL; retval = process_start(run_argv, NULL, 0, NULL, 0, &run_process); if (retval) { ovs_fatal(retval, "%s: process failed to start", run_command); } } else { run_process = NULL; } daemonize_complete(); unixctl_command_register("exit", ovsdb_server_exit, &exiting); unixctl_command_register("ovsdb-server/compact", ovsdb_server_compact, file); unixctl_command_register("ovsdb-server/reconnect", ovsdb_server_reconnect, jsonrpc); exiting = false; while (!exiting) { reconfigure_from_db(jsonrpc, db, &remotes); ovsdb_jsonrpc_server_run(jsonrpc); unixctl_server_run(unixctl); ovsdb_trigger_run(db, time_msec()); if (run_process && process_exited(run_process)) { exiting = true; } ovsdb_jsonrpc_server_wait(jsonrpc); unixctl_server_wait(unixctl); ovsdb_trigger_wait(db, time_msec()); if (run_process) { process_wait(run_process); } poll_block(); } ovsdb_jsonrpc_server_destroy(jsonrpc); ovsdb_destroy(db); shash_destroy(&remotes); unixctl_server_destroy(unixctl); if (run_process && process_exited(run_process)) { int status = process_status(run_process); if (status) { ovs_fatal(0, "%s: child exited, %s", run_command, process_status_msg(status)); } } return 0; }
void *router_thread(struct wiimote *wiimote) { unsigned char buf[READ_BUF_LEN]; ssize_t len; struct mesg_array ma; char err, print_clock_err = 1; while (1) { /* Read packet */ len = read(wiimote->int_socket, buf, READ_BUF_LEN); ma.count = 0; if (clock_gettime(CLOCK_REALTIME, &ma.timestamp)) { if (print_clock_err) { cwiid_err(wiimote, "clock_gettime error"); print_clock_err = 0; } } err = 0; if ((len == -1) || (len == 0)) { process_error(wiimote, len, &ma); write_mesg_array(wiimote, &ma); /* Quit! */ break; } else { /* Verify first byte (DATA/INPUT) */ if (buf[0] != (BT_TRANS_DATA | BT_PARAM_INPUT)) { cwiid_err(wiimote, "Invalid packet type"); } /* Main switch */ /* printf("%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); printf("%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X\n", buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); printf("%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X\n", buf[16], buf[17], buf[18], buf[19], buf[20], buf[21], buf[22], buf[23]); printf("\n"); */ switch (buf[1]) { case RPT_STATUS: err = process_status(wiimote, &buf[2], &ma); break; case RPT_BTN: err = process_btn(wiimote, &buf[2], &ma); break; case RPT_BTN_ACC: err = process_btn(wiimote, &buf[2], &ma) || process_acc(wiimote, &buf[4], &ma); break; case RPT_BTN_EXT8: err = process_btn(wiimote, &buf[2], &ma) || process_ext(wiimote, &buf[4], 8, &ma); break; case RPT_BTN_ACC_IR12: err = process_btn(wiimote, &buf[2], &ma) || process_acc(wiimote, &buf[4], &ma) || process_ir12(wiimote, &buf[7], &ma); break; case RPT_BTN_EXT19: err = process_btn(wiimote, &buf[2], &ma) || process_ext(wiimote, &buf[4], 19, &ma); break; case RPT_BTN_ACC_EXT16: err = process_btn(wiimote, &buf[2], &ma) || process_acc(wiimote, &buf[4], &ma) || process_ext(wiimote, &buf[7], 16, &ma); break; case RPT_BTN_IR10_EXT9: err = process_btn(wiimote, &buf[2], &ma) || process_ir10(wiimote, &buf[4], &ma) || process_ext(wiimote, &buf[14], 9, &ma); break; case RPT_BTN_ACC_IR10_EXT6: err = process_btn(wiimote, &buf[2], &ma) || process_acc(wiimote, &buf[4], &ma) || process_ir10(wiimote, &buf[7], &ma) || process_ext(wiimote, &buf[17], 6, &ma); break; case RPT_EXT21: err = process_ext(wiimote, &buf[2], 21, &ma); break; case RPT_BTN_ACC_IR36_1: case RPT_BTN_ACC_IR36_2: cwiid_err(wiimote, "Unsupported report type received " "(interleaved data)"); err = 1; break; case RPT_READ_DATA: err = process_read(wiimote, &buf[4]) || process_btn(wiimote, &buf[2], &ma); break; case RPT_WRITE_ACK: err = process_write(wiimote, &buf[2]); break; default: cwiid_err(wiimote, "Unknown message type"); err = 1; break; } if (!err && (ma.count > 0)) { if (update_state(wiimote, &ma)) { cwiid_err(wiimote, "State update error"); } if (wiimote->flags & CWIID_FLAG_MESG_IFC) { /* prints its own errors */ write_mesg_array(wiimote, &ma); } } } } return NULL; }