From db1227ab769b71abad0ef9291a9ceb43435bfc55 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sun, 28 Dec 2008 04:34:27 +0100 Subject: [PATCH] libxbps: add fexec.c from NetBSD's pkg_install, with some minor mods. --HG-- extra : convert_revision : 42a4231615746fdc21c826d7f5c1ccbe5ea7a6e2 --- include/fexec.h | 37 +++++++++++ include/xbps_api.h | 1 + lib/Makefile | 2 +- lib/fexec.c | 153 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 include/fexec.h create mode 100644 lib/fexec.c diff --git a/include/fexec.h b/include/fexec.h new file mode 100644 index 00000000000..b753ccae593 --- /dev/null +++ b/include/fexec.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBPS_FEXEC_H_ +#define _XBPS_FEXEC_H_ + +int xbps_file_exec(const char *, ...); +int xbps_file_exec_skipempty(const char *, ...); +int xbps_file_chdir_exec(const char *, const char *, ...); + +#endif diff --git a/include/xbps_api.h b/include/xbps_api.h index 4c5f0ef8659..ccec5c13764 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -58,5 +58,6 @@ #include "plist.h" #include "sha256.h" #include "queue.h" +#include "fexec.h" #endif /* !_XBPS_API_H_ */ diff --git a/lib/Makefile b/lib/Makefile index d14e186374b..e8aa2b25b6f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ LIBXBPS = libxbps.so LIBXBPS_LDFLAGS = -larchive -lprop -shared -Wl,-soname,$(LIBXBPS).$(MAJOR) OBJECTS = cmpver.o depends.o humanize_number.o install.o plist.o -OBJECTS += sha256.o util.o repository.o +OBJECTS += sha256.o util.o repository.o fexec.o all: $(LIBXBPS) .PHONY: all diff --git a/lib/fexec.c b/lib/fexec.c new file mode 100644 index 00000000000..4f10078e88c --- /dev/null +++ b/lib/fexec.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int vfcexec(const char *, int, const char *, va_list); +static int pfcexec(const char *, const char *, const char **); + +/* + * fork, then change current working directory to path and + * execute the command and arguments in the argv array. + * wait for the command to finish, then return the exit status. + */ +static int +pfcexec(const char *path, const char *file, const char **argv) +{ + pid_t child; + int status; + + child = vfork(); + switch (child) { + case 0: + if ((path != NULL) && (chdir(path) < 0)) + _exit(127); + + (void)execvp(file, (char ** const)argv); + _exit(127); + /* NOTREACHED */ + case -1: + return -1; + } + + while (waitpid(child, &status, 0) < 0) { + if (errno != EINTR) + return -1; + } + + if (!WIFEXITED(status)) + return -1; + + return WEXITSTATUS(status); +} + +static int +vfcexec(const char *path, int skipempty, const char *arg, va_list ap) +{ + const char **argv; + size_t argv_size, argc; + int retval; + + argv_size = 16; + if ((argv = malloc(argv_size * sizeof(*argv))) == NULL) { + errno = ENOMEM; + return -1; + } + + argv[0] = arg; + argc = 1; + + do { + if (argc == argv_size) { + argv_size *= 2; + argv = realloc(argv, argv_size * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return -1; + } + } + + arg = va_arg(ap, const char *); + if (skipempty && arg && strlen(arg) == 0) + continue; + + argv[argc++] = arg; + + } while (arg != NULL); + + retval = pfcexec(path, argv[0], argv); + free(argv); + + return retval; +} + +int +xbps_file_exec(const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(NULL, 0, arg, ap); + va_end(ap); + + return result; +} + +int +xbps_file_exec_skipempty(const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(NULL, 1, arg, ap); + va_end(ap); + + return result; +} + +int +xbps_file_chdir_exec(const char *path, const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(path, 0, arg, ap); + va_end(ap); + + return result; +}