int process_test_str(struct config *config, char *value, int value_sz, char *keyprefix) { int r; char c_file[1024]; char elf_file[1024]; snprintf(c_file, sizeof(c_file), "%s/plugin-%s.c", config->tmpdir, keyprefix); snprintf(elf_file, sizeof(elf_file), "%s/plugin-%s.elf", config->tmpdir, keyprefix); if(0 != write_file(c_file, value, value_sz)) { log_perror("write()"); return(-1); } char warn_buf[1024]; int warn_buf_sz = 0; if(0 != process_compile(config, c_file, elf_file, warn_buf, sizeof(warn_buf), &warn_buf_sz)) { warn_buf[MAX(1, warn_buf_sz)-1] = '\0'; log_error("compilation failed:\n%s", warn_buf); return(-1); } struct process *process = process_new(NULL, keyprefix, strlen(keyprefix)); log_warn("#%p: loaded code from str", process); r = process_load(process, elf_file); if(0 != r) { process_free(process); log_error("unable to load process:\n%s", warn_buf); return(-1); } r = process_run(NULL, process); process_free(process); if(r <= 0) { log_error("error while running process"); return(-1); } // ok! return(r); }
/* Request: MUST NOT have extras. MUST have key. MUST have value. */ ST_RES *cmd_code_load(CONN *conn, ST_REQ *req, ST_RES *res) { if(req->extras_sz || !req->key_sz || !req->value_sz) return(set_error_code(res, MEMCACHE_STATUS_INVALID_ARGUMENTS, NULL)); if(CONFIG(conn)->vx32_disabled) { return(set_error_code(res, MEMCACHE_STATUS_UNKNOWN_COMMAND, "Command disabled by configuration")); } if(NULL != find_process(req->key, req->key_sz)) return(set_error_code(res, MEMCACHE_STATUS_KEY_EXISTS, NULL)); int r; char c_file[1024]; char elf_file[1024]; char keyprefix[32]; key_escape(keyprefix, sizeof(keyprefix), req->key, req->key_sz); keyprefix[MIN(req->key_sz, sizeof(keyprefix)-1)] = '\0'; // make it reasonably short snprintf(c_file, sizeof(c_file), "%s/plugin-%s.c", CONFIG(conn)->tmpdir, keyprefix); snprintf(elf_file, sizeof(elf_file), "%s/plugin-%s.elf", CONFIG(conn)->tmpdir, keyprefix); res->value = res->buf; r = write_file(c_file, req->value, req->value_sz); if(0 != r) { // never res->status = MEMCACHE_STATUS_ITEM_NOT_STORED; res->value_sz += snprintf(&res->value[res->value_sz], res->buf_sz - res->value_sz, "Error while saving file: %s", strerror(errno)); return(res); } if(0 != process_compile(CONFIG(conn), c_file, elf_file, res->value, res->buf_sz, (int*)&res->value_sz)) { res->status = MEMCACHE_STATUS_ITEM_NOT_STORED; return(res); } res->value_sz = MIN(res->value_sz, 4096); // no more than 4k logs res->value[res->value_sz++] = '\n'; res->value[res->value_sz++] = '\n'; struct process *process = process_new(conn, req->key, req->key_sz); log_warn("#%p: loaded code", process); r = process_load(process, elf_file); if(0 != r) { // never process_free(process); res->value_sz += snprintf(&res->value[res->value_sz], res->buf_sz - res->value_sz, "Error while loading the binary"); res->status = MEMCACHE_STATUS_ITEM_NOT_STORED; return(res); } if(0 != process_run(conn, process)) { process_free(process); res->value_sz += snprintf(&res->value[res->value_sz], res->buf_sz - res->value_sz, "Error while running the binary"); res->status = MEMCACHE_STATUS_ITEM_NOT_STORED; return(res); } res->status = MEMCACHE_STATUS_OK; return res; }
void engine_cleanup(t_engine *engine) { t_link *link; t_process *process; if(engine->garbage->first) { int do_loop = 0; for(link = engine->garbage->first; link; link = link->next) { process = (t_process * ) link->data; if(process->done) { lst_link_delete_by_id(engine->processes, process->id.id); lst_link_delete_by_id(engine->garbage, process->id.id); process_free(process); do_loop = 1; break; } } if(do_loop) engine_cleanup(engine); } }
gboolean process_pid_finish (gpointer user_data) { ProcessData *process_data = (ProcessData *) user_data; // If both childwatch and io_callback are finished // Then finish and clean ourselves up. if ((process_data->pid != 0) | (process_data->io_handler_id != 0)) { process_data->finish_handler_id = 0; return FALSE; } // Remove local watchdog handler if (process_data->timeout_handler_id != 0) { g_source_remove(process_data->timeout_handler_id); process_data->timeout_handler_id = 0; } process_data->finish_callback (process_data->pid_result, process_data->localwatchdog, process_data->user_data, process_data->error); // Free process_data. process_free (process_data); return FALSE; }
static bool process_one_request(struct thread_arg *arg) { union tee_rpc_invoke request; size_t num_params; size_t num_meta; struct tee_ioctl_param *params; uint32_t func; uint32_t ret; DMSG("looping"); memset(&request, 0, sizeof(request)); request.recv.num_params = RPC_NUM_PARAMS; /* Let it be known that we can deal with meta parameters */ params = (struct tee_ioctl_param *)(&request.send + 1); params->attr = TEE_IOCTL_PARAM_ATTR_META; num_waiters_inc(arg); if (!read_request(arg->fd, &request)) return false; if (!find_params(&request, &func, &num_params, ¶ms, &num_meta)) return false; if (num_meta && !num_waiters_dec(arg) && !spawn_thread(arg)) return false; switch (func) { case OPTEE_MSG_RPC_CMD_LOAD_TA: ret = load_ta(num_params, params); break; case OPTEE_MSG_RPC_CMD_FS: ret = tee_supp_fs_process(num_params, params); break; case OPTEE_MSG_RPC_CMD_RPMB: ret = process_rpmb(num_params, params); break; case OPTEE_MSG_RPC_CMD_SHM_ALLOC: ret = process_alloc(arg, num_params, params); break; case OPTEE_MSG_RPC_CMD_SHM_FREE: ret = process_free(num_params, params); break; case OPTEE_MSG_RPC_CMD_GPROF: ret = gprof_process(num_params, params); break; case OPTEE_MSG_RPC_CMD_SOCKET: ret = tee_socket_process(num_params, params); break; default: EMSG("Cmd [0x%" PRIx32 "] not supported", func); /* Not supported. */ ret = TEEC_ERROR_NOT_SUPPORTED; break; } request.send.ret = ret; return write_response(arg->fd, &request); }
void process_scheduler(void) { struct process *next; if ((current_process = run_head) == NULL) return; for (;;) { next = current_process->next; #ifdef DEBUG if (trace_scheduling) printf("context switched to process #%d\n", current_process->number); #endif switch (vm_run(current_process->vm, TIMESLICE)) { case VM_TERMINATED: #ifdef DEBUG if (trace_scheduling) printf("process #%d terminated\n", current_process->number); #endif process_free(current_process); break; case VM_RETURNED: #ifdef DEBUG if (trace_scheduling) printf("process #%d returned\n", current_process->number); #endif process_free(current_process); break; case VM_WAITING: #ifdef DEBUG if (trace_scheduling) printf("process #%d falling asleep\n", current_process->number); #endif process_sleep(current_process); break; case VM_TIME_EXPIRED: default: break; } if ((current_process = next) == NULL) if ((current_process = run_head) == NULL) return; } }
/* * Stop all running processes. This is called as a cleanup handler during * process shutdown. The first argument, which says whether the test was * successful, is ignored, since the same actions should be performed * regardless. The second argument says whether this is the primary process, * in which case we do the full shutdown. Otherwise, we only free resources * but don't stop the process. */ static void process_stop_all(int success UNUSED, int primary) { while (processes != NULL) { if (primary) process_stop(processes); else process_free(processes); } }
/* Request: MUST NOT have extras. MUST have key. MUST NOT have value. */ ST_RES *cmd_code_unload(CONN *conn, ST_REQ *req, ST_RES *res) { if(req->extras_sz || !req->key_sz || req->value_sz) return(set_error_code(res, MEMCACHE_STATUS_INVALID_ARGUMENTS, NULL)); if(CONFIG(conn)->vx32_disabled) { return(set_error_code(res, MEMCACHE_STATUS_UNKNOWN_COMMAND, "Command disabled by configuration")); } struct process *process = find_process(req->key, req->key_sz); if(NULL == process) return(set_error_code(res, MEMCACHE_STATUS_KEY_NOT_FOUND, NULL)); process_free(process); res->status = MEMCACHE_STATUS_OK; return res; }
int main(int argc, char *argv[]) { char *shell = getenv("TALON_SHELL"); char **args = malloc((argc+2)*sizeof(char *)); int i; proc *p; for (i=1; i < argc; i++) { args[i] = argv[i]; printf("arg: %s\n", args[i]); } args[argc] = NULL; if (! shell) { fprintf(stderr, "error: %s", "TALONSHELL not set in environment\n"); return 1; } args[0] = shell; p = process_run(shell, args, 4000); if (p) { buffer_prepend(p->output, "<recipe>\n<!CDATA<[[\n", 20); buffer_append(p->output, "\n]]></recipe>\n", 13); unsigned int iterator = 0; byteblock *bb; while ((bb = buffer_getbytes(p->output, &iterator))) { write(STDOUT_FILENO, &bb->byte0, bb->fill); } process_free(&p); } else { fprintf(stderr, "error: %s", "failed to run process\n"); return 1; } free(args); return 0; }
static int __ocmem_free(int id, struct ocmem_buf *buf) { int ret = 0; struct ocmem_handle *handle = buffer_to_handle(buf); if (!handle) return -EINVAL; mutex_lock(&handle->handle_mutex); ret = process_free(id, handle); mutex_unlock(&handle->handle_mutex); if (ret) return -EINVAL; free_handle(handle); return 0; }
/* * Stop a particular process given its process struct. This kills the * process, waits for it to exit if possible (giving it at most five seconds), * and then removes it from the global processes struct so that it isn't * stopped again during global shutdown. */ void process_stop(struct process *process) { int status; unsigned long pid = process->pid; /* Stop the process. */ status = process_kill(process); /* Call diag to flush logs as well as provide exit status. */ if (process->is_child) diag("stopped process %lu (exit status %d)", pid, status); else diag("stopped process %lu", pid); /* Remove the log and PID file. */ diag_file_remove(process->logfile); unlink(process->pidfile); unlink(process->logfile); /* Free resources. */ process_free(process); }
void process_pid_finish (gpointer user_data) { ProcessData *process_data = (ProcessData *) user_data; // Remove local watchdog handler if (process_data->timeout_handler_id != 0) { g_source_remove(process_data->timeout_handler_id); process_data->timeout_handler_id = 0; } // Remove io handler if (process_data->io_handler_id != 0) { g_source_remove(process_data->io_handler_id); process_data->io_handler_id = 0; } process_data->finish_callback (process_data->pid_result, process_data->localwatchdog, process_data->user_data); // Free process_data. process_free (process_data); }
void host_freeAllApplications(Host* host) { MAGIC_ASSERT(host); while(!g_queue_is_empty(host->applications)) { process_free(g_queue_pop_head(host->applications)); } }
proc *process_run(char executable[], char *args[], int timeout) { proc *retval = NULL; char *text; int status; tl_stream stdout_p; tl_stream stdin_p; SECURITY_ATTRIBUTES saAttr; PROCESS_INFORMATION pi; STARTUPINFO si; BOOL createproc_success = FALSE; BOOL timedout = FALSE; TCHAR *commandline = NULL; proc *p = process_new(); if (p == NULL) return NULL; /* Make sure pipe handles are inherited */ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; p->causeofdeath = PROC_PIPECREATE; DEBUG(("making pipes \n")); /* Child's Stdout */ if ( ! CreatePipe(&stdout_p.read, &stdout_p.write, &saAttr, 1) ) { printlasterror(); RETURN(p); } DEBUG(("stdout done \n")); /* read handle to the pipe for STDOUT is not inherited */ if ( ! SetHandleInformation(stdout_p.read, HANDLE_FLAG_INHERIT, 0) ) { printlasterror(); RETURN(p); } DEBUG(("stdout noinherit \n")); /* a pipe for the child process's STDIN */ if ( ! CreatePipe(&stdin_p.read, &stdin_p.write, &saAttr, 0) ) { printlasterror(); RETURN(p); } DEBUG(("stdin done \n")); /* write handle to the pipe for STDIN not inherited */ if ( ! SetHandleInformation(stdin_p.read, HANDLE_FLAG_INHERIT, 0) ) { printlasterror(); RETURN(p); } DEBUG(("pipes done \n")); p->causeofdeath = PROC_START; ZeroMemory( &si, sizeof(STARTUPINFO) ); ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) ); si.cb = sizeof(STARTUPINFO); si.hStdError = stdout_p.write; si.hStdOutput = stdout_p.write; /* Rather than use the stdin pipe, which would be si.hStdInput = stdin_p.read; Pass on talon's own standard input to the child process This helps with programs like xcopy which demand that they are attached to a console and not just any type of input file. */ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; DEBUG(("pre commandline \n")); /* create the commandline string */ int len = 0; int i = 0; while (args[i] != NULL) { len += strlen(args[i++]) + 1; } len+=2; commandline = malloc(len*2); if (! commandline) RETURN(p); commandline[0] = '\0'; i = 0; while (args[i] != NULL) { strcat(commandline, args[i]); strcat(commandline, " "); i++; } /* Get the read thread ready to go before creating * the process. */ ReadOpQ *ropq = malloc(sizeof(ReadOpQ)); ropq->first=NULL; ropq->last=NULL; ropq->semaphore = CreateSemaphore(NULL, 0, 1, NULL); DEBUG(("Creating read thread. \n")); DWORD readpipe_threadid; HANDLE h_readpipe_thread = CreateThread(NULL, 8192, (LPTHREAD_START_ROUTINE) readpipe_thread, (void*)ropq, 0, &readpipe_threadid); /* ready to run the process */ DEBUG(("process commandline:\n%s \n", commandline)); DEBUG(("\n")); createproc_success = CreateProcess(executable, commandline, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &si, // STARTUPINFO pointer &pi); // receives PROCESS_INFORMATION if (! createproc_success) { DEBUG(("Createprocess failed. \n")); p->causeofdeath = PROC_SOMEODDDEATH; RETURN(p); } int have_status = 0; DEBUG(("Closing Handles. \n")); if (!CloseHandle(stdout_p.write)) RETURN(p); if (!CloseHandle(stdin_p.read)) RETURN(p); DEBUG(("Closed Handles. \n")); static int id=0; do { char *space = buffer_makespace(p->output, READSIZE); DWORD waitres; ReadOp *iopipe_op = malloc(sizeof(ReadOp)); iopipe_op->semaphore = CreateSemaphore(NULL, 0, 1, NULL); iopipe_op->thread = h_readpipe_thread; iopipe_op->timeout = timeout; iopipe_op->file = stdout_p.read; iopipe_op->space = malloc(READSIZE); iopipe_op->id = id++; iopipe_op->nbytes = READSIZE; iopipe_op->next = NULL; if (!ropq->first) { ropq->first = iopipe_op; ropq->last = iopipe_op; } else { ropq->last->next = iopipe_op; ropq->last = iopipe_op; } ReleaseSemaphore(ropq->semaphore, 1, NULL); DEBUG(("waiting for read %d\n", timeout)); waitres = WaitForSingleObject(iopipe_op->semaphore, timeout); DEBUG(("read wait finished result= %d\n", waitres)); if (waitres != WAIT_OBJECT_0) { DEBUG(("timeout \n")); timedout = TRUE; break; } else { DEBUG(("read signalled: nbytes: %d \n", iopipe_op->nbytes)); if (iopipe_op->nbytes <= 0) { break; } memcpy(space, iopipe_op->space, iopipe_op->nbytes); buffer_usespace(p->output, iopipe_op->nbytes); DEBUG(("buffer took on nbytes: %d \n", iopipe_op->nbytes)); } } while (1); if (timedout == FALSE) { DEBUG(("Wait for process exit\n")); // Wait until child process exits. WaitForSingleObject(pi.hProcess, INFINITE); DEBUG(("Process exited\n")); DWORD exitcode; if (GetExitCodeProcess(pi.hProcess, &exitcode)) { p->causeofdeath = PROC_NORMALDEATH; p->returncode = exitcode; DEBUG(("process exited normally = %d:\n", p->returncode)); RETURN(p); } else { p->causeofdeath = PROC_SOMEODDDEATH; p->returncode = 128; DEBUG(("process terminated \n")); RETURN(p); } } else { TerminateProcess(pi.hProcess,1); p->causeofdeath = PROC_TIMEOUTDEATH; p->returncode = 128; DEBUG(("process timedout \n")); RETURN(p); } /* Clean up the read operation queue ReadOp *r = ropq.first; do { CloseHandle(r->semaphore); free(r->space); free(r); r = r->next; } while (r != NULL); */ CLEANUP(); if (retval == NULL) { if (p) process_free(&p); } if (commandline) free(commandline); return retval; }
int main(int argc, char *argv[]) { /* find the argument to -c then strip the talon related front section */ char *recipe = NULL; int talon_returncode = 0; #ifdef HAS_WINSOCK2 WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); /* We ignore the result as we are only doing this to use gethostname and if that fails then leaving the host attribute blank is perfectly acceptable. */ #endif #ifdef HAS_GETCOMMANDLINE char *commandline= GetCommandLine(); /* * The command line should be either, * talon -c "some shell commands" * or * talon shell_script_file * * talon could be an absolute path and may have a .exe extension. */ recipe = chompCommand(commandline); if (recipe) { /* there was a -c so extract the quoted commands */ int recipelen = strlen(recipe); if (recipelen > 0 && recipe[recipelen - 1] == '"') recipe[recipelen - 1] = '\0'; /* remove trailing quote */ } else { /* there was no -c so extract the argument as a filename */ recipe = strstr(commandline, "talon"); if (recipe) { /* find the first space */ while (!isspace(*recipe) && *recipe != '\0') recipe++; /* skip past the spaces */ while (isspace(*recipe)) recipe++; recipe = read_recipe_from_file(recipe); if (!recipe) { error("talon: error: bad script file in shell call '%s'\n", commandline); return 1; } } else { error("talon: error: no 'talon' in shell call '%s'\n", commandline); return 1; } } #else /* * The command line should be either, * talon -c "some shell commands" * or * talon shell_script_file * * talon could be an absolute path and may have a .exe extension. */ switch (argc) { case 2: recipe = read_recipe_from_file(argv[1]); break; case 3: if (strcmp("-c", argv[1]) != 0) { error("talon: error: %s\n", "usage is 'talon -c command' or 'talon script_filename'"); return 1; } recipe = argv[2]; break; default: error("talon: error: %s\n", "usage is 'talon -c command' or 'talon script_filename'"); return 1; } #endif /* did we get a recipe at all? */ if (!recipe) { error("talon: error: %s", "no recipe supplied to the shell.\n"); return 1; } /* remove any leading white space on the recipe */ while (isspace(*recipe)) recipe++; /* turn debugging on? */ char *debugstr=talon_getenv("TALON_DEBUG"); if (debugstr) { loglevel=LOGDEBUG; free(debugstr); debugstr=NULL; } DEBUG(("talon: recipe: %s\n", recipe)); /* Make sure that the agent's hostname can be put into the host attribute */ char hostname[HOSTNAME_MAX]; int hostresult=0; hostresult = gethostname(hostname, HOSTNAME_MAX-1); if (0 != hostresult) { DEBUG(("talon: failed to get hostname: %d\n", hostresult)); hostname[0] = '\0'; } talon_setenv("HOSTNAME", hostname); DEBUG(("talon: setenv: hostname: %s\n", hostname)); char varname[VARNAMEMAX]; char varval[VARVALMAX]; int dotagging = 0; int force_descramble_off = 0; char *rp = recipe; if (*rp == TALONDELIMITER) { dotagging = 1; /* there are some talon-specific settings * in the command which must be stripped */ rp++; char *out = varname; char *stopout = varname + VARNAMEMAX - 1; DEBUG(("talon: parameters found\n")); while (*rp != '\0') { switch (*rp) { case '=': *out = '\0'; DEBUG(("talon: varname: %s\n",varname)); out = varval; stopout = varval + VARVALMAX - 1; break; case ';': *out = '\0'; DEBUG(("talon: varval: %s\n",varval)); talon_setenv(varname, varval); out = varname; stopout = varname + VARNAMEMAX - 1; break; default: *out = *rp; if (out < stopout) out++; break; } if (*rp == TALONDELIMITER) { rp++; break; } rp++; } } else { /* This is probably a $(shell) statement * in make so no descrambling needed and * tags are definitely not wanted as they * would corrupt the expected output*/ force_descramble_off = 1; } /* Now take settings from the environment (having potentially modified it) */ if (talon_getenv("TALON_DEBUG")) loglevel=LOGDEBUG; int enverrors = 0; char *shell = talon_getenv("TALON_SHELL"); if (!shell) { error("error: %s", "TALON_SHELL not set in environment\n"); enverrors++; } int timeout = -1; char *timeout_str = talon_getenv("TALON_TIMEOUT"); if (timeout_str) { timeout = atoi(timeout_str); free(timeout_str); timeout_str = NULL; } char *buildid = talon_getenv("TALON_BUILDID"); if (!buildid) { error("error: %s", "TALON_BUILDID not set in environment\n"); enverrors++; } char *attributes = talon_getenv("TALON_RECIPEATTRIBUTES"); if (!attributes) { error("error: %s", "TALON_RECIPEATTRIBUTES not set in environment\n"); enverrors++; } int max_retries = 0; char *retries_str = talon_getenv("TALON_RETRIES"); if (retries_str) { max_retries = atoi(retries_str); free(retries_str); retries_str = NULL; } int descramble = 0; if (! force_descramble_off ) { char *descramblestr = talon_getenv("TALON_DESCRAMBLE"); if (descramblestr) { if (*descramblestr == '0') descramble = 0; else descramble = 1; free(descramblestr); descramblestr = NULL; } } /* check command line lengths if a maximum is supplied */ int shell_cl_max = 0; char *shell_cl_max_str = talon_getenv("TALON_SHELL_CL_MAX"); if (shell_cl_max_str) { shell_cl_max = atoi(shell_cl_max_str); free(shell_cl_max_str); shell_cl_max_str = NULL; } /* Talon can look in a flags variable to alter its behaviour */ int force_success = 0; char *flags_str = talon_getenv("TALON_FLAGS"); if (flags_str) { int c; for (c=0; flags_str[c] !=0; c++) flags_str[c] = tolower(flags_str[c]); if (strstr(flags_str, "forcesuccess")) force_success = 1; /* don't put <recipe> or <CDATA<[[ tags around the output. e.g. if it's XML already*/ if (strstr(flags_str, "rawoutput")) { dotagging = 0; } free(flags_str); flags_str = NULL; } /* Talon subprocesses need to have the "correct" shell variable set. */ talon_setenv("SHELL", shell); /* we have allowed some errors to build up so that the user * can see all of them before we stop and force the user * to fix them */ if (enverrors) { return 1; } /* Run the recipe repeatedly until the retry count expires or * it succeeds. */ int attempt = 0, retries = max_retries; proc *p = NULL; char *args[5]; char *qrp=rp; #ifdef HAS_GETCOMMANDLINE /* re-quote the argument to -c since this helps windows deal with it */ int qrpsize = strlen(rp) + 3; qrp = malloc(qrpsize); qrp[0] = '"'; strcpy(&qrp[1], rp); qrp[qrpsize-2] = '"'; qrp[qrpsize-1] = '\0'; #endif int index = 0; args[index++] = shell; if (dotagging) /* don't do bash -x for non-tagged commands e.g. $(shell output) */ args[index++] = "-x"; args[index++] = "-c"; args[index++] = qrp; args[index++] = NULL; /* get the semaphore ready */ talon_sem.name = buildid; talon_sem.timeout = timeout; do { char talon_attempt[TALON_ATTEMPT_STRMAX]; double start_time = getseconds(); attempt++; snprintf(talon_attempt, TALON_ATTEMPT_STRMAX-1, "%d", attempt); talon_attempt[TALON_ATTEMPT_STRMAX - 1] = '\0'; talon_setenv("TALON_ATTEMPT", talon_attempt); p = process_run(shell, args, timeout); double end_time = getseconds(); if (p) { talon_returncode = p->returncode; if (dotagging) { char status[STATUS_STRMAX]; char timestat[STATUS_STRMAX]; char warning[WARNING_STRMAX]; warning[0] = '\0'; if (shell_cl_max) { int cl_actual = strlen(qrp); if (cl_actual > shell_cl_max) { snprintf(warning, WARNING_STRMAX-1, \ "\n<warning>Command line length '%d' exceeds the shell limit on this system of '%d'. " \ "If this recipe is a compile, try using the '.use_compilation_command_file' variant to reduce overall command line length.</warning>", \ cl_actual, shell_cl_max); warning[WARNING_STRMAX-1] = '\0'; } } char *flagsstr = force_success == 0 ? "" : " flags='FORCESUCCESS'"; char *reasonstr = "" ; if (p->causeofdeath == PROC_TIMEOUTDEATH) reasonstr = " reason='timeout'"; if (p->returncode != 0) { char *exitstr = (force_success || retries <= 0) ? "failed" : "retry"; snprintf(status, STATUS_STRMAX - 1, "\n<status exit='%s' code='%d' attempt='%d'%s%s />", exitstr, p->returncode, attempt, flagsstr, reasonstr ); } else { snprintf(status, STATUS_STRMAX - 1, "\n<status exit='ok' attempt='%d'%s%s />", attempt, flagsstr, reasonstr ); } status[STATUS_STRMAX-1] = '\0'; snprintf(timestat, STATUS_STRMAX - 1, "<time start='%.5f' elapsed='%.3f' />",start_time, end_time-start_time ); timestat[STATUS_STRMAX-1] = '\0'; prependattributes(p->output, attributes); buffer_append(p->output, "\n]]>", 4); buffer_append(p->output, timestat, strlen(timestat)); buffer_append(p->output, status, strlen(status)); buffer_append(p->output, warning, strlen(warning)); buffer_append(p->output, "\n</recipe>\n", 11); } unsigned int iterator = 0; unsigned int written = 0; byteblock *bb; char sub[7] = "�"; if (descramble) sema_wait(&talon_sem); while ((bb = buffer_getbytes(p->output, &iterator))) { if (bb->fill < 1) continue; /* empty buffer */ if (dotagging) { /* the output is XML so we must replace any non-printable characters */ char *ptr = &bb->byte0; char *end = ptr + bb->fill; char *start = ptr; while (ptr < end) { if ((*ptr < 32 || *ptr > 126) && *ptr != 9 && *ptr != 10 && *ptr != 13) { /* output any unwritten characters before this non-printable */ if (ptr > start) write(STDOUT_FILENO, start, ptr - start); /* 0->� 1-> ... 255->ÿ */ sprintf(sub, "&#x%02x;", (unsigned char)*ptr); /* output the modified non-printable character */ write(STDOUT_FILENO, sub, 6); start = ptr + 1; } ptr++; } if (ptr > start) write(STDOUT_FILENO, start, ptr - start); } else { /* the output isn't XML so write out the whole buffer as-is */ written = write(STDOUT_FILENO, &bb->byte0, bb->fill); DEBUG(("talon: wrote %d bytes out of %d\n", written, bb->fill)); } } if (descramble) sema_release(&talon_sem); if (p->returncode == 0 || force_success) { process_free(&p); break; } process_free(&p); } else { error("error: failed to run shell: %s: check the SHELL environment variable.\n", args[0]); return 1; } retries--; } while (retries >= 0); if (buildid) free(buildid); buildid = NULL; if (attributes) free(attributes); attributes = NULL; if (shell) free(shell); shell = NULL; if (force_success) return 0; else return talon_returncode; }
/** * Frees a chunk of memory. * If the memory could not be freed, a FreeException is thrown. * * @param address The address of the previously allocated memory. */ void Free(uint32_t address) { StackTrace trace(__METHOD__, __FILE__, __LINE__); if (process_free(_handle, address) == false) { throw FreeException(); } }
Process::~Process() { process_free(this->obj); }