aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2010-05-25 12:14:06 +0100
committerEric Blake <eblake@redhat.com>2010-12-02 16:00:44 -0700
commitf16ad06fb2aeb5e5c9974b20d91800d1f6b5cc1d (patch)
tree3142609ab0a3b6d3c917be8d0de8e05ccf625f6f /tests/commandhelper.c
parentutil: add virVasprintf (diff)
downloadlibvirt-f16ad06fb2aeb5e5c9974b20d91800d1f6b5cc1d.tar.gz
libvirt-f16ad06fb2aeb5e5c9974b20d91800d1f6b5cc1d.tar.bz2
libvirt-f16ad06fb2aeb5e5c9974b20d91800d1f6b5cc1d.zip
Introduce new APIs for spawning processes
This introduces a new set of APIs in src/util/command.h to use for invoking commands. This is intended to replace all current usage of virRun and virExec variants, with a more flexible and less error prone API. * src/util/command.c: New file. * src/util/command.h: New header. * src/Makefile.am (UTIL_SOURCES): Build it. * src/libvirt_private.syms: Export symbols internally. * tests/commandtest.c: New test. * tests/Makefile.am (check_PROGRAMS): Run it. * tests/commandhelper.c: Auxiliary program. * tests/commanddata/test2.log - test15.log: New expected outputs. * cfg.mk (useless_free_options): Add virCommandFree. (msg_gen_function): Add virCommandError. * po/POTFILES.in: New translation. * .x-sc_avoid_write: Add exemption. * tests/.gitignore: Ignore new built file.
Diffstat (limited to 'tests/commandhelper.c')
-rw-r--r--tests/commandhelper.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/tests/commandhelper.c b/tests/commandhelper.c
new file mode 100644
index 000000000..2ee9153d7
--- /dev/null
+++ b/tests/commandhelper.c
@@ -0,0 +1,137 @@
+/*
+ * commandhelper.c: Auxiliary program for commandtest
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "internal.h"
+#include "util.h"
+#include "memory.h"
+#include "files.h"
+
+
+static int envsort(const void *a, const void *b) {
+ const char *const*astrptr = a;
+ const char *const*bstrptr = b;
+ const char *astr = *astrptr;
+ const char *bstr = *bstrptr;
+ char *aeq = strchr(astr, '=');
+ char *beq = strchr(bstr, '=');
+ char *akey = strndup(astr, aeq - astr);
+ char *bkey = strndup(bstr, beq - bstr);
+ int ret = strcmp(akey, bkey);
+ free(akey);
+ free(bkey);
+ return ret;
+}
+
+int main(int argc, char **argv) {
+ int i, n;
+ char **origenv;
+ char **newenv;
+ FILE *log = fopen(abs_builddir "/commandhelper.log", "w");
+
+ if (!log)
+ goto error;
+
+ for (i = 1 ; i < argc ; i++) {
+ fprintf(log, "ARG:%s\n", argv[i]);
+ }
+
+ origenv = environ;
+ n = 0;
+ while (*origenv != NULL) {
+ n++;
+ origenv++;
+ }
+
+ if (VIR_ALLOC_N(newenv, n) < 0) {
+ exit(EXIT_FAILURE);
+ }
+
+ origenv = environ;
+ n = i = 0;
+ while (*origenv != NULL) {
+ newenv[i++] = *origenv;
+ n++;
+ origenv++;
+ }
+ qsort(newenv, n, sizeof(newenv[0]), envsort);
+
+ for (i = 0 ; i < n ; i++) {
+ fprintf(log, "ENV:%s\n", newenv[i]);
+ }
+
+ for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++) {
+ int f;
+ int closed;
+ if (i == fileno(log))
+ continue;
+ closed = fcntl(i, F_GETFD, &f) == -1 &&
+ errno == EBADF;
+ if (!closed)
+ fprintf(log, "FD:%d\n", i);
+ }
+
+ fprintf(log, "DAEMON:%s\n", getppid() == 1 ? "yes" : "no");
+ char cwd[1024];
+ getcwd(cwd, sizeof(cwd));
+ if (strlen(cwd) > strlen("/commanddata") &&
+ STREQ(cwd + strlen(cwd) - strlen("/commanddata"), "/commanddata"))
+ strcpy(cwd, ".../commanddata");
+ fprintf(log, "CWD:%s\n", cwd);
+
+ VIR_FORCE_FCLOSE(log);
+
+ char buf[1024];
+ ssize_t got;
+
+ fprintf(stdout, "BEGIN STDOUT\n");
+ fflush(stdout);
+ fprintf(stderr, "BEGIN STDERR\n");
+ fflush(stderr);
+
+ for (;;) {
+ got = read(STDIN_FILENO, buf, sizeof(buf));
+ if (got < 0)
+ goto error;
+ if (got == 0)
+ break;
+ if (safewrite(STDOUT_FILENO, buf, got) != got)
+ goto error;
+ if (safewrite(STDERR_FILENO, buf, got) != got)
+ goto error;
+ }
+
+ fprintf(stdout, "END STDOUT\n");
+ fflush(stdout);
+ fprintf(stderr, "END STDERR\n");
+ fflush(stderr);
+
+ return EXIT_SUCCESS;
+
+error:
+ return EXIT_FAILURE;
+}