#include <errno.h>
#include <stdio.h>
#include <string.h>
+#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
return boost::shared_array<char *> (ret);
}
+/** @brief Helper for redirecting a file descriptor to \c /dev/null.
+ * This will only acquire an fd the first time it is called
+ * or if it is called after unsuccessfully attempting to
+ * acquire one.
+ *
+ * @param fd The open file descriptor to operate on.
+ *
+ * @returns \c true on success, \c false otherwise (the call to
+ * either \c open(2) or \c dup2(2) failed).
+ */
+static bool
+redirect_devnull (const int fd)
+{
+ static int nullfd = -1;
+
+ errno = 0;
+ if (nullfd == -1 && (nullfd = open ("/dev/null", O_RDWR)) == -1) {
+ return false;
+ }
+
+ errno = 0;
+ if (dup2 (nullfd, fd) == -1) {
+ return false;
+ }
+
+ return true;
+}
+
/** @brief Helper aggregating common code for the shell-free ctors.
*
* @param argv Argument list prepared for \c execve(2).
close (pipefd [0]);
if (!out) {
- close (STDOUT_FILENO);
+ if (!redirect_devnull (STDOUT_FILENO)) {
+ fprintf(stderr, "redirect_devnull/stdout: %m\n");
+ /* XXX should we bail here? */
+ }
} else if (dup2 (pipefd[1], STDOUT_FILENO) == -1) {
fprintf(stderr, "dup2/stdout: %m\n");
exit(EXIT_FAILURE);
}
if (!err) {
- close (STDERR_FILENO);
+ if (!redirect_devnull (STDERR_FILENO)) {
+ fprintf(stderr, "redirect_devnull/stderr: %m\n");
+ /* XXX should we bail here? */
+ }
} else if (dup2 (pipefd[1], STDERR_FILENO) == -1) {
fprintf(stderr, "dup2/stderr: %m\n");
exit(EXIT_FAILURE);