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 <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2013-01-09 20:25:04 +03:00
parent 1535d12d43
commit c2f030f2e8
5 changed files with 113 additions and 109 deletions

View File

@ -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);

View File

@ -285,9 +285,92 @@ 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;
@ -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;

View File

@ -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;
static GPtrArray *execvp__args__captured;
/* @ThenReturnValue */
static int execl__return_value = 0;
static int execvp__return_value = 0;
/* @Mock */
int
execl (const char *path, const char *arg, ...)
execvp (const char *file, char *const argv[])
{
char *one_arg;
va_list vargs;
char **one_arg;
execvp__file__captured = g_strdup (file);
execl__path__captured = g_strdup (path);
execl__arg__captured = g_strdup (arg);
for (one_arg = (char **) argv; *one_arg != NULL; one_arg++)
g_ptr_array_add (execvp__args__captured, g_strdup (*one_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;
return execvp__return_value;
}
static void
execl__init (void)
execvp__init (void)
{
execl__args__captured = g_ptr_array_new ();
execvp__args__captured = g_ptr_array_new ();
}
static void
execl__deinit (void)
execvp__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;
/* @ThenReturnValue */
static int execlp__return_value = 0;
/* @Mock */
int
execlp(const char *file, const char *arg, ...)
{
char *one_arg;
va_list vargs;
execlp__file__captured = g_strdup (file);
execlp__arg__captured = g_strdup (arg);
va_start (vargs, 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;
}
static void
execlp__init (void)
{
execlp__args__captured = g_ptr_array_new ();
}
static void
execlp__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 ();
}

View File

@ -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);

View File

@ -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);