Exemplo n.º 1
0
Arquivo: exec.c Projeto: srfrog/epic5
/*
 * close_out:  When we are done sending to a process sometimes we have to 
 * close our stdout before they will do their thing and send us data back
 * to stdin.  
 */
static void 	exec_close_out (int idx)
{
	Process *proc;

	if (valid_process_index(idx) == 0)
		return;

	proc = process_list[idx];
	if (proc->p_stdout != -1)
		proc->p_stdout = new_close(proc->p_stdout);
	if (proc->p_stderr != -1)
		proc->p_stderr = new_close(proc->p_stderr);

	proc->dumb = 1;
}
Exemplo n.º 2
0
/*
 * exec_close: silly, eh?  Well, it makes the code look nicer.  Or does it
 * really?  No.  But what the hell
 */
static int exec_close(int des)
{

    if (des == -1)
        return (-1);
    new_close(des);
    return (-1);
}
Exemplo n.º 3
0
Arquivo: exec.c Projeto: srfrog/epic5
/*
 * close_in:  When we are finished with the process but still want the
 * rest of its output, we close its input, and hopefully it will get the
 * message and close up shop.
 */
static void 	exec_close_in (int idx)
{
	Process *proc;

	if (valid_process_index(idx) == 0)
		return;

	proc = process_list[idx];
	if (proc->p_stdin != -1)
		proc->p_stdin = new_close(proc->p_stdin);
}
Exemplo n.º 4
0
Arquivo: exec.c Projeto: srfrog/epic5
/*
 * This is the back end to do_processes, saves some repeated code
 */
static void 	handle_filedesc (Process *proc, int *fd, int hook_nonl, int hook_nl)
{
	char 	exec_buffer[IO_BUFFER_SIZE + 1];
	ssize_t	len;
	int	ofs;
	const char *callback = NULL;
	int	hook = -1;
	int	l;
	char	logical_name[1024];
	const char	*utf8_text;
	char *extra = NULL;

	/* No buffering! */
	switch ((len = dgets(*fd, exec_buffer, IO_BUFFER_SIZE, 0))) 
	{
	    case -1:		/* Something died */
	    {
		*fd = new_close(*fd);
		if (proc->p_stdout == -1 && proc->p_stderr == -1)
			proc->dumb = 1;
		return;				/* PUNT! */
	    }

	    case 0:		/* We didnt get a full line */
	    {
		/* 
		 * XXX This is a hack.  dgets() can return 0 for a line
		 * containing solely a newline, as well as a line that didn't
		 * have a newline.  So we have to check to see if the line 
		 * contains only a newline!
		 */
		if (exec_buffer[0] != '\n')
		{
		    if (hook_nl == EXEC_LIST)
		    {
			if (proc->stdoutpc && *proc->stdoutpc)
			    callback = proc->stdoutpc;
		    }
		    else if (hook_nl == EXEC_ERRORS_LIST)
		    {
			if (proc->stderrpc && *proc->stderrpc)
			    callback = proc->stderrpc;
		    }
		    hook = hook_nonl;
		    break;
		}

		/* XXX HACK -- Line contains only a newline.  */
		*exec_buffer = 0;
		/* FALLTHROUGH */
	    }

	    default:		/* We got a full line */
	    {
		if (hook_nl == EXEC_LIST)
		{
		    if (proc->stdoutc && *proc->stdoutc)
			callback = proc->stdoutc;
		}
		else if (hook_nl == EXEC_ERRORS_LIST)
		{
		    if (proc->stderrc && *proc->stderrc)
			callback = proc->stderrc;
		}
		hook = hook_nl;
		break;
	    }
	}

	ofs = from_server;
	from_server = proc->server;
	if (proc->refnum)
		l = message_setall(proc->refnum, NULL, LEVEL_OTHER);
	else
		l = message_from(NULL, LEVEL_OTHER);

	proc->counter++;

	while (len > 0 && (exec_buffer[len - 1] == '\n' ||
			   exec_buffer[len - 1] == '\r'))
	     exec_buffer[--len] = 0;

	index_to_target(proc->index, logical_name, sizeof(logical_name));
	utf8_text = inbound_recode(logical_name, proc->server, empty_string, exec_buffer, &extra);

	if (proc->redirect) 
	     redirect_text(proc->server, proc->who, 
				utf8_text, proc->redirect, 1);

	if (callback)
	    call_lambda_command("EXEC", callback, utf8_text);
	else if (proc->logical)
	{
	     if ((do_hook(hook, "%s %s", proc->logical, utf8_text)))
		if (!proc->redirect)
		    put_it("%s", utf8_text);
	}
	else
	{
	    if ((do_hook(hook, "%d %s", proc->index, utf8_text)))
		if (!proc->redirect)
		    put_it("%s", utf8_text);
	}

	new_free(&extra);
	pop_message_from(l);
	from_server = ofs;
}
Exemplo n.º 5
0
Arquivo: exec.c Projeto: srfrog/epic5
/*
 * This function is called by the three places that can effect a change
 * on the state of a running process:
 * 	1) get_child_exit, which can mark a process as exited
 *	2) do_processes, which can mark a child as being done with I/O
 *	3) execcmd, which can mark a child as being done with I/O
 *
 * Any processes that are found to have both exited and having completed
 * their I/O will be summarily destroyed.
 */
static void 	cleanup_dead_processes (void)
{
	int	i;
	List	*cmd,
		*next;
	Process *deadproc, *proc;
	char	*exit_info;
	int	old_from_server, l;

	if (!process_list)
		return;		/* Nothing to do */

	old_from_server = from_server;
	for (i = 0; i < process_list_size; i++)
	{
		if (!(proc = process_list[i]))
			continue;

		/*
		 * We do not parse the process if it has not 
		 * both exited and finished its io, UNLESS
		 * it has been disowned.
		 */
		if ((!proc->exited || !proc->dumb) && !proc->disowned)
			continue;		/* Not really dead yet */

		deadproc = process_list[i];
		process_list[i] = NULL;

		/*
		 * First thing to do is fill out the exit information
		 */
		if (deadproc->logical)
		{
			size_t	len = strlen(deadproc->logical) + 25;

			exit_info = alloca(len);
			snprintf(exit_info, len, "%s %d %d", 
					deadproc->logical, deadproc->termsig,
					deadproc->retcode);
		}
		else
		{
			exit_info = alloca(40);
			snprintf(exit_info, 32, "%d %d %d",
				deadproc->index, deadproc->termsig, deadproc->retcode);
		}

		from_server = deadproc->server;
		l = message_from(NULL, LEVEL_OTHER);

		/*
		 * First thing we do is run any /wait %proc -cmd commands
		 */
		next = deadproc->waitcmds;
		deadproc->waitcmds = NULL;
		while ((cmd = next))
		{
			next = cmd->next;
			call_lambda_command("WAITPROC", cmd->name, exit_info);
			new_free(&cmd->name);
			new_free((char **)&cmd);
		}

		/*
		 * Throw /on exec_exit
		 */
		if (do_hook(EXEC_EXIT_LIST, "%s", exit_info))
		{
		    if (get_int_var(NOTIFY_ON_TERMINATION_VAR))
		    {
			if (deadproc->termsig > 0 && deadproc->termsig < NSIG)
			{
				say("Process %d (%s) terminated "
					"with signal %s (%d)", 
				   deadproc->index, deadproc->name, 
				   sys_siglist[deadproc->termsig], 
				   deadproc->termsig);
			}
			else if (deadproc->disowned)
			{
				say("Process %d (%s) disowned", 
				   deadproc->index, deadproc->name);
			}
			else
			{
				say("Process %d (%s) terminated "
					"with return code %d", 
				   deadproc->index, deadproc->name, 
				   deadproc->retcode);
			}
		    }
		}
		pop_message_from(l);

		deadproc->p_stdin = new_close(deadproc->p_stdin);
		deadproc->p_stdout = new_close(deadproc->p_stdout);
		deadproc->p_stderr = new_close(deadproc->p_stderr);
		new_free(&deadproc->name);
		new_free(&deadproc->logical);
		new_free(&deadproc->who);
		new_free(&deadproc->redirect);
		new_free(&deadproc->stdoutc);
		new_free(&deadproc->stdoutpc);
		new_free(&deadproc->stderrc);
		new_free(&deadproc->stderrpc);
		new_free((char **)&deadproc);
	}

	/*
	 * Resize away any dead processes at the end
	 */
	for (i = process_list_size - 1; i >= 0; i--)
	{
		if (process_list[i])
			break;
	}

	if (process_list_size != i + 1)
	{
		process_list_size = i + 1;
		RESIZE(process_list, Process, process_list_size);
	}

	from_server = old_from_server;
}
Exemplo n.º 6
0
/*
 * This is the back end to do_processes, saves some repeated code
 */
static void 	handle_filedesc (Process *proc, int *fd, int hook_nonl, int hook_nl)
{
	char 	exec_buffer[IO_BUFFER_SIZE + 1];
	ssize_t	len;

	switch ((len = dgets(*fd, exec_buffer, IO_BUFFER_SIZE, 0, NULL))) /* No buffering! */
	{
		case -1:	/* Something died */
		{
			*fd = new_close(*fd);
			if (proc->p_stdout == -1 && proc->p_stderr == -1)
				proc->dumb = 1;
			break;
		}
		case 0:		/* We didnt get a full line */
		{
			/* 
			 * XXX XXX Major, world class hack here XXX XXX 
			 * Since this problem has been addressed already
			 * by newio2.c, it doesn't matter if we just fix the
			 * symptom here since this code is all obsolete.
			 */
			if (exec_buffer[0] == '\n')
			{
				exec_buffer[0] = 0;
				goto this_sucks;
			}

			     if (hook_nl == EXEC_LIST && proc->stdoutpc && *proc->stdoutpc)
				parse_line("EXEC", proc->stdoutpc, 
						exec_buffer, 0, 0);
			else if (hook_nl == EXEC_ERRORS_LIST && proc->stderrpc && *proc->stderrpc)
				parse_line("EXEC", proc->stderrpc, 
						exec_buffer, 0, 0);
			else if (proc->logical)
				do_hook(hook_nonl, "%s %s", 
					proc->logical, exec_buffer);
			else
				do_hook(hook_nonl, "%d %s", 
					proc->index, exec_buffer);

			set_prompt_by_refnum(proc->refnum, exec_buffer);
			break;
		}
		default:	/* We got a full line */
this_sucks:
		{
			int ofs;

			ofs = from_server;
			from_server = proc->server;
			if (proc->refnum)
				message_to(proc->refnum);
			proc->counter++;

			while (len > 0 && (exec_buffer[len] == '\n' ||
					   exec_buffer[len] == '\r'))
			{
				exec_buffer[len--] = 0;
			}

			if (proc->redirect) 
				redirect_text(proc->server, proc->who, 
					exec_buffer, proc->redirect, 1);

			if (hook_nl == EXEC_LIST && proc->stdoutc && *proc->stdoutc)
				parse_line("EXEC", proc->stdoutc, 
						exec_buffer, 0, 0);
			else if (hook_nl == EXEC_ERRORS_LIST && proc->stderrc && *proc->stderrc)
				parse_line("EXEC", proc->stderrc, 
						exec_buffer, 0, 0);
			else if (proc->logical)
			{
				if ((do_hook(hook_nl, "%s %s", 
						proc->logical, exec_buffer)))
					if (!proc->redirect)
						put_it("%s", exec_buffer);
			}
			else
			{
				if ((do_hook(hook_nl, "%d %s", 
						proc->index, exec_buffer)))
					if (!proc->redirect)
						put_it("%s", exec_buffer);
			}

			message_to(-1);
			from_server = ofs;
		}
	}
}