summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/run.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/run.c')
-rw-r--r--libglusterfs/src/run.c147
1 files changed, 92 insertions, 55 deletions
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index 41601209c..4fd2a3a0d 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _GNU_SOURCE
@@ -30,7 +21,9 @@
#include <fcntl.h>
#include <dirent.h>
#include <assert.h>
+#include <signal.h>
#include <sys/wait.h>
+#include <sys/resource.h>
#ifdef RUN_STANDALONE
#define GF_CALLOC(n, s, t) calloc(n, s)
@@ -74,7 +67,10 @@ runner_chio (runner_t *runner, int fd)
{
GF_ASSERT (fd > 0 && fd < 3);
- return runner->chio[fd];
+ if ((fd > 0) && (fd < 3))
+ return runner->chio[fd];
+
+ return NULL;
}
static void
@@ -191,7 +187,7 @@ runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
if (len > 0)
buf[len - 1] = '\0';
- gf_log (dom, lvl, "%s: %s", msg, buf);
+ gf_log_callingfn (dom, lvl, "%s: %s", msg, buf);
GF_FREE (buf);
}
@@ -201,7 +197,8 @@ runner_redir (runner_t *runner, int fd, int tgt_fd)
{
GF_ASSERT (fd > 0 && fd < 3);
- runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
+ if ((fd > 0) && (fd < 3))
+ runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
}
int
@@ -257,8 +254,26 @@ runner_start (runner_t *runner)
close (pi[i][i ? 0 : 1]);
close (xpi[0]);
ret = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (ret == -1)
+ break;
+ switch (runner->chfd[i]) {
+ case -1:
+ /* no redir */
+ break;
+ case -2:
+ /* redir to pipe */
+ ret = dup2 (pi[i][i ? 1 : 0], i);
+ break;
+ default:
+ /* redir to file */
+ ret = dup2 (runner->chfd[i], i);
+ }
+ }
+
+ if (ret != -1 ) {
#ifdef GF_LINUX_HOST_OS
- {
DIR *d = NULL;
struct dirent *de = NULL;
char *e = NULL;
@@ -267,42 +282,23 @@ runner_start (runner_t *runner)
if (d) {
while ((de = readdir (d))) {
i = strtoul (de->d_name, &e, 10);
- if (*e == '\0' &&
- i > 2 && i != dirfd (d) &&
- i != pi[0][0] && i != pi[1][1] &&
- i != pi[2][1] && i != xpi[1])
+ if (*e == '\0' && i > 2 &&
+ i != dirfd (d) && i != xpi[1])
close (i);
}
closedir (d);
} else
ret = -1;
- }
#else
- for (i = 3; i < 65536; i++) {
- if (i != pi[0][0] && i != pi[1][1] &&
- i != pi[2][1] && i != xpi[1])
- close (i);
- }
-#endif
+ struct rlimit rl;
+ ret = getrlimit (RLIMIT_NOFILE, &rl);
+ GF_ASSERT (ret == 0);
- for (i = 0; i < 3; i++) {
- if (ret == -1)
- break;
- switch (runner->chfd[i]) {
- case -1:
- /* no redir */
- break;
- case -2:
- /* redir to pipe */
- ret = dup2 (pi[i][i ? 1 : 0], i);
- errno_priv = errno;
- close (pi[i][i ? 1 : 0]);
- errno = errno_priv;
- break;
- default:
- /* redir to file */
- ret = dup2 (runner->chfd[i], i);
+ for (i = 3; i < rl.rlim_cur; i++) {
+ if (i != xpi[1])
+ close (i);
}
+#endif
}
if (ret != -1) {
@@ -369,9 +365,11 @@ runner_end (runner_t *runner)
ret = runner_end_reuse (runner);
- for (p = runner->argv; *p; p++)
- GF_FREE (*p);
- GF_FREE (runner->argv);
+ if (runner->argv) {
+ for (p = runner->argv; *p; p++)
+ GF_FREE (*p);
+ GF_FREE (runner->argv);
+ }
for (i = 0; i < 3; i++)
close (runner->chfd[i]);
@@ -384,10 +382,8 @@ runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
int ret = 0;
ret = runner_start (runner);
- if (ret != 0)
- return -1;
- return rfin (runner) ? -1 : 0;
+ return -(rfin (runner) || ret);
}
int
@@ -396,6 +392,25 @@ runner_run (runner_t *runner)
return runner_run_generic (runner, runner_end);
}
+
+int
+runner_run_nowait (runner_t *runner)
+{
+ int pid;
+
+ pid = fork ();
+
+ if (!pid) {
+ setsid ();
+ _exit (runner_start (runner));
+ }
+
+ if (pid > 0)
+ runner->chpid = pid;
+ return runner_end (runner);
+}
+
+
int
runner_run_reuse (runner_t *runner)
{
@@ -427,13 +442,16 @@ TBANNER (const char *txt)
}
int
-main ()
+main (int argc, char **argv)
{
runner_t runner;
char buf[80];
char *wdbuf;;
int ret;
+ int fd;
long pathmax = pathconf ("/", _PC_PATH_MAX);
+ struct timeval tv = {0,};
+ struct timeval *tvp = NULL;
wdbuf = malloc (pathmax);
assert (wdbuf);
@@ -471,6 +489,25 @@ main ()
ret = runcmd ("bafflavvitty", NULL);
printf ("%d %d [%s]\n", ret, errno, strerror (errno));
+ TBANNER ("output redirection");
+ fd = mkstemp ("/tmp/foof");
+ assert (fd != -1);
+ runinit (&runner);
+ runner_add_args (&runner, "echo", "foo", NULL);
+ runner_redir (&runner, 1, fd);
+ ret = runner_run (&runner);
+ printf ("%d", ret);
+ if (ret != 0)
+ printf (" %d [%s]", errno, strerror (errno));
+ putchar ('\n');
+
+ if (argc > 1) {
+ tv.tv_sec = strtoul (argv[1], NULL, 10);
+ if (tv.tv_sec > 0)
+ tvp = &tv;
+ select (0, 0, 0, 0, tvp);
+ }
+
return 0;
}
#endif