Example #1
0
int
run_in_shell_no_cls(char command[])
{
	typedef void (*sig_handler)(int);

	int pid;
	int result;
	extern char **environ;
	sig_handler sigtstp_handler;

	if(command == NULL)
		return 1;

	sigtstp_handler = signal(SIGTSTP, SIG_DFL);

	/* We need to block SIGCHLD signal.  One can't just set it to SIG_DFL, because
	 * it will possibly cause missing of SIGCHLD from a background process
	 * (job). */
	(void)set_sigchld(1);

	pid = fork();
	if(pid == -1)
	{
		signal(SIGTSTP, sigtstp_handler);
		(void)set_sigchld(0);
		return -1;
	}
	if(pid == 0)
	{
		char *args[4];

		signal(SIGTSTP, SIG_DFL);
		signal(SIGINT, SIG_DFL);
		(void)set_sigchld(0);

		args[0] = cfg.shell;
		args[1] = "-c";
		args[2] = command;
		args[3] = NULL;
		execve(cfg.shell, args, environ);
		exit(127);
	}

	result = get_proc_exit_status(pid);

	signal(SIGTSTP, sigtstp_handler);
	(void)set_sigchld(0);

	return result;
}
Example #2
0
int
background_and_wait_for_errors(char cmd[], int cancellable)
{
#ifndef _WIN32
	pid_t pid;
	int error_pipe[2];
	int result = 0;

	if(pipe(error_pipe) != 0)
	{
		error_msg("File pipe error", "Error creating pipe");
		return -1;
	}

	(void)set_sigchld(1);

	if((pid = fork()) == -1)
	{
		(void)set_sigchld(0);
		return -1;
	}

	if(pid == 0)
	{
		(void)set_sigchld(0);
		run_from_fork(error_pipe, 1, cmd);
	}
	else
	{
		char buf[80*10];
		char linebuf[80];
		int nread = 0;

		close(error_pipe[1]); /* Close write end of pipe. */

		if(cancellable)
		{
			ui_cancellation_enable();
		}

		wait_for_data_from(pid, NULL, error_pipe[0]);

		buf[0] = '\0';
		while((nread = read(error_pipe[0], linebuf, sizeof(linebuf) - 1)) > 0)
		{
			const int read_empty_line = nread == 1 && linebuf[0] == '\n';
			result = -1;
			linebuf[nread] = '\0';

			if(!read_empty_line)
			{
				strncat(buf, linebuf, sizeof(buf) - strlen(buf) - 1);
			}

			wait_for_data_from(pid, NULL, error_pipe[0]);
		}
		close(error_pipe[0]);

		if(cancellable)
		{
			ui_cancellation_disable();
		}

		if(result != 0)
		{
			error_msg("Background Process Error", buf);
		}
		else
		{
			/* Don't use "const int" variables with WEXITSTATUS() as they cause
			 * compilation errors in case __USE_BSD is defined.  Anonymous type with
			 * "const int" is composed via compound literal expression. */
			int status = get_proc_exit_status(pid);
			result = (status != -1 && WIFEXITED(status)) ? WEXITSTATUS(status) : -1;
		}
	}

	(void)set_sigchld(0);

	return result;
#else
	return -1;
#endif
}