Supports an interactive shell in case of the 'sdb shell cmd'
authorKim Gunsoo <gunsoo83.kim@samsung.com>
Mon, 28 Dec 2015 08:36:46 +0000 (17:36 +0900)
committerKim Gunsoo <gunsoo83.kim@samsung.com>
Wed, 20 Jan 2016 06:56:21 +0000 (15:56 +0900)
- enable the sdb stdin routine that pass shell msg to sdbd.
- refactorying the shell routine.
    - remove duplicate code. (interactive_shell(), shell())
    - it is a unified interface that was different for each OS.
      (sdb_shell_stdin_init(), sdb_shell_stdin_restore())

Change-Id: I4b4d723b8e8b1e61410d4760b0bb2b8eb52d1351
Signed-off-by: Kim Gunsoo <gunsoo83.kim@samsung.com>
Makefile
src/command_function.c
src/commandline.c
src/commandline.h

index 3760ca4997d2d1ca652e86048becc1396cf1aebc..342c96f9823a9fe37c452fdd37ca508ef9059c50 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ ifeq ($(HOST_OS),linux)
        LOCAL_UTIL_SRC := src/utils_unix.c
        LOCAL_OTHER_SRC := src/fdevent.c src/fdevent_unix.c src/auto_complete.c
        LOCAL_LFLAGS := -lrt -lpthread -ludev -lcrypto
-       LOCAL_CFLAGS := -DOS_LINUX -DHAVE_FORKEXEC -DHAVE_TERMIO_H -DHAVE_SYMLINKS -DSDB_HOST=1 -DSDB_HOST_ON_TARGET=1 -D_FILE_OFFSET_BITS=64
+       LOCAL_CFLAGS := -DOS_LINUX -DHAVE_FORKEXEC -DHAVE_SYMLINKS -DSDB_HOST=1 -DSDB_HOST_ON_TARGET=1 -D_FILE_OFFSET_BITS=64
 endif
 
 ifeq ($(HOST_OS),darwin)
@@ -29,7 +29,7 @@ ifeq ($(HOST_OS),darwin)
        LOCAL_UTIL_SRC := src/utils_unix.c
        LOCAL_OTHER_SRC := src/fdevent.c src/fdevent_unix.c src/auto_complete.c
        LOCAL_LFLAGS := -lpthread -lcrypto -framework CoreFoundation -framework IOKit -framework Carbon
-       LOCAL_CFLAGS := -DOS_DARWIN -DHAVE_FORKEXEC -DHAVE_TERMIO_H -DHAVE_SYMLINKS -mmacosx-version-min=10.4 -DSDB_HOST=1 -DSDB_HOST_ON_TARGET=1
+       LOCAL_CFLAGS := -DOS_DARWIN -DHAVE_FORKEXEC -DHAVE_SYMLINKS -mmacosx-version-min=10.4 -DSDB_HOST=1 -DSDB_HOST_ON_TARGET=1
 endif
 
 ifeq ($(HOST_OS),mingw32)
@@ -89,4 +89,4 @@ sdb : $(SDB_SRC_FILES)
 clean :
        rm -rf $(OBJDIR)
 
-       
\ No newline at end of file
+       
index 6fb7c4565d7524f2c9643072a066af90f50ba6ce..dd32c7f7375a7e5667dd4f67e69568685e9a019b 100644 (file)
@@ -580,47 +580,72 @@ int pull(int argc, char ** argv) {
     return do_sync_copy(argv[1], argv[2], &info, 0);
 }
 
-int shell(int argc, char ** argv) {
-    char buf[4096];
+static int shell_connect()
+{
+    int fd = -1;
+    char shell_cmd[SHELLCMD_BUF_SIZE] = {0,};
+    struct sdb_version version;
+
+    /* eshell */
+    if(!get_platform_version(&version) && is_support_eshell(&version)) {
+        int lines, columns;
+        if(!get_screensize(&lines, &columns)) {
+            snprintf(shell_cmd, sizeof(shell_cmd), "eshell:%d:%d", lines, columns);
+            D("interactive shell : eshell command=%s\n", shell_cmd);
+            fd = sdb_connect(shell_cmd);
+        }
+    }
 
-        int r;
-        int fd;
+    /* retry basic shell service */
+    if(fd < 0){
+        fd = sdb_connect("shell:");
+    }
 
-        if(argc < 2) {
-            D("starting interactive shell\n");
-            r = interactive_shell();
-            return r;
-        }
+    return fd;
+}
 
-        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
-        argc -= 2;
-        argv += 2;
-        while(argc-- > 0) {
-            strcat(buf, " ");
-
-            /* quote empty strings and strings with spaces */
-            int quote = (**argv == 0 || strchr(*argv, ' '));
-            if (quote)
-                strcat(buf, "\"");
-            strcat(buf, *argv++);
-            if (quote)
-                strcat(buf, "\"");
-        }
+static int shell_connect_args(int argc, char ** argv)
+{
+    int fd = -1;
+    char shell_cmd[SHELLCMD_BUF_SIZE] = {0,};
 
-        D("interactive shell loop. buff=%s\n", buf);
-        fd = sdb_connect(buf);
-        if(fd >= 0) {
-            D("about to read_and_dump(fd=%d)\n", fd);
-            read_and_dump(fd);
-            D("read_and_dump() done.\n");
-            sdb_close(fd);
-            r = 0;
-        } else {
-            r = 1;
-        }
+    snprintf(shell_cmd, sizeof(shell_cmd), "shell:%s", argv[1]);
+    argc -= 2;
+    argv += 2;
+    while(argc-- > 0) {
+        strcat(shell_cmd, " ");
 
-        D("interactive shell loop. return r=%d\n", r);
-        return r;
+        /* quote empty strings and strings with spaces */
+        int quote = (**argv == 0 || strchr(*argv, ' '));
+        if (quote)
+            strcat(shell_cmd, "\"");
+        strcat(shell_cmd, *argv++);
+        if (quote)
+            strcat(shell_cmd, "\"");
+    }
+
+    fd = sdb_connect(shell_cmd);
+
+    return fd;
+}
+
+int shell(int argc, char ** argv) {
+    int fd = -1;
+
+    if(argc < 2) {
+        fd = shell_connect();
+    } else {
+        fd = shell_connect_args(argc, argv);
+    }
+
+    if (fd < 0) {
+        return 1;
+    }
+
+    sdb_execute_shell(fd, SDB_STDIN_ON);
+    sdb_close(fd);
+
+    return 0;
 }
 
 int forkserver(int argc, char** argv) {
@@ -635,7 +660,7 @@ int forkserver(int argc, char** argv) {
 }
 
 static int is_support_debug_option(void){
-    int is_support = 0;
+    int supported = 0;
     char buf[512] = {};
 
     const char* SHELL_GET_PROFILE_VER_CMD ="shell:/usr/bin/profile_command getversion";
@@ -651,39 +676,33 @@ static int is_support_debug_option(void){
         if (sscanf(buf, "%d.%d", &major, &minor) == 2) {
             // major version number at least 4
             if (major >= 4) {
-                is_support = 1;
+                supported = 1;
             }
         }
     }
 
     sdb_close(fd);
-    return is_support;
+    return supported;
 }
 
 static int is_support_whitespace_pkgname(void){
-    int is_support = 0;
-    int version = 0;
-    int major = 0;
-    int minor = 0;
-    int patch = 0;
-
-    version = get_platform_version();
-    if(!version) {
+    int supported = 0;
+    struct sdb_version version;
+    int ret = -1;
+
+    ret = get_platform_version(&version);
+    if(ret < 0) {
         // default : not support whitespace for package file name.
         return 0;
     }
 
-    major = MK_PLATFORM_MAJOR(version);
-    minor = MK_PLATFORM_MINOR(version);
-    patch = MK_PLATFORM_PATCH(version);
-
-    D("Platform version : %d.%d.%d\n", major, minor, patch);
+    D("Platform version : %d.%d.%d\n", version.major, version.minor, version.patch);
     // version number at least 2.4.0
-    if (major >= 3 || (major >= 2 && minor >=4)) {
-        is_support = 1;
+    if (version.major >= 3 || (version.major >= 2 && version.minor >=4)) {
+        supported = 1;
     }
 
-    return is_support;
+    return supported;
 }
 
 int install(int argc, char **argv) {
index 304fef40da3bb992f463f06921f1df01618603fa..1ddab3ac80a9c67081b50c8ce6c0accd202d0c73 100755 (executable)
@@ -31,7 +31,7 @@
 #include "fdevent.h"
 #include "strutils.h"
 
-#ifdef HAVE_TERMIO_H
+#if defined(OS_LINUX) || defined(OS_DARWIN) // for UNIX
 #include <termios.h>
 #include <sys/ioctl.h>
 #endif
@@ -51,11 +51,10 @@ static void print_help(LIST_NODE* optlist, LIST_NODE* cmdlist);
 static void create_opt_list(LIST_NODE** opt_list);
 static void create_cmd_list(LIST_NODE** cmd_list);
 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
-
-static int ishell_fd = -1;
-static int enable_sync_winsz = 0;
 static void sync_winsz(void);
 
+struct sdb_stdin_info g_stdin_info;
+
 #define INFOBUF_MAXLEN 64
 typedef struct platform_info {
     char platform_info_version[INFOBUF_MAXLEN];
@@ -65,15 +64,19 @@ typedef struct platform_info {
     char profile_name[INFOBUF_MAXLEN]; // 2.2.1
 } pinfo;
 
-int get_platform_version(void) {
+int get_platform_version(struct sdb_version *pversion) {
     struct platform_info pinfo;
-
     const char* GET_SYSTEM_INFO_CMD = "sysinfo:";
-    int fd = sdb_connect(GET_SYSTEM_INFO_CMD);
-    int version = 0;
+    int fd = -1;
+    int ret = -1;
 
+    if (pversion == NULL) {
+        return -1;
+    }
+
+    fd = sdb_connect(GET_SYSTEM_INFO_CMD);
     if(fd < 0) {
-        return 0;
+        return -1;
     }
 
     if (readx(fd, &pinfo, sizeof(struct platform_info)) == 0) {
@@ -81,94 +84,18 @@ int get_platform_version(void) {
         int minor = 0;
         int patch = 0;
         if (sscanf(pinfo.platform_version, "%d.%d.%d", &major, &minor, &patch) == 3) {
-            if (major < 1024 && minor < 1024 && patch < 1024) {
-                version |= (major << 20);
-                version |= (minor << 10);
-                version |= patch;
-            } else {
-                LOG_ERROR("Unexpected version : %d.%d.%d\n", major, minor, patch);
-            }
+            pversion->major = major;
+            pversion->minor = minor;
+            pversion->patch = patch;
+            ret = 0;
         }
     }
-    D("Platform version : %s(%x)\n", pinfo.platform_version, version);
+    D("Platform version : %d.%d.%d\n", pversion->major, pversion->minor, pversion->patch);
 
     sdb_close(fd);
-    return version;
-}
-
-#ifdef HAVE_TERMIO_H
-
-static __inline__ void stdin_raw_init(int fd, struct termios* tio_save);
-static __inline__ void stdin_raw_restore(int fd, struct termios* tio_save);
-
-static __inline__ void stdin_raw_init(int fd, struct termios* tio_save)
-{
-    struct termios tio;
-
-    if(tcgetattr(fd, &tio)) return;
-    memcpy(tio_save, &tio, sizeof(struct termios));
-
-    tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
-
-        /* no timeout but request at least one character per read */
-    tio.c_cc[VTIME] = 0;
-    tio.c_cc[VMIN] = 1;
-
-    tcsetattr(fd, TCSANOW, &tio);
-    tcflush(fd, TCIFLUSH);
-}
-
-static __inline__ void stdin_raw_restore(int fd, struct termios* tio_save)
-{
-    tcsetattr(fd, TCSANOW, tio_save);
-    tcflush(fd, TCIFLUSH);
-}
-#else
-static __inline__ void stdin_raw_init(void** args);
-static __inline__ void stdin_raw_restore(void** args);
-
-static __inline__ void stdin_raw_init(void** args) {
-    HANDLE input_t_handle = GetStdHandle(STD_INPUT_HANDLE);
-    args[1] = NULL;
-
-    if(input_t_handle == INVALID_HANDLE_VALUE) {
-        fprintf(stdout, "error: fail to get the stdin handle\n");
-        return;
-    }
-
-    DWORD console_mode_save;
-    if(!GetConsoleMode(input_t_handle, &console_mode_save)) {
-        fprintf(stdout, "error: fail to get the stdin console mode\n");
-        return;
-    }
-
-    if(!SetConsoleMode(input_t_handle, ENABLE_MOUSE_INPUT)) {
-        fprintf(stdout, "error: fail to set console mode\n");
-        return;
-    }
-
-    DWORD* cms_ptr = malloc(sizeof(DWORD));
-    *cms_ptr = console_mode_save;
-    args[1] = cms_ptr;
-
-    HANDLE* input_t_ptr = malloc(sizeof(HANDLE));
-    *input_t_ptr = input_t_handle;
-    args[2] = input_t_ptr;
-}
-
-static __inline__ void stdin_raw_restore(void** args) {
-    DWORD* cms_ptr = args[1];
-    if(cms_ptr != NULL) {
-        HANDLE* input_t_ptr = args[2];
-
-        if(!SetConsoleMode(*input_t_ptr, *cms_ptr)) {
-            fprintf(stdout, "error: fail to restore console mode\n");
-        }
-    }
+    return ret;
 }
 
-#endif
-
 void read_and_dump(int fd)
 {
     char buf[PATH_MAX];
@@ -192,69 +119,71 @@ void read_and_dump(int fd)
 
 }
 
-#ifdef HAVE_TERMIO_H
-static void *stdin_read_thread(void *x)
-{
-    unsigned char buf[1024];
-    int r, n;
+// TODO: move the following functions to util file for each OS.
+void sdb_shell_stdin_init(int fd);
+void sdb_shell_stdin_restore(int fd);
+void *stdin_read_thread(void *args);
+int get_screensize(int* lines, int* columns);
 
-    void** args = (void**) x;
-    int fd = *(int*)args[0];
-    struct termios* tio_save = args[1];
-    free(args[0]);
-    free(args);
-    for(;;) {
-        /* fdi is really the client's stdin, so use read, not sdb_read here */
-        D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", INPUT_FD);
-        r = unix_read(INPUT_FD, buf, 1024);
-        D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", INPUT_FD);
-        if(r == 0) break;
-        if(r < 0) {
-            if(errno == EINTR) continue;
-            break;
-        }
-        for(n = 0; n < r; n++){
-            if(buf[n] == '\n' || buf[n] == '\r') {
-                n++;
-                if(buf[n] == '~') {
-                    n++;
-                    if(buf[n] == '.') {
-                        fprintf(stderr,"\n* disconnect *\n");
-                        stdin_raw_restore(INPUT_FD, tio_save);
-                        free(tio_save);
-                        exit(0);
-                    }
-                }
-            }
-        }
-        r = sdb_write(fd, buf, r);
-        if(r <= 0) {
-            break;
-        }
-    }
-    return 0;
-}
-#else
+#if defined(OS_WINDOWS) // for Windows
+HANDLE g_input_handle = NULL;
+DWORD g_console_mode_save = NULL;
 
 static char arrow_up[3] = {27, 91, 65};
 static char arrow_down[3] = {27, 91, 66};
 static char arrow_right[3] = {27, 91, 67};
 static char arrow_left[3] = {27, 91, 68};
 
-static void *stdin_read_thread(void *x)
+void sdb_shell_stdin_init(int fd)
+{
+    if (fd != INPUT_FD) {
+        return;
+    }
+
+    g_input_handle = GetStdHandle(STD_INPUT_HANDLE);
+
+    if(g_input_handle == INVALID_HANDLE_VALUE) {
+        fprintf(stdout, "error: fail to get the stdin handle\n");
+        g_input_handle = NULL;
+        return;
+    }
+
+    if(!GetConsoleMode(g_input_handle, &g_console_mode_save)) {
+        fprintf(stdout, "error: fail to get the stdin console mode\n");
+        g_input_handle = NULL;
+        return;
+    }
+
+    if(!SetConsoleMode(g_input_handle, ENABLE_MOUSE_INPUT)) {
+        fprintf(stdout, "error: fail to set console mode\n");
+        return;
+    }
+}
+
+void sdb_shell_stdin_restore(int fd)
+{
+    if (fd != INPUT_FD) {
+        return;
+    }
+
+    if (g_input_handle != NULL) {
+        if(!SetConsoleMode(g_input_handle, g_console_mode_save)) {
+            fprintf(stdout, "error: fail to restore console mode\n");
+        }
+        g_input_handle = NULL;
+    }
+}
+
+void *stdin_read_thread(void *args)
 {
-    void** args = (void**) x;
-    int fd = *(int*)args[0];
     char* buf = NULL;
     int buf_len;
-    HANDLE* console_input_handle_ptr = args[2];
     INPUT_RECORD i_record;
     DWORD cNumRead;
-    SAFE_FREE(args[0]);
 
-    if(args[1] != NULL) {
+    if(g_console_mode_save != NULL) {
         while(1) {
-            if(!ReadConsoleInput(*console_input_handle_ptr, &i_record, 1, &cNumRead)) {
+            if(!ReadConsoleInput(g_input_handle, &i_record, 1, &cNumRead)) {
                 fprintf(stdout, "error: fail to read console standard input\n");
                 break;
             }
@@ -289,7 +218,7 @@ static void *stdin_read_thread(void *x)
                         }
                     }
                     if(buf) {
-                        if(sdb_write(fd, buf, buf_len) <= 0) {
+                        if(sdb_write(g_stdin_info.remote_fd, buf, buf_len) <= 0) {
                             break;
                         }
                     }
@@ -297,7 +226,7 @@ static void *stdin_read_thread(void *x)
                 }
             } else if(i_record.EventType == MOUSE_EVENT) {
                 if (i_record.Event.MouseEvent.dwEventFlags == 0) {
-                    if (enable_sync_winsz == 1) {
+                    if (g_stdin_info.enable_sync_winsz == SYNCWINSZ_SUPPORTED) {
                         sync_winsz();
                     }
                 }
@@ -307,13 +236,13 @@ static void *stdin_read_thread(void *x)
     else {
         while(1) {
             unsigned char buf[1024];
-            int r = unix_read(INPUT_FD, buf, 1024);
+            int r = unix_read(g_stdin_info.stdin_fd, buf, 1024);
             if(r == 0) break;
             if(r < 0) {
                 if(errno == EINTR) continue;
                 break;
             }
-            r = sdb_write(fd, buf, r);
+            r = sdb_write(g_stdin_info.remote_fd, buf, r);
             if(r <= 0) {
                 break;
             }
@@ -321,10 +250,100 @@ static void *stdin_read_thread(void *x)
     }
     return 0;
 }
-#endif
 
-#ifdef HAVE_TERMIO_H
-static int get_screensize(int* lines, int* columns)
+int get_screensize(int* lines, int* columns)
+{
+    HANDLE hConOut;
+    CONSOLE_SCREEN_BUFFER_INFO scr;
+
+    hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
+    if (hConOut != INVALID_HANDLE_VALUE)
+    {
+        if (GetConsoleScreenBufferInfo (hConOut, &scr))
+        {
+            *columns = scr.dwSize.X;
+            *lines = scr.srWindow.Bottom - scr.srWindow.Top + 1;
+            return 0;
+        }
+    }
+
+    D("failed to get windows size\n");
+    return -1;
+}
+
+#else // for UNIX
+struct termios g_tio_save;
+static void sig_winch_handler(int sig);
+
+void sdb_shell_stdin_init(int fd)
+{
+    struct termios tio;
+
+    if(tcgetattr(fd, &tio)) return;
+    memcpy(&g_tio_save, &tio, sizeof(struct termios));
+
+    /* disable CANON, ECHO*, etc */
+    tio.c_lflag = 0;
+    /* no timeout but request at least one character per read */
+    tio.c_cc[VTIME] = 0;
+    tio.c_cc[VMIN] = 1;
+
+    tcsetattr(fd, TCSANOW, &tio);
+    tcflush(fd, TCIFLUSH);
+
+    /* register SIGWINCH signal handler. */
+    struct sigaction sa_winch;
+    sigemptyset(&sa_winch.sa_mask);
+    sa_winch.sa_flags = 0;
+    sa_winch.sa_handler = sig_winch_handler;
+    if (sigaction(SIGWINCH, &sa_winch, NULL) < -1) {
+        D("failed to register the SIGWINCH signal handler.\n");
+    }
+}
+
+void sdb_shell_stdin_restore(int fd)
+{
+    tcsetattr(fd, TCSANOW, &g_tio_save);
+    tcflush(fd, TCIFLUSH);
+}
+
+void *stdin_read_thread(void *args)
+{
+    unsigned char buf[1024];
+    int r, n;
+
+    for(;;) {
+        /* fdi is really the client's stdin, so use read, not sdb_read here */
+        D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", INPUT_FD);
+        r = unix_read(g_stdin_info.stdin_fd, buf, 1024);
+        D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", INPUT_FD);
+        if(r == 0) break;
+        if(r < 0) {
+            if(errno == EINTR) continue;
+            break;
+        }
+        for(n = 0; n < r; n++){
+            if(buf[n] == '\n' || buf[n] == '\r') {
+                n++;
+                if(buf[n] == '~') {
+                    n++;
+                    if(buf[n] == '.') {
+                        fprintf(stderr,"\n* disconnect *\n");
+                        sdb_shell_stdin_restore(g_stdin_info.stdin_fd);
+                        exit(0);
+                    }
+                }
+            }
+        }
+        r = sdb_write(g_stdin_info.remote_fd, buf, r);
+        if(r <= 0) {
+            break;
+        }
+    }
+    return 0;
+}
+
+int get_screensize(int* lines, int* columns)
 {
     struct winsize win_sz;
 
@@ -344,31 +363,10 @@ static void sig_winch_handler(int sig) {
         return;
     }
 
-    if (enable_sync_winsz == 1) {
+    if (g_stdin_info.enable_sync_winsz == SYNCWINSZ_SUPPORTED) {
         sync_winsz();
     }
 }
-
-#else // for Windows
-static int get_screensize(int* lines, int* columns)
-{
-    HANDLE hConOut;
-    CONSOLE_SCREEN_BUFFER_INFO scr;
-
-    hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
-    if (hConOut != INVALID_HANDLE_VALUE)
-    {
-        if (GetConsoleScreenBufferInfo (hConOut, &scr))
-        {
-            *columns = scr.dwSize.X;
-            *lines = scr.srWindow.Bottom - scr.srWindow.Top + 1;
-            return 0;
-        }
-    }
-
-    D("failed to get windows size\n");
-    return -1;
-}
 #endif
 
 static void sync_winsz() {
@@ -382,7 +380,7 @@ static void sync_winsz() {
 
     if (get_screensize(&lines, &columns) == 0) {
         memset(&addr, 0, sizeof(addr));
-        if (sdb_getsockname(ishell_fd, (struct sockaddr *)&addr, &sockaddr_len) < 0) {
+        if (sdb_getsockname(g_stdin_info.remote_fd, (struct sockaddr *)&addr, &sockaddr_len) < 0) {
             D("failed to get sock name. errno=%d, %s\n", errno, strerror(errno));
             return;
         }
@@ -404,7 +402,7 @@ static void sync_winsz() {
         snprintf(full_cmd, sizeof(full_cmd), "shellconf:syncwinsz:%d:%d:%d", remote_id, lines, columns);
         fd = sdb_connect(full_cmd);
         if(fd < 0) {
-            enable_sync_winsz = 0;
+            g_stdin_info.enable_sync_winsz = SYNCWINSZ_UNSUPPORTED;
             D("failed to syncwinsz.\n");
             return;
         }
@@ -413,12 +411,16 @@ static void sync_winsz() {
     }
 }
 
+/* Check whether the key/value matches with the platform capability.
+ * Return value
+ *  1 : if key/value matches with capability.
+ *  0 : if there is no match. */
 static int match_capability_key_value(char* cap, char* key, char* value) {
     char *p_str = NULL;
     int offset = 0;
     char *k = NULL;
     char *v = NULL;
-    int matched = -1;
+    int matched = 0;
 
     if (cap == NULL || key == NULL || value == NULL) {
         return -1;
@@ -458,10 +460,11 @@ static int check_syncwinsz_support() {
     char full_cmd[16] = {0,};
     char cap_buffer[CAPBUF_SIZE] = {0,};
     uint16_t len = 0;
-    int supported = -1;
+    int supported = SYNCWINSZ_UNSUPPORTED;
+    int fd = -1;
 
     snprintf(full_cmd, sizeof(full_cmd), "capability:");
-    int fd = sdb_connect(full_cmd);
+    fd = sdb_connect(full_cmd);
     if (fd >= 0) {
         readx(fd, &len, sizeof(uint16_t));
         if (len > CAPBUF_SIZE-1) {
@@ -470,83 +473,56 @@ static int check_syncwinsz_support() {
         readx(fd, cap_buffer, len);
         sdb_close(fd);
 
-        supported = match_capability_key_value(cap_buffer, "syncwinsz_support", "enabled");
+        if (match_capability_key_value(cap_buffer, "syncwinsz_support", "enabled")) {
+            supported = SYNCWINSZ_SUPPORTED;
+        }
     }
     return supported;
 }
 
-int interactive_shell()
+static void stdin_info_init(int fd)
 {
-    sdb_thread_t thr;
-    char eshell[32] = "eshell:";
-    int lines, columns;
-    int fd = -1;
-    int major = 0;
-    int minor = 0;
-    int patch = 0;
-    int version = 0;
-
-    version = get_platform_version();
-    major = MK_PLATFORM_MAJOR(version);
-    minor = MK_PLATFORM_MINOR(version);
-    patch = MK_PLATFORM_PATCH(version);
-
-    // eshell to support from the 2.4.0 version.
-    if (major >= 3 || (major >= 2 && minor >=4)) {
-        if(get_screensize(&lines, &columns) == 0) {
-            snprintf(eshell+7, sizeof(eshell)-7, "%d:%d", lines, columns);
-            D("interactive shell : eshell command=%s\n", eshell);
-            fd = sdb_connect(eshell);
-            if(fd < 0) {
-                fprintf(stdout, "failed environment shell, so it will retry shell command.\n");
-                return 1;
-            }
-        }
+    g_stdin_info.stdin_fd = INPUT_FD;
+    g_stdin_info.remote_fd = fd;
+    g_stdin_info.enable_sync_winsz = check_syncwinsz_support();
+}
 
-        if(check_syncwinsz_support() == 1) {
-            D("Support sync window size with remote\n");
-            enable_sync_winsz = 1;
-        }
+void sdb_execute_shell(int fd, int stdin_on)
+{
+    stdin_info_init(fd);
+
+    if (stdin_on == SDB_STDIN_ON) {
+        sdb_thread_t thr;
+
+        sdb_shell_stdin_init(INPUT_FD);
+
+        sdb_thread_create(&thr, stdin_read_thread, NULL);
+        read_and_dump(fd);
+
+        sdb_shell_stdin_restore(INPUT_FD);
     } else {
-        fd = sdb_connect("shell:");
-        if(fd < 0) {
-            return 1;
-        }
+        read_and_dump(fd);
     }
+}
 
-    int* fd_p = malloc(sizeof(int));
-    *fd_p = fd;
-    ishell_fd = fd;
+int is_support_eshell(struct sdb_version *pversion)
+{
+    int supported = 0;
 
-#ifdef HAVE_TERMIO_H
-    void** args = (void**)malloc(sizeof(void*)*2);
-    struct termios tio_save;
-    stdin_raw_init(INPUT_FD, &tio_save);
-    struct termios* tio_save_p = (struct termios*)malloc(sizeof(struct termios));
-    memcpy(tio_save_p, &tio_save, sizeof(struct termios));
-    args[1] = tio_save_p;
+    if (pversion == NULL) {
+        return 0;
+    }
 
-    // register SIGWINCH signal handler.
-    struct sigaction sa_winch;
-    sigemptyset(&sa_winch.sa_mask);
-    sa_winch.sa_flags = 0;
-    sa_winch.sa_handler = sig_winch_handler;
-    if (sigaction(SIGWINCH, &sa_winch, NULL) < -1) {
-        D("failed to register the SIGWINCH signal handler.\n");
+    /* eshell to support from the 2.4.0 version. */
+    if (pversion->major >= 3 || (pversion->major >= 2 && pversion->minor >=4)) {
+        /* It must be checked whether it can be obtained window size from the terminal. */
+        int lines, columns;
+        if(get_screensize(&lines, &columns) == 0) {
+            supported = 1;
+        }
     }
-#else
-    void** args = (void**)malloc(sizeof(void*)*3);
-    stdin_raw_init(args);
-#endif
-    args[0] = fd_p;
-    sdb_thread_create(&thr, stdin_read_thread, args);
-    read_and_dump(fd);
-#ifdef HAVE_TERMIO_H
-    stdin_raw_restore(INPUT_FD, &tio_save);
-#else
-    stdin_raw_restore(args);
-#endif
-    return 0;
+
+    return supported;
 }
 
 int send_shellcommand(char* buf)
index 6f62268956f0b99309d133202771f057c8033299..46540145876d9aed7afb1a0c7b6c8f78185c9d79 100644 (file)
 #define INPUT_FD 0
 #endif
 
-#define MK_PLATFORM_MAJOR(ver)      ((version & 0x3ff00000) >> 20)
-#define MK_PLATFORM_MINOR(ver)      ((version & 0xffc00) >> 10)
-#define MK_PLATFORM_PATCH(ver)      ((version & 0x3ff))
+#define SHELLCMD_BUF_SIZE   4096
+#define SDB_STDIN_OFF       0
+#define SDB_STDIN_ON        1
+#define SYNCWINSZ_UNSUPPORTED   0
+#define SYNCWINSZ_SUPPORTED     1
+
+struct sdb_stdin_info {
+    int stdin_fd;
+    int remote_fd;
+    int enable_sync_winsz;
+};
+
+struct sdb_version {
+    int major;
+    int minor;
+    int patch;
+};
 
 int send_shellcommand(char* buf);
 int process_cmdline(int argc, char** argv);
 void read_and_dump(int fd);
 int interactive_shell();
+int is_support_eshell(struct sdb_version *pversion);
+int get_screensize(int* lines, int* columns);
+void sdb_execute_shell(int fd, int stdin_on);
 int get_server_port();
-int get_platform_version();
+int get_platform_version(struct sdb_version *pversion);
 int __sdb_command(const char* cmd);
 
 #endif /* COMMANDLINE_H_ */