From: Kim Gunsoo Date: Mon, 28 Dec 2015 08:36:46 +0000 (+0900) Subject: Supports an interactive shell in case of the 'sdb shell cmd' X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=23a64396c537ccc1546bb10ba4cd137ae7d892c8;p=sdk%2Ftools%2Fsdb.git Supports an interactive shell in case of the 'sdb shell cmd' - 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 --- diff --git a/Makefile b/Makefile index 3760ca4..342c96f 100644 --- 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 + diff --git a/src/command_function.c b/src/command_function.c index 6fb7c45..dd32c7f 100644 --- a/src/command_function.c +++ b/src/command_function.c @@ -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) { diff --git a/src/commandline.c b/src/commandline.c index 304fef4..1ddab3a 100755 --- a/src/commandline.c +++ b/src/commandline.c @@ -31,7 +31,7 @@ #include "fdevent.h" #include "strutils.h" -#ifdef HAVE_TERMIO_H +#if defined(OS_LINUX) || defined(OS_DARWIN) // for UNIX #include #include #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) diff --git a/src/commandline.h b/src/commandline.h index 6f62268..4654014 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -43,16 +43,33 @@ #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_ */