diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2010-05-25 12:14:06 +0100 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2010-12-02 16:00:44 -0700 |
commit | f16ad06fb2aeb5e5c9974b20d91800d1f6b5cc1d (patch) | |
tree | 3142609ab0a3b6d3c917be8d0de8e05ccf625f6f /tests/commandhelper.c | |
parent | util: add virVasprintf (diff) | |
download | libvirt-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.c | 137 |
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; +} |