mirror of https://github.com/MidnightCommander/mc
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:
parent
1535d12d43
commit
c2f030f2e8
|
@ -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);
|
||||
|
||||
|
|
106
lib/utilunix.c
106
lib/utilunix.c
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue