示例#1
0
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);
}
示例#2
0
/*
   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;
}
示例#3
0
文件: eng.c 项目: colinbouvry/minuit
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);
	}
}
示例#4
0
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;
}
示例#5
0
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, &params, &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);
}
示例#6
0
文件: process.c 项目: catseye/Bhuna
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;
	}
}
示例#7
0
/*
 * 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);
    }
}
示例#8
0
/*
   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;
}
示例#9
0
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;
}
示例#10
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;
}
示例#11
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);
}
示例#12
0
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);
}
示例#13
0
void host_freeAllApplications(Host* host) {
	MAGIC_ASSERT(host);
	while(!g_queue_is_empty(host->applications)) {
		process_free(g_queue_pop_head(host->applications));
	}
}
示例#14
0
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;
}
示例#15
0
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] = "&#x00;";
			
			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->&#x00; 1->&#x01; ... 255->&#xff; */
							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;
}
示例#16
0
	/**
	 * 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();
		}
	}
示例#17
0
文件: la_process.c 项目: Laukien/la-C
		Process::~Process() {
			process_free(this->obj);
		}