From 1535d12d43026f55eccbc4267d26104f35a10856 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Sun, 6 Jan 2013 00:30:56 +0300 Subject: [PATCH] Code refactoring: my_system was split by few functions. Signed-off-by: Slava Zanko --- lib/utilunix.c | 168 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 108 insertions(+), 60 deletions(-) diff --git a/lib/utilunix.c b/lib/utilunix.c index dab48f297..a14f6e57d 100644 --- a/lib/utilunix.c +++ b/lib/utilunix.c @@ -96,6 +96,20 @@ typedef struct char *string; } int_cache; +typedef enum +{ + FORK_ERROR = -1, + FORK_CHILD, + FORK_PARENT, +} my_fork_state_t; + +typedef struct +{ + struct sigaction intr; + struct sigaction quit; + struct sigaction stop; +} my_system_sigactions_t; + /*** file scope variables ************************************************************************/ static int_cache uid_cache[UID_CACHE_SIZE]; @@ -130,6 +144,65 @@ i_cache_add (int id, int_cache * cache, int size, char *text, int *last) } /* --------------------------------------------------------------------------------------------- */ + +static my_fork_state_t +my_fork (void) +{ + pid_t pid; + + pid = fork (); + + if (pid < 0) + { + fprintf (stderr, "\n\nfork () = -1\n"); + return FORK_ERROR; + } + + if (pid == 0) + return FORK_CHILD; + + while (TRUE) + { + int status = 0; + + if (waitpid (pid, &status, 0) > 0) + return WEXITSTATUS (status) == 0 ? FORK_PARENT : FORK_ERROR; + + if (errno != EINTR) + return FORK_ERROR; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +my_system__save_sigaction_handlers (my_system_sigactions_t * sigactions) +{ + struct sigaction ignore; + + ignore.sa_handler = SIG_IGN; + sigemptyset (&ignore.sa_mask); + ignore.sa_flags = 0; + + sigaction (SIGINT, &ignore, &sigactions->intr); + sigaction (SIGQUIT, &ignore, &sigactions->quit); + + /* Restore the original SIGTSTP handler, we don't want ncurses' */ + /* handler messing the screen after the SIGCONT */ + sigaction (SIGTSTP, &startup_handler, &sigactions->stop); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +my_system__restore_sigaction_handlers (my_system_sigactions_t * sigactions) +{ + sigaction (SIGINT, &sigactions->intr, NULL); + sigaction (SIGQUIT, &sigactions->quit, NULL); + sigaction (SIGTSTP, &sigactions->stop, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -216,84 +289,59 @@ my_exit (int status) int my_system (int flags, const char *shell, const char *command) { - struct sigaction ignore, save_intr, save_quit, save_stop; - pid_t pid; + my_fork_state_t fork_state; int status = 0; + my_system_sigactions_t sigactions; - ignore.sa_handler = SIG_IGN; - sigemptyset (&ignore.sa_mask); - ignore.sa_flags = 0; - - sigaction (SIGINT, &ignore, &save_intr); - sigaction (SIGQUIT, &ignore, &save_quit); + my_system__save_sigaction_handlers (&sigactions); - /* Restore the original SIGTSTP handler, we don't want ncurses' */ - /* handler messing the screen after the SIGCONT */ - sigaction (SIGTSTP, &startup_handler, &save_stop); - - pid = fork (); - if (pid < 0) + fork_state = my_fork (); + switch (fork_state) { - fprintf (stderr, "\n\nfork () = -1\n"); + case FORK_ERROR: status = -1; - } - else if (pid == 0) - { - signal (SIGINT, SIG_DFL); - signal (SIGQUIT, SIG_DFL); - signal (SIGTSTP, SIG_DFL); - signal (SIGCHLD, SIG_DFL); - - if (flags & EXECUTE_AS_SHELL) - execl (shell, shell, "-c", command, (char *) NULL); - else + break; + case FORK_CHILD: { - gchar **shell_tokens; - const gchar *only_cmd; + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGTSTP, SIG_DFL); + signal (SIGCHLD, SIG_DFL); - shell_tokens = g_strsplit (shell, " ", 2); - if (shell_tokens == NULL) - only_cmd = shell; + if (flags & EXECUTE_AS_SHELL) + execl (shell, shell, "-c", command, (char *) NULL); else - only_cmd = (*shell_tokens != NULL) ? *shell_tokens : shell; - - execlp (only_cmd, shell, command, (char *) NULL); + { + gchar **shell_tokens; + const gchar *only_cmd; - /* - execlp will replace current process, - therefore no sence in call of g_strfreev(). - But this keeped for estetic reason :) - */ - g_strfreev (shell_tokens); + 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); - my_exit (127); /* Exec error */ - } - else - { - while (TRUE) - { - if (waitpid (pid, &status, 0) > 0) - { - status = WEXITSTATUS (status); - break; - } - if (errno != EINTR) - { - status = -1; - break; + /* + execlp will replace current process, + therefore no sence in call of g_strfreev(). + But this keeped for estetic reason :) + */ + g_strfreev (shell_tokens); } + my_exit (127); /* Exec error */ } + break; + default: + status = 0; + break; } - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); - sigaction (SIGTSTP, &save_stop, NULL); + my_system__restore_sigaction_handlers (&sigactions); return status; } - /* --------------------------------------------------------------------------------------------- */ /** -- 2.11.4.GIT