process: Add a wrapper to invoke a command under the system default shell

This commit is contained in:
Martin Willi
2014-10-06 18:24:39 +02:00
parent 02e4dedce5
commit 7dd06d274d
3 changed files with 110 additions and 0 deletions
@@ -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;
}
+77
View File
@@ -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 */
+17
View File
@@ -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_ @}*/