diff options
author | Martin Willi <martin@revosec.ch> | 2014-10-06 10:52:18 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-10-06 18:24:39 +0200 |
commit | 7dd06d274da5c0775e772f0d74e2f823f85b675b (patch) | |
tree | 89dc696de0d42061cce09b4814911c6cfe9336e8 /src | |
parent | 02e4dedce513c07da88b873acc6bd5e59dd867ae (diff) | |
download | strongswan-7dd06d274da5c0775e772f0d74e2f823f85b675b.tar.bz2 strongswan-7dd06d274da5c0775e772f0d74e2f823f85b675b.tar.xz |
process: Add a wrapper to invoke a command under the system default shell
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/tests/suites/test_process.c | 16 | ||||
-rw-r--r-- | src/libstrongswan/utils/process.c | 77 | ||||
-rw-r--r-- | src/libstrongswan/utils/process.h | 17 |
3 files changed, 110 insertions, 0 deletions
diff --git a/src/libstrongswan/tests/suites/test_process.c b/src/libstrongswan/tests/suites/test_process.c index 7092f0650..c22c47294 100644 --- a/src/libstrongswan/tests/suites/test_process.c +++ b/src/libstrongswan/tests/suites/test_process.c @@ -176,6 +176,18 @@ START_TEST(test_env) } END_TEST +START_TEST(test_shell) +{ + process_t *process; + int retval; + + process = process_start_shell(NULL, NULL, NULL, NULL, "exit %d", 3); + ck_assert(process != NULL); + ck_assert(process->wait(process, &retval)); + ck_assert_int_eq(retval, 3); +} +END_TEST + Suite *process_suite_create() { Suite *s; @@ -201,5 +213,9 @@ Suite *process_suite_create() tcase_add_test(tc, test_env); suite_add_tcase(s, tc); + tc = tcase_create("shell"); + tcase_add_test(tc, test_shell); + suite_add_tcase(s, tc); + return s; } diff --git a/src/libstrongswan/utils/process.c b/src/libstrongswan/utils/process.c index 25e161b2c..233429447 100644 --- a/src/libstrongswan/utils/process.c +++ b/src/libstrongswan/utils/process.c @@ -13,11 +13,16 @@ * for more details. */ +/* vasprintf() */ +#define _GNU_SOURCE #include "process.h" +#include <library.h> #include <utils/debug.h> #include <fcntl.h> +#include <stdio.h> +#include <stdarg.h> typedef struct private_process_t private_process_t; @@ -218,6 +223,35 @@ process_t* process_start(char *const argv[], char *const envp[], } } +/** + * See header + */ +process_t* process_start_shell(char *const envp[], int *in, int *out, int *err, + char *fmt, ...) +{ + char *argv[] = { + "/bin/sh", + "-c", + NULL, + NULL + }; + process_t *process; + va_list args; + int len; + + va_start(args, fmt); + len = vasprintf(&argv[2], fmt, args); + va_end(args); + if (len < 0) + { + return NULL; + } + + process = process_start(argv, envp, in, out, err, TRUE); + free(argv[2]); + return process; +} + #else /* WIN32 */ /** @@ -511,4 +545,47 @@ process_t* process_start(char *const argv[], char *const envp[], return &this->public; } +/** + * See header + */ +process_t* process_start_shell(char *const envp[], int *in, int *out, int *err, + char *fmt, ...) +{ + char path[MAX_PATH], *exe = "system32\\cmd.exe"; + char *argv[] = { + path, + "/C", + NULL, + NULL + }; + process_t *process; + va_list args; + int len; + + len = GetSystemWindowsDirectory(path, sizeof(path)); + if (len == 0 || len >= sizeof(path) - strlen(exe)) + { + DBG1(DBG_LIB, "resolving Windows directory failed: 0x%08x", + GetLastError()); + return NULL; + } + if (path[len + 1] != '\\') + { + strncat(path, "\\", sizeof(path) - len++); + } + strncat(path, exe, sizeof(path) - len); + + va_start(args, fmt); + len = vasprintf(&argv[2], fmt, args); + va_end(args); + if (len < 0) + { + return NULL; + } + + process = process_start(argv, envp, in, out, err, TRUE); + free(argv[2]); + return process; +} + #endif /* WIN32 */ diff --git a/src/libstrongswan/utils/process.h b/src/libstrongswan/utils/process.h index 62d2ce757..81719201c 100644 --- a/src/libstrongswan/utils/process.h +++ b/src/libstrongswan/utils/process.h @@ -77,4 +77,21 @@ struct process_t { process_t* process_start(char *const argv[], char *const envp[], int *in, int *out, int *err, bool close_all); +/** + * Spawn a command in a shell child process. + * + * Same as process_start(), but passes a single command to a shell, such as + * "sh -c". See process_start() for I/O redirection notes. + * + * @param envp NULL terminated list of environment variables + * @param in pipe fd returned for redirecting data to child stdin + * @param out pipe fd returned to redirect child stdout data to + * @param err pipe fd returned to redirect child stderr data to + * @param fmt printf format string for command + * @param ... arguments for fmt + * @return process, NULL on failure + */ +process_t* process_start_shell(char *const envp[], int *in, int *out, int *err, + char *fmt, ...); + #endif /** PROCESS_H_ @}*/ |