From c2f030f2e879907bc187a5b181942b31f6077687 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Wed, 9 Jan 2013 20:25:04 +0300 Subject: [PATCH] Add new functions: * int my_systeml (int flags, const char *shell, ...); * int my_systemv (const char *command, char *const argv[]); Signed-off-by: Slava Zanko --- lib/util.h | 3 + lib/utilunix.c | 106 ++++++++++++++++++----- tests/lib/utilunix__my_system-common.c | 95 ++++---------------- tests/lib/utilunix__my_system-fork_child.c | 8 +- tests/lib/utilunix__my_system-fork_child_shell.c | 10 +-- 5 files changed, 113 insertions(+), 109 deletions(-) diff --git a/lib/util.h b/lib/util.h index 5b1a1c01c..f76ef5520 100644 --- a/lib/util.h +++ b/lib/util.h @@ -149,6 +149,9 @@ int close_error_pipe (int error, const char *text); /* Process spawning */ int my_system (int flags, const char *shell, const char *command); +int my_systeml (int flags, const char *shell, ...); +int my_systemv (const char *command, char *const argv[]); + void my_exit (int status); void save_stop_handler (void); diff --git a/lib/utilunix.c b/lib/utilunix.c index a14f6e57d..932d80614 100644 --- a/lib/utilunix.c +++ b/lib/utilunix.c @@ -285,10 +285,93 @@ my_exit (int status) } /* --------------------------------------------------------------------------------------------- */ +/** + * Call external programs. + * + * @parameter flags addition conditions for running external programs. + * @parameter shell shell (if flags contain EXECUTE_AS_SHELL), command to run otherwise. + * Shell (or command) will be found in paths described in PATH variable + * (if shell parameter doesn't begin from path delimiter) + * @parameter command Command for shell (or first parameter for command, if flags contain EXECUTE_AS_SHELL) + * @return 0 if successfull, -1 otherwise + */ int my_system (int flags, const char *shell, const char *command) { + return my_systeml (flags, shell, command, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Call external programs with various parameters number. + * + * @parameter flags addition conditions for running external programs. + * @parameter shell shell (if flags contain EXECUTE_AS_SHELL), command to run otherwise. + * Shell (or command) will be found in pathes described in PATH variable + * (if shell parameter doesn't begin from path delimiter) + * @parameter ... Command for shell with addition parameters for shell + * (or parameters for command, if flags contain EXECUTE_AS_SHELL). + * Should be NULL terminated. + * @return 0 if successfull, -1 otherwise + */ + +int +my_systeml (int flags, const char *shell, ...) +{ + char *execute_name; + GPtrArray *args_array; + int status = 0; + va_list vargs; + char *one_arg; + + args_array = g_ptr_array_new (); + + if ((flags & EXECUTE_AS_SHELL) != 0) + { + g_ptr_array_add (args_array, g_strdup (shell)); + g_ptr_array_add (args_array, g_strdup ("-c")); + execute_name = g_strdup (shell); + } + else + { + gchar *shell_token; + + shell_token = shell != NULL ? strchr (shell, ' ') : NULL; + if (shell_token == NULL) + *execute_name = g_strdup (shell); + else + *execute_name = g_strndup (shell, (gsize) (shell_token - shell)); + g_ptr_array_add (args_array, g_strdup (shell)); + } + + va_start (vargs, shell); + while ((one_arg = va_arg (vargs, char *)) != NULL) + g_ptr_array_add (args_array, g_strdup (one_arg)); + va_end (vargs); + + g_ptr_array_add (args_array, NULL); + status = my_systemv (execute_name, (char *const *) args_array->pdata); + + g_free (execute_name); + g_ptr_array_free (args_array, TRUE); + + return status; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Call external programs with array of strings as parameters. + * + * @parameter command command to run. Command will be found in paths described in PATH variable + * (if command parameter doesn't begin from path delimiter) + * @parameter argv Array of strings (NULL-terminated) with parameters for command + * @return 0 if successfull, -1 otherwise + */ + +int +my_systemv (const char *command, char *const argv[]) +{ my_fork_state_t fork_state; int status = 0; my_system_sigactions_t sigactions; @@ -308,28 +391,7 @@ my_system (int flags, const char *shell, const char *command) signal (SIGTSTP, SIG_DFL); signal (SIGCHLD, SIG_DFL); - if (flags & EXECUTE_AS_SHELL) - execl (shell, shell, "-c", command, (char *) NULL); - else - { - gchar **shell_tokens; - const gchar *only_cmd; - - shell_tokens = g_strsplit (shell, " ", 2); - if (shell_tokens == NULL) - only_cmd = shell; - else - only_cmd = (*shell_tokens != NULL) ? *shell_tokens : shell; - - execlp (only_cmd, shell, command, (char *) NULL); - - /* - execlp will replace current process, - therefore no sence in call of g_strfreev(). - But this keeped for estetic reason :) - */ - g_strfreev (shell_tokens); - } + execvp (command, argv); my_exit (127); /* Exec error */ } break; diff --git a/tests/lib/utilunix__my_system-common.c b/tests/lib/utilunix__my_system-common.c index 69354cef0..5741591b5 100644 --- a/tests/lib/utilunix__my_system-common.c +++ b/tests/lib/utilunix__my_system-common.c @@ -191,96 +191,37 @@ my_exit (int status) /* --------------------------------------------------------------------------------------------- */ /* @CapturedValue */ -static char *execl__path__captured = NULL; +static char *execvp__file__captured = NULL; /* @CapturedValue */ -static char *execl__arg__captured = NULL; -/* @CapturedValue */ -static GPtrArray *execl__args__captured; -/* @ThenReturnValue */ -static int execl__return_value = 0; - -/* @Mock */ -int -execl (const char *path, const char *arg, ...) -{ - char *one_arg; - va_list vargs; - - execl__path__captured = g_strdup (path); - execl__arg__captured = g_strdup (arg); - - va_start (vargs, arg); - - while ((one_arg = va_arg (vargs, char *)) != NULL) - { - g_ptr_array_add (execl__args__captured, g_strdup (one_arg)); - } - va_end (vargs); - - return execl__return_value; -} - -static void -execl__init (void) -{ - execl__args__captured = g_ptr_array_new (); -} - -static void -execl__deinit (void) -{ - g_ptr_array_foreach (execl__args__captured, (GFunc) g_free, NULL); - g_ptr_array_free (execl__args__captured, TRUE); - g_free (execl__path__captured); - g_free (execl__arg__captured); -} - -/* --------------------------------------------------------------------------------------------- */ - -/* @CapturedValue */ -static char *execlp__file__captured = NULL; -/* @CapturedValue */ -static char *execlp__arg__captured = NULL; -/* @CapturedValue */ -static GPtrArray *execlp__args__captured; +static GPtrArray *execvp__args__captured; /* @ThenReturnValue */ -static int execlp__return_value = 0; +static int execvp__return_value = 0; /* @Mock */ int -execlp(const char *file, const char *arg, ...) +execvp (const char *file, char *const argv[]) { - char *one_arg; - va_list vargs; - - execlp__file__captured = g_strdup (file); - execlp__arg__captured = g_strdup (arg); + char **one_arg; + execvp__file__captured = g_strdup (file); - va_start (vargs, arg); + for (one_arg = (char **) argv; *one_arg != NULL; one_arg++) + g_ptr_array_add (execvp__args__captured, g_strdup (*one_arg)); - while ((one_arg = va_arg (vargs, char *)) != NULL) - { - g_ptr_array_add (execlp__args__captured, g_strdup (one_arg)); - } - va_end (vargs); - - return execlp__return_value; + return execvp__return_value; } static void -execlp__init (void) +execvp__init (void) { - execlp__args__captured = g_ptr_array_new (); + execvp__args__captured = g_ptr_array_new (); } static void -execlp__deinit (void) +execvp__deinit (void) { - g_ptr_array_foreach (execlp__args__captured, (GFunc) g_free, NULL); - g_ptr_array_free (execlp__args__captured, TRUE); - - g_free (execlp__file__captured); - g_free (execlp__arg__captured); + g_ptr_array_foreach (execvp__args__captured, (GFunc) g_free, NULL); + g_ptr_array_free (execvp__args__captured, TRUE); + g_free (execvp__file__captured); } /* --------------------------------------------------------------------------------------------- */ @@ -361,8 +302,7 @@ setup (void) sigaction__init (); signal__init (); - execl__init (); - execlp__init (); + execvp__init (); } /* --------------------------------------------------------------------------------------------- */ @@ -371,8 +311,7 @@ setup (void) static void teardown (void) { - execlp__deinit (); - execl__deinit (); + execvp__deinit (); signal__deinit (); sigaction__deinit (); } diff --git a/tests/lib/utilunix__my_system-fork_child.c b/tests/lib/utilunix__my_system-fork_child.c index 135d1233a..0de07a8f0 100644 --- a/tests/lib/utilunix__my_system-fork_child.c +++ b/tests/lib/utilunix__my_system-fork_child.c @@ -54,11 +54,11 @@ START_TEST (fork_child) VERIFY_SIGACTION_CALLS (); VERIFY_SIGNAL_CALLS (); - g_assert_cmpstr (execlp__file__captured, ==, "/bin/some-command"); - g_assert_cmpstr (execlp__arg__captured, ==, "/bin/some-command"); - ck_assert_int_eq (execlp__args__captured->len, 1); + g_assert_cmpstr (execvp__file__captured, ==, "/bin/some-command"); + ck_assert_int_eq (execvp__args__captured->len, 2); - g_assert_cmpstr (g_ptr_array_index(execlp__args__captured, 0), ==, "some parameter"); + g_assert_cmpstr (g_ptr_array_index (execvp__args__captured, 0), ==, "/bin/some-command"); + g_assert_cmpstr (g_ptr_array_index (execvp__args__captured, 1), ==, "some parameter"); /* All exec* calls is mocked, so call to _exit() function with 127 status code it's a normal situation */ ck_assert_int_eq (my_exit__status__captured, 127); diff --git a/tests/lib/utilunix__my_system-fork_child_shell.c b/tests/lib/utilunix__my_system-fork_child_shell.c index 107833065..be4586a0d 100644 --- a/tests/lib/utilunix__my_system-fork_child_shell.c +++ b/tests/lib/utilunix__my_system-fork_child_shell.c @@ -54,12 +54,12 @@ START_TEST (fork_child_as_shell) VERIFY_SIGACTION_CALLS (); VERIFY_SIGNAL_CALLS (); - g_assert_cmpstr (execl__path__captured, ==, "/bin/shell"); - g_assert_cmpstr (execl__arg__captured, ==, "/bin/shell"); - ck_assert_int_eq (execl__args__captured->len, 2); + g_assert_cmpstr (execvp__file__captured, ==, "/bin/shell"); + ck_assert_int_eq (execvp__args__captured->len, 3); - g_assert_cmpstr (g_ptr_array_index(execl__args__captured, 0), ==, "-c"); - g_assert_cmpstr (g_ptr_array_index(execl__args__captured, 1), ==, "some command"); + g_assert_cmpstr (g_ptr_array_index (execvp__args__captured, 0), ==, "/bin/shell"); + g_assert_cmpstr (g_ptr_array_index (execvp__args__captured, 1), ==, "-c"); + g_assert_cmpstr (g_ptr_array_index (execvp__args__captured, 2), ==, "some command"); /* All exec* calls is mocked, so call to _exit() function with 127 status code it's a normal situation */ ck_assert_int_eq (my_exit__status__captured, 127); -- 2.11.4.GIT