Example #1
0
void* sendChildOutputToSyslogThread(void *p) {
    int error = EXIT_SUCCESS;
    sigset_t blockedSignalsMask;
    outputToSyslogParam *params = (outputToSyslogParam*) p;
    char buffer[MAXLINE];
    ssize_t n;

    sigemptyset(&blockedSignalsMask);
    sigaddset(&blockedSignalsMask, SIGCHLD);
    error = pthread_sigmask(SIG_BLOCK, &blockedSignalsMask, NULL);
    if (error != 0) {
        WARNING_MSG("pthread_sigmask error %d (%m)", error);
    }

    while ((n = read(params->pipe, buffer, sizeof (buffer))) > 0) {
        buffer[n] = '\0';
        DEBUG_VAR(buffer, "%s");
        __syslogex_pid_chk(params->pid, params->level, -1, buffer);
    }

    if (n != 0) {
        const int error = errno;
        ERROR_MSG("read from %d error %d (%m)", params->pipe, error);
    }
    CLOSE_PIPE(params->pipe);
    return NULL;
}
Example #2
0
static inline int execChild(const char *file, char *argv[], int stdoutWritePipe, int stderrWritePipe) {
    int error = EXIT_SUCCESS;

    if (dup2(stdoutWritePipe, STDOUT_FILENO) != -1) { /* close stdout and redirect it to the pipe */
        if (dup2(stderrWritePipe, STDERR_FILENO) != -1) { /* close stderr and redirect it to the pipe */
            //DEBUG_VAR(file,"%s");
            //DEBUG_VAR(argv[0],"%s");
            //usleep(500);
            if (execvp(file, argv)) {
                error = errno;
                ERROR_MSG("execvp error %d (%m)", error);
            }
        } else {
            int error = errno;
            ERROR_MSG("dup2 stderr error %d (%m)", error);
        }
    } else {
        int error = errno;
        ERROR_MSG("dup2 stdout error %d (%m)", error);
    }
    CLOSE_PIPE(stdoutWritePipe);
    CLOSE_PIPE(stderrWritePipe);
    return error;
}
Example #3
0
/*
 * This is the only use we have in mono/metadata
!g_spawn_async_with_pipes (NULL, (char**)addr_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, &ch_in, &ch_out, NULL, NULL)
*/
gboolean
g_spawn_async_with_pipes (const gchar *working_directory,
			gchar **argv,
			gchar **envp,
			GSpawnFlags flags,
			GSpawnChildSetupFunc child_setup,
			gpointer user_data,
			GPid *child_pid,
			gint *standard_input,
			gint *standard_output,
			gint *standard_error,
			GError **error)
{
#ifdef G_OS_WIN32
#else
	pid_t pid;
	int info_pipe [2];
	int in_pipe [2] = { -1, -1 };
	int out_pipe [2] = { -1, -1 };
	int err_pipe [2] = { -1, -1 };
	int status;

	g_return_val_if_fail (argv != NULL, FALSE); /* Only mandatory arg */

	if (!create_pipe (info_pipe, error))
		return FALSE;

	if (standard_output && !create_pipe (out_pipe, error)) {
		CLOSE_PIPE (info_pipe);
		return FALSE;
	}

	if (standard_error && !create_pipe (err_pipe, error)) {
		CLOSE_PIPE (info_pipe);
		CLOSE_PIPE (out_pipe);
		return FALSE;
	}

	if (standard_input && !create_pipe (in_pipe, error)) {
		CLOSE_PIPE (info_pipe);
		CLOSE_PIPE (out_pipe);
		CLOSE_PIPE (err_pipe);
		return FALSE;
	}

	pid = fork ();
	if (pid == -1) {
		CLOSE_PIPE (info_pipe);
		CLOSE_PIPE (out_pipe);
		CLOSE_PIPE (err_pipe);
		CLOSE_PIPE (in_pipe);
		set_error ("%s", "Error in fork ()");
		return FALSE;
	}

	if (pid == 0) {
		/* No zombie left behind */
		if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) {
			pid = fork ();
		}

		if (pid != 0) {
			exit (pid == -1 ? 1 : 0);
		}  else {
			gint i;
			int fd;
			gchar *arg0;
			gchar **actual_args;
			gint unused;

			close (info_pipe [0]);
			close (in_pipe [1]);
			close (out_pipe [0]);
			close (err_pipe [0]);

			/* when exec* succeeds, we want to close this fd, which will return
			 * a 0 read on the parent. We're not supposed to keep it open forever.
			 * If exec fails, we still can write the error to it before closing.
			 */
			fcntl (info_pipe [1], F_SETFD, FD_CLOEXEC);

			if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) {
				pid = getpid ();
				NO_INTR (unused, write_all (info_pipe [1], &pid, sizeof (pid_t)));
			}

			if (working_directory && chdir (working_directory) == -1) {
				int err = errno;
				NO_INTR (unused, write_all (info_pipe [1], &err, sizeof (int)));
				exit (0);
			}

			if (standard_output) {
				dup2 (out_pipe [1], STDOUT_FILENO);
			} else if ((flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0) {
				fd = open ("/dev/null", O_WRONLY);
				dup2 (fd, STDOUT_FILENO);
			}

			if (standard_error) {
				dup2 (err_pipe [1], STDERR_FILENO);
			} else if ((flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0) {
				fd = open ("/dev/null", O_WRONLY);
				dup2 (fd, STDERR_FILENO);
			}

			if (standard_input) {
				dup2 (in_pipe [0], STDIN_FILENO);
			} else if ((flags & G_SPAWN_CHILD_INHERITS_STDIN) == 0) {
				fd = open ("/dev/null", O_RDONLY);
				dup2 (fd, STDIN_FILENO);
			}

			if ((flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN) != 0) {
				for (i = getdtablesize () - 1; i >= 3; i--)
					close (i);
			}

			actual_args = ((flags & G_SPAWN_FILE_AND_ARGV_ZERO) == 0) ? argv : argv + 1;
			if (envp == NULL)
				envp = environ;

			if (child_setup)
				child_setup (user_data);

			arg0 = argv [0];
			if (!g_path_is_absolute (arg0) || (flags & G_SPAWN_SEARCH_PATH) != 0) {
				arg0 = g_find_program_in_path (argv [0]);
				if (arg0 == NULL) {
					int err = ENOENT;
					write_all (info_pipe [1], &err, sizeof (int));
					exit (0);
				}
			}

			execve (arg0, actual_args, envp);
			write_all (info_pipe [1], &errno, sizeof (int));
			exit (0);
		}
	} else if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) {
		int w;
		/* Wait for the first child if two are created */
		NO_INTR (w, waitpid (pid, &status, 0));
		if (status == 1 || w == -1) {
			CLOSE_PIPE (info_pipe);
			CLOSE_PIPE (out_pipe);
			CLOSE_PIPE (err_pipe);
			CLOSE_PIPE (in_pipe);
			set_error ("Error in fork (): %d", status);
			return FALSE;
		}
	}
	close (info_pipe [1]);
	close (in_pipe [0]);
	close (out_pipe [1]);
	close (err_pipe [1]);

	if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) {
		int x;
		NO_INTR (x, read (info_pipe [0], &pid, sizeof (pid_t))); /* if we read < sizeof (pid_t)... */
	}

	if (child_pid) {
		*child_pid = pid;
	}

	if (read (info_pipe [0], &status, sizeof (int)) != 0) {
		close (info_pipe [0]);
		close (in_pipe [0]);
		close (out_pipe [1]);
		close (err_pipe [1]);
		set_error_status (status, "Error in exec (%d -> %s)", status, strerror (status));
		return FALSE;
	}

	close (info_pipe [0]);
	if (standard_input)
		*standard_input = in_pipe [1];
	if (standard_output)
		*standard_output = out_pipe [0];
	if (standard_error)
		*standard_error = err_pipe [0];
#endif
	return TRUE;
}
Example #4
0
gboolean
g_spawn_command_line_sync (const gchar *command_line,
				gchar **standard_output,
				gchar **standard_error,
				gint *exit_status,
				GError **error)
{
#ifdef G_OS_WIN32
#else
	pid_t pid;
	gchar **argv;
	gint argc;
	int stdout_pipe [2] = { -1, -1 };
	int stderr_pipe [2] = { -1, -1 };
	int status;
	int res;
	
	if (!g_shell_parse_argv (command_line, &argc, &argv, error))
		return FALSE;

	if (standard_output && !create_pipe (stdout_pipe, error))
		return FALSE;

	if (standard_error && !create_pipe (stderr_pipe, error)) {
		if (standard_output) {
			CLOSE_PIPE (stdout_pipe);
		}
		return FALSE;
	}

	pid = fork ();
	if (pid == 0) {
		gint i;

		if (standard_output) {
			close (stdout_pipe [0]);
			dup2 (stdout_pipe [1], STDOUT_FILENO);
		}

		if (standard_error) {
			close (stderr_pipe [0]);
			dup2 (stderr_pipe [1], STDERR_FILENO);
		}
		for (i = getdtablesize () - 1; i >= 3; i--)
			close (i);

		/* G_SPAWN_SEARCH_PATH is always enabled for g_spawn_command_line_sync */
		if (!g_path_is_absolute (argv [0])) {
			gchar *arg0;

			arg0 = g_find_program_in_path (argv [0]);
			if (arg0 == NULL) {
				exit (1);
			}
			//g_free (argv [0]);
			argv [0] = arg0;
		}
		execv (argv [0], argv);
		exit (1); /* TODO: What now? */
	}

	g_strfreev (argv);
	if (standard_output)
		close (stdout_pipe [1]);

	if (standard_error)
		close (stderr_pipe [1]);

	if (standard_output || standard_error) {
		res = read_pipes (stdout_pipe [0], standard_output, stderr_pipe [0], standard_error, error);
		if (res) {
			waitpid (pid, &status, WNOHANG); /* avoid zombie */
			return FALSE;
		}
	}

	NO_INTR (res, waitpid (pid, &status, 0));

	/* TODO: What if error? */
	if (WIFEXITED (status) && exit_status) {
		*exit_status = WEXITSTATUS (status);
	}
#endif
	return TRUE;
}