Revert "[Title]fix multi instance problem on windows"
authormunkyu.im <munkyu.im@samsung.com>
Fri, 27 Jul 2012 03:44:44 +0000 (12:44 +0900)
committergiwoong.kim <giwoong.kim@samsung.com>
Wed, 1 Aug 2012 07:39:09 +0000 (16:39 +0900)
This reverts commit 38b9a35ce7bdb3b8ea14b8db24090519a66e5332.

tizen/src/emulator.c
tizen/src/sdb.c

index 9104c2109e197da8fd012b8dd2f6132b6911fa5a..204a011508294d5fcd42bcd7b43aabd3df0301b0 100644 (file)
-/* \r
- * Emulator\r
- *\r
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: \r
- * SeokYeon Hwang <syeon.hwang@samsung.com>\r
- * HyunJun Son <hj79.son@samsung.com>\r
- * MunKyu Im <munkyu.im@samsung.com>\r
- * GiWoong Kim <giwoong.kim@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-\r
-#include <stdlib.h>\r
-#include <SDL.h>\r
-#include "maru_common.h"\r
-#include "emulator.h"\r
-#include "sdb.h"\r
-#include "string.h"\r
-#include "skin/maruskin_server.h"\r
-#include "skin/maruskin_client.h"\r
-#include "guest_server.h"\r
-#include "debug_ch.h"\r
-#include "option.h"\r
-#include "emul_state.h"\r
-#include "qemu_socket.h"\r
-#include "build_info.h"\r
-#include "maru_err_table.h"\r
-#include <glib.h>\r
-#include <glib/gstdio.h>\r
-\r
-#if defined( _WIN32)\r
-#include <windows.h>\r
-#elif defined(__linux__)\r
-#include <linux/version.h>\r
-#include <sys/utsname.h>\r
-#include <sys/sysinfo.h>\r
-#include <sys/ipc.h>  \r
-#include <sys/shm.h>\r
-\r
-#endif\r
-\r
-#include "mloop_event.h"\r
-\r
-MULTI_DEBUG_CHANNEL(qemu, main);\r
-\r
-\r
-#define IMAGE_PATH_PREFIX   "file="\r
-#define IMAGE_PATH_SUFFIX   ",if=virtio"\r
-#define SDB_PORT_PREFIX     "sdb_port="\r
-#define LOGS_SUFFIX         "/logs/"\r
-#define LOGFILE             "emulator.log"\r
-#define MIDBUF  128\r
-int tizen_base_port = 0;\r
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;\r
-char tizen_target_path[MAXLEN] = {0, };\r
-char logpath[MAXLEN] = { 0, };\r
-\r
-static int skin_argc = 0;\r
-static char** skin_argv = NULL;\r
-static int qemu_argc = 0;\r
-static char** qemu_argv = NULL;\r
-\r
-extern void maruskin_sdl_quit(void);\r
-void exit_emulator(void)\r
-{\r
-    cleanup_multi_touch_state();\r
-\r
-    mloop_ev_stop();\r
-    shutdown_skin_server();\r
-    shutdown_guest_server();\r
-\r
-    maruskin_sdl_quit();\r
-}\r
-\r
-void check_shdmem(void)\r
-{\r
-#ifndef CONFIG_WIN32\r
-    int shm_id;\r
-    void *shm_addr;\r
-    u_int port;\r
-    int val;\r
-    struct shmid_ds shm_info;\r
-\r
-    for(port=26100;port < 26200; port += 10)\r
-    {\r
-        if ( -1 != ( shm_id = shmget( (key_t)port, 0, 0)))\r
-        {\r
-            if((void *)-1 == (shm_addr = shmat(shm_id, (void *)0, 0)))\r
-            {\r
-                ERR( "error occured at shmat()\n");\r
-                break;\r
-            }\r
-\r
-            val = shmctl(shm_id, IPC_STAT, &shm_info);\r
-            if(val != -1)\r
-            {\r
-                INFO( "count of process that use shared memory : %d\n", shm_info.shm_nattch);\r
-                if(shm_info.shm_nattch > 0 && strcmp(tizen_target_path, (char*)shm_addr) == 0)\r
-                {\r
-                    if(check_port_bind_listen(port+1) > 0){\r
-                        shmdt(shm_addr);\r
-                        continue;\r
-                    }\r
-                    shmdt(shm_addr);\r
-                    maru_register_exit_msg(MARU_EXIT_UNKNOWN, (char*)"Can not execute this VM.\nThe same name is running now.");\r
-                    exit(0);\r
-                }\r
-                else{\r
-                    shmdt(shm_addr);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-#else /* _WIN32*/\r
-    u_int port;\r
-    char* base_port = NULL;\r
-    char* pBuf;\r
-    HANDLE hMapFile;\r
-    for(port=26100;port < 26200; port += 10)\r
-    {\r
-        base_port = g_strdup_printf("%d", port);\r
-        hMapFile = OpenFileMapping(\r
-                 FILE_MAP_READ,\r
-                 TRUE,\r
-                 base_port);\r
-        if(hMapFile == NULL)\r
-        {\r
-            INFO("port %s is not used.\n", base_port);\r
-            continue;\r
-        }\r
-        else\r
-        {\r
-             pBuf = (char*)MapViewOfFile(hMapFile,\r
-                        FILE_MAP_READ,\r
-                        0,\r
-                        0,\r
-                        50);\r
-            if (pBuf == NULL)\r
-            {\r
-                ERR("Could not map view of file (%d).\n", GetLastError());\r
-                CloseHandle(hMapFile);\r
-            }\r
-\r
-            if(strcmp(pBuf, tizen_target_path) == 0)\r
-            {\r
-                       /*\r
-                if(check_port_bind_listen(port+1) > 0)\r
-                {\r
-                    UnmapViewOfFile(pBuf);\r
-                    CloseHandle(hMapFile);\r
-                    continue;\r
-                }\r
-                       */\r
-                maru_register_exit_msg(MARU_EXIT_UNKNOWN, "Can not execute this VM.\nThe same name is running now.");\r
-                UnmapViewOfFile(pBuf);\r
-                CloseHandle(hMapFile);\r
-                free(base_port);\r
-                exit(0);\r
-            }\r
-            else\r
-                UnmapViewOfFile(pBuf);\r
-        }\r
-\r
-        CloseHandle(hMapFile);\r
-        free(base_port);\r
-    }\r
-#endif\r
-}\r
-\r
-void make_shdmem(void)\r
-{\r
-#ifndef _WIN32\r
-       int shmid; \r
-       char *shared_memory;\r
-       shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT); \r
-       if (shmid == -1) \r
-       { \r
-               ERR("shmget failed\n"); \r
-               return; \r
-       } \r
-       shared_memory = shmat(shmid, (char*)0x00, 0); \r
-       if (shared_memory == (void *)-1) \r
-       { \r
-               ERR("shmat failed\n"); \r
-               return; \r
-       } \r
-       sprintf(shared_memory, "%s", tizen_target_path);\r
-       INFO( "shared memory key: %d value: %s\n", tizen_base_port, (char*)shared_memory);\r
-#else\r
-       HANDLE hMapFile;\r
-       char* pBuf;\r
-       char* port_in_use;\r
-       char *shared_memory;\r
-       shared_memory = g_strdup_printf("%s", tizen_target_path);\r
-       port_in_use =  g_strdup_printf("%d", tizen_base_port);\r
-    hMapFile = CreateFileMapping(\r
-                 INVALID_HANDLE_VALUE,    // use paging file\r
-                 NULL,                    // default security\r
-                 PAGE_READWRITE,          // read/write access\r
-                 0,                       // maximum object size (high-order DWORD)\r
-                 50,                // maximum object size (low-order DWORD)\r
-                 port_in_use);                 // name of mapping object\r
-    if (hMapFile == NULL)\r
-    {\r
-               ERR("Could not create file mapping object (%d).\n", GetLastError());\r
-               return;\r
-    }\r
-    pBuf = MapViewOfFile(hMapFile,   // handle to map object\r
-                        FILE_MAP_ALL_ACCESS, // read/write permission\r
-                        0,\r
-                        0,\r
-                        50);\r
-\r
-    if (pBuf == NULL)\r
-    {\r
-               ERR("Could not map view of file (%d).\n", GetLastError());\r
-               CloseHandle(hMapFile);\r
-               return;\r
-    }\r
-       \r
-       CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));\r
-       free(port_in_use);\r
-       free(shared_memory);\r
-#endif\r
-       return;\r
-}\r
-\r
-\r
-\r
-static void construct_main_window(int skin_argc, char* skin_argv[], int qemu_argc, char* qemu_argv[] )\r
-{\r
-    INFO("construct main window\n");\r
-\r
-    start_skin_server( skin_argc, skin_argv, qemu_argc, qemu_argv );\r
-\r
-    if (get_emul_skin_enable() == 1) { //this line is check for debugging, etc..\r
-        if ( 0 > start_skin_client(skin_argc, skin_argv) ) {\r
-            maru_register_exit_msg(MARU_EXIT_SKIN_SERVER_FAILED, NULL);\r
-            exit( -1 );\r
-        }\r
-    }\r
-\r
-    set_emul_caps_lock_state(0);\r
-    set_emul_num_lock_state(0);\r
-}\r
-\r
-static void parse_options(int argc, char* argv[], int* skin_argc, char*** skin_argv, int* qemu_argc, char*** qemu_argv)\r
-{\r
-    int i;\r
-    int j;\r
-\r
-// FIXME !!!\r
-// TODO:\r
-   \r
-    for(i = 1; i < argc; ++i)\r
-    {\r
-        if(strncmp(argv[i], "--skin-args", 11) == 0)\r
-        {\r
-            *skin_argv = &(argv[i + 1]);\r
-            break;\r
-        }\r
-    }\r
-    for(j = i; j < argc; ++j)\r
-    {\r
-        if(strncmp(argv[j], "--qemu-args", 11) == 0)\r
-        {\r
-            *skin_argc = j - i - 1;\r
-\r
-            *qemu_argc = argc - j - i + 1;\r
-            *qemu_argv = &(argv[j]);\r
-\r
-            argv[j] = argv[0];\r
-        }\r
-    }\r
-}\r
-\r
-static void get_bin_dir( char* exec_argv ) {\r
-\r
-    if ( !exec_argv ) {\r
-        return;\r
-    }\r
-\r
-    char* data = strdup( exec_argv );\r
-    if ( !data ) {\r
-        fprintf( stderr, "Fail to strdup for paring a binary directory.\n" );\r
-        return;\r
-    }\r
-\r
-    char* p = NULL;\r
-#ifdef _WIN32\r
-    p = strrchr( data, '\\' );\r
-    if ( !p ) {\r
-        p = strrchr( data, '/' );\r
-    }\r
-#else\r
-    p = strrchr( data, '/' );\r
-#endif\r
-    if ( !p ) {\r
-        free( data );\r
-        return;\r
-    }\r
-\r
-    strncpy( bin_dir, data, strlen( data ) - strlen( p ) );\r
-\r
-    free( data );\r
-\r
-}\r
-\r
-void set_image_and_log_path(char* qemu_argv)\r
-{\r
-    int i;\r
-    int j = 0;\r
-    int name_len = 0;\r
-    int prefix_len = 0;\r
-    int suffix_len = 0;\r
-    int max = 0;\r
-    char *path = malloc(MAXLEN);\r
-    name_len = strlen(qemu_argv);\r
-    prefix_len = strlen(IMAGE_PATH_PREFIX);\r
-    suffix_len = strlen(IMAGE_PATH_SUFFIX);\r
-    max = name_len - suffix_len;\r
-    for(i = prefix_len , j = 0; i < max; i++)\r
-    {\r
-        path[j++] = qemu_argv[i];\r
-    }\r
-    path[j] = '\0';\r
-    if(!g_path_is_absolute(path))\r
-        strcpy(tizen_target_path, g_get_current_dir());\r
-    else\r
-        strcpy(tizen_target_path, g_path_get_dirname(path));\r
-\r
-    strcpy(logpath, tizen_target_path);\r
-    strcat(logpath, LOGS_SUFFIX);\r
-#ifdef _WIN32\r
-    if(access(g_win32_locale_filename_from_utf8(logpath), R_OK) != 0) {\r
-       g_mkdir(g_win32_locale_filename_from_utf8(logpath), 0755); \r
-    }\r
-#else\r
-    if(access(logpath, R_OK) != 0) {\r
-       g_mkdir(logpath, 0755); \r
-    }\r
-#endif\r
-       strcat(logpath, LOGFILE);\r
-    set_log_path(logpath);\r
-}\r
-\r
-void redir_output(void)\r
-{\r
-       FILE *fp;\r
-\r
-       fp = freopen(logpath, "a+", stdout);\r
-       if(fp ==NULL)\r
-               fprintf(stderr, "log file open error\n");\r
-       fp = freopen(logpath, "a+", stderr);\r
-       if(fp ==NULL)\r
-               fprintf(stderr, "log file open error\n");\r
-\r
-       setvbuf(stdout, NULL, _IOLBF, BUFSIZ);\r
-       setvbuf(stderr, NULL, _IOLBF, BUFSIZ);\r
-}\r
-\r
-void extract_info(int qemu_argc, char** qemu_argv)\r
-{\r
-    int i;\r
-\r
-    for(i = 0; i < qemu_argc; ++i)\r
-    {\r
-        if(strstr(qemu_argv[i], IMAGE_PATH_PREFIX) != NULL) {\r
-            set_image_and_log_path(qemu_argv[i]);\r
-            break;\r
-        }\r
-    }\r
-    \r
-    tizen_base_port = get_sdb_base_port();\r
-}\r
-\r
-static void system_info(void)\r
-{\r
-#define DIV 1024\r
-\r
-    char timeinfo[64] = {0, };\r
-    struct tm *tm_time;\r
-    struct timeval tval;\r
-\r
-    INFO("* SDK Version : %s\n", build_version);\r
-    INFO("* Package %s\n", pkginfo_version);\r
-    INFO("* User name : %s\n", g_get_real_name());\r
-    INFO("* Host name : %s\n", g_get_host_name());\r
-\r
-    /* timestamp */\r
-    INFO("* Build date : %s\n", build_date);\r
-    gettimeofday(&tval, NULL);\r
-    tm_time = localtime(&(tval.tv_sec));\r
-    strftime(timeinfo, sizeof(timeinfo), "%Y/%m/%d %H:%M:%S", tm_time);\r
-    INFO("* Current time : %s\n", timeinfo);\r
-\r
-    /* Gets the version of the dynamically linked SDL library */\r
-    INFO("* Host sdl version : (%d, %d, %d)\n",\r
-        SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch);\r
-\r
-#if defined(CONFIG_WIN32)\r
-    /* Retrieves information about the current os */\r
-    OSVERSIONINFO osvi;\r
-    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));\r
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
-\r
-    if (GetVersionEx(&osvi)) {\r
-        INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, PlatformId : %d, CSDVersion : %s\n",\r
-            osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.dwPlatformId, osvi.szCSDVersion);\r
-    }\r
-\r
-    /* Retrieves information about the current system */\r
-    SYSTEM_INFO sysi;\r
-    ZeroMemory(&sysi, sizeof(SYSTEM_INFO));\r
-\r
-    GetSystemInfo(&sysi);\r
-    INFO("* Processor type : %d, Number of processors : %d\n", sysi.dwProcessorType, sysi.dwNumberOfProcessors);\r
-\r
-    MEMORYSTATUSEX memInfo;\r
-    memInfo.dwLength = sizeof(MEMORYSTATUSEX);\r
-    GlobalMemoryStatusEx(&memInfo);\r
-    INFO("* Total Ram : %llu kB, Free: %lld kB\n",\r
-        memInfo.ullTotalPhys / DIV, memInfo.ullAvailPhys / DIV);\r
-\r
-#elif defined(CONFIG_LINUX)\r
-    /* depends on building */\r
-    INFO("* Qemu build machine linux kernel version : (%d, %d, %d)\n",\r
-        LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff, LINUX_VERSION_CODE & 0xff);\r
-\r
-     /* depends on launching */\r
-    struct utsname host_uname_buf;\r
-    if (uname(&host_uname_buf) == 0) {\r
-        INFO("* Host machine uname : %s %s %s %s %s\n", host_uname_buf.sysname, host_uname_buf.nodename,\r
-            host_uname_buf.release, host_uname_buf.version, host_uname_buf.machine);\r
-    }\r
-\r
-    struct sysinfo sys_info;\r
-    if (sysinfo(&sys_info) == 0) {\r
-        INFO("* Total Ram : %llu kB, Free: %llu kB\n",\r
-            sys_info.totalram * (unsigned long long)sys_info.mem_unit / DIV,\r
-            sys_info.freeram * (unsigned long long)sys_info.mem_unit / DIV);\r
-    }\r
-\r
-    /* pci device description */\r
-    INFO("* Pci devices :\n");\r
-    char lscmd[MAXLEN] = "lspci >> ";\r
-    strcat(lscmd, logpath);\r
-    int i = system(lscmd);\r
-    INFO("system function command : %s, system function returned value : %d\n", lscmd, i);\r
-\r
-#elif defined(CONFIG_DARWIN)\r
-    //TODO:\r
-#endif\r
-\r
-    INFO("\n");\r
-}\r
-\r
-void prepare_maru(void)\r
-{\r
-    INFO("Prepare maru specified feature\n");\r
-\r
-    INFO("call construct_main_window\n");\r
-\r
-    construct_main_window(skin_argc, skin_argv, qemu_argc, qemu_argv);\r
-\r
-    int guest_server_port = tizen_base_port + SDB_UDP_SENSOR_INDEX;\r
-    start_guest_server( guest_server_port );\r
-\r
-    mloop_ev_init();\r
-}\r
-\r
-int qemu_main(int argc, char** argv, char** envp);\r
-\r
-int main(int argc, char* argv[])\r
-{\r
-    parse_options(argc, argv, &skin_argc, &skin_argv, &qemu_argc, &qemu_argv);\r
-    get_bin_dir( qemu_argv[0] );\r
-    socket_init();\r
-    extract_info(qemu_argc, qemu_argv);\r
-\r
-    INFO("Emulator start !!!\n");\r
-    \r
-    atexit(maru_atexit);\r
-    \r
-       check_shdmem();\r
-    make_shdmem();\r
-       sdb_setup();\r
-    \r
-       system_info();\r
-\r
-    INFO("Prepare running...\n");\r
-    redir_output(); // Redirect stdout, stderr after debug_ch is initialized...\r
-\r
-    int i;\r
-\r
-    fprintf(stdout, "qemu args : ==========================================\n");\r
-    for(i = 0; i < qemu_argc; ++i)\r
-    {\r
-        fprintf(stdout, "%s ", qemu_argv[i]);\r
-    }\r
-    fprintf(stdout, "\n");\r
-    fprintf(stdout, "======================================================\n");\r
-\r
-    fprintf(stdout, "skin args : ==========================================\n");\r
-    for(i = 0; i < skin_argc; ++i)\r
-    {\r
-        fprintf(stdout, "%s ", skin_argv[i]);\r
-    }\r
-    fprintf(stdout, "\n");\r
-    fprintf(stdout, "======================================================\n");\r
-\r
-    INFO("qemu main start!\n");\r
-    qemu_main(qemu_argc, qemu_argv, NULL);\r
-\r
-    exit_emulator();\r
-\r
-    return 0;\r
-}\r
-\r
+/* 
+ * Emulator
+ *
+ * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * HyunJun Son <hj79.son@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#include "maru_common.h"
+#include <stdlib.h>
+#ifdef CONFIG_SDL
+#include <SDL.h>
+#endif
+#include "emulator.h"
+#include "sdb.h"
+#include "string.h"
+#include "skin/maruskin_server.h"
+#include "skin/maruskin_client.h"
+#include "guest_server.h"
+#include "debug_ch.h"
+#include "option.h"
+#include "emul_state.h"
+#include "qemu_socket.h"
+#include "build_info.h"
+#include "maru_err_table.h"
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#if defined(CONFIG_WIN32)
+#include <windows.h>
+#elif defined(CONFIG_LINUX)
+#include <linux/version.h>
+#include <sys/utsname.h>
+#include <sys/sysinfo.h>
+#include <sys/ipc.h>  
+#include <sys/shm.h>
+#endif
+
+#include "mloop_event.h"
+
+MULTI_DEBUG_CHANNEL(qemu, main);
+
+
+#define IMAGE_PATH_PREFIX   "file="
+#define IMAGE_PATH_SUFFIX   ",if=virtio"
+#define SDB_PORT_PREFIX     "sdb_port="
+#define LOGS_SUFFIX         "/logs/"
+#define LOGFILE             "emulator.log"
+#define MIDBUF  128
+int tizen_base_port = 0;
+
+char tizen_target_path[MAXLEN] = {0, };
+char logpath[MAXLEN] = { 0, };
+
+static int skin_argc = 0;
+static char** skin_argv = NULL;
+static int qemu_argc = 0;
+static char** qemu_argv = NULL;
+
+extern void maru_display_fini(void);
+void exit_emulator(void)
+{
+    mloop_ev_stop();
+    shutdown_skin_server();
+    shutdown_guest_server();
+
+    maru_display_fini();
+}
+
+static int check_port_bind_listen(u_int port)
+{
+    struct sockaddr_in addr;
+    int s, opt = 1;
+    int ret = -1;
+    socklen_t addrlen = sizeof(addr);
+    memset(&addr, 0, addrlen);
+
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = INADDR_ANY;
+    addr.sin_port = htons(port);
+
+    if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+            (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
+            (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
+            (listen(s,1) < 0)) {
+
+        /* fail */
+        ret = -1;
+        ERR( "check port(%d) bind listen  fail \n", port);
+    }else{
+        /*fsucess*/
+        ret = 1;
+        INFO( "check port(%d) bind listen  ok \n", port);
+    }
+
+#ifdef CONFIG_WIN32
+    closesocket(s);
+#else
+    close(s);
+#endif
+
+    return ret;
+}
+
+
+void check_shdmem(void)
+{
+#if defined(CONFIG_LINUX)
+    int shm_id;
+    void *shm_addr;
+    u_int port;
+    int val;
+    struct shmid_ds shm_info;
+
+    for(port=26100;port < 26200; port += 10)
+    {
+        if ( -1 != ( shm_id = shmget( (key_t)port, 0, 0)))
+        {
+            if((void *)-1 == (shm_addr = shmat(shm_id, (void *)0, 0)))
+            {
+                ERR( "error occured at shmat()\n");
+                break;
+            }
+
+            val = shmctl(shm_id, IPC_STAT, &shm_info);
+            if(val != -1)
+            {
+                INFO( "count of process that use shared memory : %d\n", shm_info.shm_nattch);
+                if(shm_info.shm_nattch > 0 && strcmp(tizen_target_path, (char*)shm_addr) == 0)
+                {
+                    if(check_port_bind_listen(port+1) > 0){
+                        shmdt(shm_addr);
+                        continue;
+                    }
+                    shmdt(shm_addr);
+                    maru_register_exit_msg(MARU_EXIT_UNKNOWN, (char*)"Can not execute this VM.\nThe same name is running now.");
+                    exit(0);
+                }
+                else{
+                    shmdt(shm_addr);
+                }
+            }
+        }
+    }
+
+#elif defined(CONFIG_WIN32)
+    u_int port;
+    char* base_port = NULL;
+    char* pBuf;
+    HANDLE hMapFile;
+    for(port=26100;port < 26200; port += 10)
+    {
+        base_port = g_strdup_printf("%d", port);
+        hMapFile = OpenFileMapping(
+                 FILE_MAP_READ,
+                 TRUE,
+                 base_port);
+        if(hMapFile == NULL)
+        {
+            INFO("port %s is not used.\n", base_port);
+            continue;
+        }
+        else
+        {
+             pBuf = (char*)MapViewOfFile(hMapFile,
+                        FILE_MAP_READ,
+                        0,
+                        0,
+                        50);
+            if (pBuf == NULL)
+            {
+                ERR("Could not map view of file (%d).\n", GetLastError());
+                CloseHandle(hMapFile);
+                return -1;
+            }
+
+            if(strcmp(pBuf, tizen_target_path) == 0)
+            {
+                if(check_port_bind_listen(port+1) > 0)
+                {
+                    UnmapViewOfFile(pBuf);
+                    CloseHandle(hMapFile);
+                    continue;
+                }
+
+                maru_register_exit_msg(MARU_EXIT_UNKNOWN, "Can not execute this VM.\nThe same name is running now.");
+                UnmapViewOfFile(pBuf);
+                CloseHandle(hMapFile);
+                free(base_port);
+                exit(0);
+            }
+            else
+                UnmapViewOfFile(pBuf);
+        }
+
+        CloseHandle(hMapFile);
+        free(base_port);
+    }
+#elif defined(CONFIG_DARWIN)
+    //TODO:
+#endif
+}
+
+void make_shdmem(void)
+{
+#if defined(CONFIG_LINUX)
+       int shmid; 
+       char *shared_memory;
+       shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT); 
+       if (shmid == -1) 
+       { 
+               ERR("shmget failed\n"); 
+               return; 
+       } 
+       shared_memory = shmat(shmid, (char*)0x00, 0); 
+       if (shared_memory == (void *)-1) 
+       { 
+               ERR("shmat failed\n"); 
+               return; 
+       } 
+       sprintf(shared_memory, "%s", tizen_target_path);
+       INFO( "shared memory key: %d value: %s\n", tizen_base_port, (char*)shared_memory);
+#elif defined(CONFIG_WIN32)
+       HANDLE hMapFile;
+       char* pBuf;
+       char* port_in_use;
+       char *shared_memory;
+       shared_memory = g_strdup_printf("%s", tizen_target_path);
+       port_in_use =  g_strdup_printf("%d", tizen_base_port);
+    hMapFile = CreateFileMapping(
+                 INVALID_HANDLE_VALUE,    // use paging file
+                 NULL,                    // default security
+                 PAGE_READWRITE,          // read/write access
+                 0,                       // maximum object size (high-order DWORD)
+                 50,                // maximum object size (low-order DWORD)
+                 port_in_use);                 // name of mapping object
+    if (hMapFile == NULL)
+    {
+               ERR("Could not create file mapping object (%d).\n", GetLastError());
+               return;
+    }
+    pBuf = MapViewOfFile(hMapFile,   // handle to map object
+                        FILE_MAP_ALL_ACCESS, // read/write permission
+                        0,
+                        0,
+                        50);
+
+    if (pBuf == NULL)
+    {
+               ERR("Could not map view of file (%d).\n", GetLastError());
+               CloseHandle(hMapFile);
+               return;
+    }
+       
+       CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));
+       free(port_in_use);
+       free(shared_memory);
+#elif defined(CONFIG_DARWIN)
+    //TODO:
+#endif
+       return;
+}
+
+
+
+static void construct_main_window(int skin_argc, char* skin_argv[], int qemu_argc, char* qemu_argv[] )
+{
+    INFO("construct main window\n");
+
+    start_skin_server( skin_argc, skin_argv, qemu_argc, qemu_argv );
+
+    if (get_emul_skin_enable() == 1) { //this line is check for debugging, etc..
+        if ( 0 > start_skin_client(skin_argc, skin_argv) ) {
+            maru_register_exit_msg(MARU_EXIT_SKIN_SERVER_FAILED, NULL);
+            exit( -1 );
+        }
+    }
+
+    set_emul_caps_lock_state(0);
+    set_emul_num_lock_state(0);
+}
+
+static void parse_options(int argc, char* argv[], int* skin_argc, char*** skin_argv, int* qemu_argc, char*** qemu_argv)
+{
+    int i;
+    int j;
+
+// FIXME !!!
+// TODO:
+   
+    for(i = 1; i < argc; ++i)
+    {
+        if(strncmp(argv[i], "--skin-args", 11) == 0)
+        {
+            *skin_argv = &(argv[i + 1]);
+            break;
+        }
+    }
+    for(j = i; j < argc; ++j)
+    {
+        if(strncmp(argv[j], "--qemu-args", 11) == 0)
+        {
+            *skin_argc = j - i - 1;
+
+            *qemu_argc = argc - j - i + 1;
+            *qemu_argv = &(argv[j]);
+
+            argv[j] = argv[0];
+        }
+    }
+}
+
+static void get_bin_dir( char* exec_argv ) {
+
+    if ( !exec_argv ) {
+        return;
+    }
+
+    char* data = strdup( exec_argv );
+    if ( !data ) {
+        fprintf( stderr, "Fail to strdup for paring a binary directory.\n" );
+        return;
+    }
+
+    char* p = NULL;
+#ifdef _WIN32
+    p = strrchr( data, '\\' );
+    if ( !p ) {
+        p = strrchr( data, '/' );
+    }
+#else
+    p = strrchr( data, '/' );
+#endif
+    if ( !p ) {
+        free( data );
+        return;
+    }
+
+    strncpy( bin_dir, data, strlen( data ) - strlen( p ) );
+
+    free( data );
+
+}
+
+void set_image_and_log_path(char* qemu_argv)
+{
+    int i;
+    int j = 0;
+    int name_len = 0;
+    int prefix_len = 0;
+    int suffix_len = 0;
+    int max = 0;
+    char *path = malloc(MAXLEN);
+    name_len = strlen(qemu_argv);
+    prefix_len = strlen(IMAGE_PATH_PREFIX);
+    suffix_len = strlen(IMAGE_PATH_SUFFIX);
+    max = name_len - suffix_len;
+    for(i = prefix_len , j = 0; i < max; i++)
+    {
+        path[j++] = qemu_argv[i];
+    }
+    path[j] = '\0';
+    if(!g_path_is_absolute(path))
+        strcpy(tizen_target_path, g_get_current_dir());
+    else
+        strcpy(tizen_target_path, g_path_get_dirname(path));
+
+    strcpy(logpath, tizen_target_path);
+    strcat(logpath, LOGS_SUFFIX);
+#ifdef CONFIG_WIN32
+    if(access(g_win32_locale_filename_from_utf8(logpath), R_OK) != 0) {
+       g_mkdir(g_win32_locale_filename_from_utf8(logpath), 0755); 
+    }
+#else
+    if(access(logpath, R_OK) != 0) {
+       g_mkdir(logpath, 0755); 
+    }
+#endif
+       strcat(logpath, LOGFILE);
+    set_log_path(logpath);
+}
+
+void redir_output(void)
+{
+       FILE *fp;
+
+       fp = freopen(logpath, "a+", stdout);
+       if(fp ==NULL)
+               fprintf(stderr, "log file open error\n");
+       fp = freopen(logpath, "a+", stderr);
+       if(fp ==NULL)
+               fprintf(stderr, "log file open error\n");
+
+       setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+       setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
+}
+
+void extract_info(int qemu_argc, char** qemu_argv)
+{
+    int i;
+
+    for(i = 0; i < qemu_argc; ++i)
+    {
+        if(strstr(qemu_argv[i], IMAGE_PATH_PREFIX) != NULL) {
+            set_image_and_log_path(qemu_argv[i]);
+            break;
+        }
+    }
+    
+    tizen_base_port = get_sdb_base_port();
+}
+
+static void system_info(void)
+{
+#define DIV 1024
+
+    char timeinfo[64] = {0, };
+    struct tm *tm_time;
+    struct timeval tval;
+
+    INFO("* SDK Version : %s\n", build_version);
+    INFO("* Package %s\n", pkginfo_version);
+    INFO("* User name : %s\n", g_get_real_name());
+    INFO("* Host name : %s\n", g_get_host_name());
+
+    /* timestamp */
+    INFO("* Build date : %s\n", build_date);
+    gettimeofday(&tval, NULL);
+    tm_time = localtime(&(tval.tv_sec));
+    strftime(timeinfo, sizeof(timeinfo), "%Y/%m/%d %H:%M:%S", tm_time);
+    INFO("* Current time : %s\n", timeinfo);
+
+#ifdef CONFIG_SDL
+    /* Gets the version of the dynamically linked SDL library */
+    INFO("* Host sdl version : (%d, %d, %d)\n",
+        SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch);
+#endif
+
+#if defined(CONFIG_WIN32)
+    /* Retrieves information about the current os */
+    OSVERSIONINFO osvi;
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+    if (GetVersionEx(&osvi)) {
+        INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, PlatformId : %d, CSDVersion : %s\n",
+            osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.dwPlatformId, osvi.szCSDVersion);
+    }
+
+    /* Retrieves information about the current system */
+    SYSTEM_INFO sysi;
+    ZeroMemory(&sysi, sizeof(SYSTEM_INFO));
+
+    GetSystemInfo(&sysi);
+    INFO("* Processor type : %d, Number of processors : %d\n", sysi.dwProcessorType, sysi.dwNumberOfProcessors);
+
+    MEMORYSTATUSEX memInfo;
+    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+    GlobalMemoryStatusEx(&memInfo);
+    INFO("* Total Ram : %llu kB, Free: %lld kB\n",
+        memInfo.ullTotalPhys / DIV, memInfo.ullAvailPhys / DIV);
+
+#elif defined(CONFIG_LINUX)
+    /* depends on building */
+    INFO("* Qemu build machine linux kernel version : (%d, %d, %d)\n",
+        LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff, LINUX_VERSION_CODE & 0xff);
+
+     /* depends on launching */
+    struct utsname host_uname_buf;
+    if (uname(&host_uname_buf) == 0) {
+        INFO("* Host machine uname : %s %s %s %s %s\n", host_uname_buf.sysname, host_uname_buf.nodename,
+            host_uname_buf.release, host_uname_buf.version, host_uname_buf.machine);
+    }
+
+    struct sysinfo sys_info;
+    if (sysinfo(&sys_info) == 0) {
+        INFO("* Total Ram : %llu kB, Free: %llu kB\n",
+            sys_info.totalram * (unsigned long long)sys_info.mem_unit / DIV,
+            sys_info.freeram * (unsigned long long)sys_info.mem_unit / DIV);
+    }
+
+    /* pci device description */
+    INFO("* Pci devices :\n");
+    char lscmd[MAXLEN] = "lspci >> ";
+    strcat(lscmd, logpath);
+    int i = system(lscmd);
+    INFO("system function command : %s, system function returned value : %d\n", lscmd, i);
+
+#elif defined(CONFIG_DARWIN)
+    //TODO:
+#endif
+
+    INFO("\n");
+}
+
+void prepare_maru(void)
+{
+    INFO("Prepare maru specified feature\n");
+
+    sdb_setup();
+
+    INFO("call construct_main_window\n");
+
+    construct_main_window(skin_argc, skin_argv, qemu_argc, qemu_argv);
+
+    int guest_server_port = tizen_base_port + SDB_UDP_SENSOR_INDEX;
+    start_guest_server( guest_server_port );
+
+    mloop_ev_init();
+}
+
+int qemu_main(int argc, char** argv, char** envp);
+
+int main(int argc, char* argv[])
+{
+    parse_options(argc, argv, &skin_argc, &skin_argv, &qemu_argc, &qemu_argv);
+    get_bin_dir( qemu_argv[0] );
+    socket_init();
+    extract_info(qemu_argc, qemu_argv);
+
+    INFO("Emulator start !!!\n");
+    
+    atexit(maru_atexit);
+    
+    check_shdmem();
+    make_shdmem();
+
+    system_info();
+
+    INFO("Prepare running...\n");
+    redir_output(); // Redirect stdout, stderr after debug_ch is initialized...
+
+    int i;
+
+    fprintf(stdout, "qemu args : ==========================================\n");
+    for(i = 0; i < qemu_argc; ++i)
+    {
+        fprintf(stdout, "%s ", qemu_argv[i]);
+    }
+    fprintf(stdout, "\n");
+    fprintf(stdout, "======================================================\n");
+
+    fprintf(stdout, "skin args : ==========================================\n");
+    for(i = 0; i < skin_argc; ++i)
+    {
+        fprintf(stdout, "%s ", skin_argv[i]);
+    }
+    fprintf(stdout, "\n");
+    fprintf(stdout, "======================================================\n");
+
+    INFO("qemu main start!\n");
+    qemu_main(qemu_argc, qemu_argv, NULL);
+
+    exit_emulator();
+
+    return 0;
+}
+
index 7c040ae7a460440f7afaef813cee436716aa047d..4291fdd6a7a25d73c8e9585fde72ee3cd0196dc7 100644 (file)
-/* Copyright (C) 2006-2010 The Android Open Source Project\r
-**\r
-** This software is licensed under the terms of the GNU General Public\r
-** License version 2, as published by the Free Software Foundation, and\r
-** may be copied, distributed, and modified under those terms.\r
-**\r
-** This program is distributed in the hope that it will be useful,\r
-** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-** GNU General Public License for more details.\r
-*/\r
-\r
-\r
-#ifdef _WIN32\r
-#include <windows.h>\r
-#include <winsock2.h>\r
-#include <ws2tcpip.h>\r
-#else /* !_WIN32 */\r
-#include <sys/ioctl.h>\r
-#include <sys/socket.h>\r
-#include <netinet/in.h>\r
-#include <netinet/tcp.h>\r
-#include <netdb.h>\r
-#endif /* !_WIN32 */\r
-\r
-#include "net/slirp.h"\r
-#include "qemu_socket.h"\r
-#include "sdb.h"\r
-#include "nbd.h"\r
-#include "tizen/src/debug_ch.h"\r
-\r
-//DEFAULT_DEBUG_CHANNEL(qemu);\r
-MULTI_DEBUG_CHANNEL(qemu, sdb);\r
-\r
-/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty\r
- * easily in QEMU since we use SIGALRM to implement periodic timers\r
- */\r
-\r
-#ifdef _WIN32\r
-#  define  QSOCKET_CALL(_ret,_cmd)   \\r
-       do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )\r
-#else\r
-#  define  QSOCKET_CALL(_ret,_cmd)   \\r
-       do { \\r
-               errno = 0; \\r
-               do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \\r
-       } while (0);\r
-#endif\r
-\r
-#ifdef _WIN32\r
-\r
-#include <errno.h>\r
-\r
-static int  winsock_error;\r
-\r
-#define  WINSOCK_ERRORS_LIST \\r
-       EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \\r
-EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \\r
-EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \\r
-EE(WSAEINTR,EINTR,"interrupted function call") \\r
-EE(WSAEALREADY,EALREADY,"operation already in progress") \\r
-EE(WSAEBADF,EBADF,"bad file descriptor") \\r
-EE(WSAEACCES,EACCES,"permission denied") \\r
-EE(WSAEFAULT,EFAULT,"bad address") \\r
-EE(WSAEINVAL,EINVAL,"invalid argument") \\r
-EE(WSAEMFILE,EMFILE,"too many opened files") \\r
-EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \\r
-EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \\r
-EE(WSAEALREADY,EAGAIN,"operation already in progress") \\r
-EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \\r
-EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \\r
-EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \\r
-EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \\r
-EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \\r
-EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \\r
-EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \\r
-EE(WSAENETDOWN,ENETDOWN,"network is down") \\r
-EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \\r
-EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \\r
-EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \\r
-EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \\r
-EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \\r
-EE(WSAEISCONN,EISCONN,"socket is already connected") \\r
-EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \\r
-EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \\r
-EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \\r
-EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \\r
-EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \\r
-EE(WSAELOOP,ELOOP,"cannot translate name") \\r
-EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \\r
-EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \\r
-EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \\r
-\r
-typedef struct {\r
-       int          winsock;\r
-       int          unix;\r
-       const char*  string;\r
-} WinsockError;\r
-\r
-static const WinsockError  _winsock_errors[] = {\r
-#define  EE(w,u,s)   { w, u, s },\r
-       WINSOCK_ERRORS_LIST\r
-#undef   EE\r
-       { -1, -1, NULL }\r
-};\r
-\r
-/* this function reads the latest winsock error code and updates\r
- * errno to a matching value. It also returns the new value of\r
- * errno.\r
- */\r
-static int _fix_errno( void )\r
-{\r
-       const WinsockError*  werr = _winsock_errors;\r
-       int                  unix = EINVAL;  /* generic error code */\r
-\r
-       winsock_error = WSAGetLastError();\r
-\r
-       for ( ; werr->string != NULL; werr++ ) {\r
-               if (werr->winsock == winsock_error) {\r
-                       unix = werr->unix;\r
-                       break;\r
-               }\r
-       }\r
-       errno = unix;\r
-       return -1;\r
-}\r
-\r
-#else\r
-static int _fix_errno( void )\r
-{\r
-       return -1;\r
-}\r
-\r
-#endif\r
-\r
-#define  SOCKET_CALL(cmd)  \\r
-       int  ret; \\r
-QSOCKET_CALL(ret, (cmd)); \\r
-if (ret < 0) \\r
-return _fix_errno(); \\r
-return ret; \\r
-\r
-int socket_send(int  fd, const void*  buf, int  buflen)\r
-{\r
-       SOCKET_CALL(send(fd, buf, buflen, 0))\r
-}\r
-\r
-#ifdef _WIN32\r
-\r
-       static void\r
-socket_close_handler( void*  _fd )\r
-{\r
-       int   fd = (int)_fd;\r
-       int   ret;\r
-       char  buff[64];\r
-\r
-       /* we want to drain the read side of the socket before closing it */\r
-       do {\r
-               ret = recv( fd, buff, sizeof(buff), 0 );\r
-       } while (ret < 0 && WSAGetLastError() == WSAEINTR);\r
-\r
-       if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)\r
-               return;\r
-\r
-       qemu_set_fd_handler( fd, NULL, NULL, NULL );\r
-       closesocket( fd );\r
-}\r
-\r
-       void\r
-socket_close( int  fd )\r
-{\r
-       int  old_errno = errno;\r
-\r
-       shutdown( fd, SD_BOTH );\r
-       /* we want to drain the socket before closing it */\r
-       qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );\r
-\r
-       errno = old_errno;\r
-}\r
-\r
-#else /* !_WIN32 */\r
-\r
-#include <unistd.h>\r
-\r
-       void\r
-socket_close( int  fd )\r
-{\r
-       int  old_errno = errno;\r
-\r
-       shutdown( fd, SHUT_RDWR );\r
-       close( fd );\r
-\r
-       errno = old_errno;\r
-}\r
-\r
-#endif /* !_WIN32 */\r
-\r
-int inet_strtoip(const char*  str, uint32_t  *ip)\r
-{\r
-       int  comp[4];\r
-\r
-       if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)\r
-               return -1;\r
-\r
-       if ((unsigned)comp[0] >= 256 ||\r
-                       (unsigned)comp[1] >= 256 ||\r
-                       (unsigned)comp[2] >= 256 ||\r
-                       (unsigned)comp[3] >= 256)\r
-               return -1;\r
-\r
-       *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |\r
-                       (comp[2] << 8)  |  comp[3]);\r
-       return 0;\r
-}\r
-\r
-static int check_port_bind_listen(u_int port)\r
-{\r
-       struct sockaddr_in addr;\r
-       int s, opt = 1;\r
-       int ret = -1;\r
-       socklen_t addrlen = sizeof(addr);\r
-       memset(&addr, 0, addrlen);\r
-\r
-       addr.sin_family = AF_INET;\r
-       addr.sin_addr.s_addr = INADDR_ANY;\r
-       addr.sin_port = htons(port);\r
-\r
-       if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||\r
-#ifndef _WIN32\r
-                       (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||\r
-#endif\r
-                       (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||\r
-                       (listen(s, 1) < 0)) {\r
-\r
-               /* fail */\r
-               ret = -1;\r
-               ERR( "port(%d) listen  fail \n", port);\r
-       }else{\r
-               /*fsucess*/\r
-               ret = 1;\r
-               INFO( "port(%d) listen  ok \n", port);\r
-       }\r
-\r
-#ifdef _WIN32\r
-       closesocket(s);\r
-#else\r
-       close(s);\r
-#endif\r
-\r
-       return ret;\r
-}\r
-\r
-int get_sdb_base_port(void)\r
-{\r
-       int   tries     = 10;\r
-       int   success   = 0;\r
-       u_int port = 26100;\r
-\r
-       if(tizen_base_port == 0){\r
-\r
-               for ( ; tries > 0; tries--, port += 10 ) {\r
-                       if(check_port_bind_listen(port + 1) < 0 )\r
-                               continue;\r
-\r
-                       success = 1;\r
-                       break;\r
-               }\r
-\r
-               if (!success) {\r
-                       ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
-                       exit(1);\r
-               }\r
-\r
-               tizen_base_port = port;\r
-               INFO( "sdb port is %d \n", tizen_base_port);\r
-       }\r
-\r
-       return tizen_base_port;\r
-}\r
-\r
-void sdb_setup(void)\r
-{\r
-       int   tries     = 10;\r
-       int   success   = 0;\r
-       uint32_t  guest_ip;\r
-       char buf[64] = {0,};\r
-       inet_strtoip("10.0.2.16", &guest_ip);\r
-\r
-       for ( ; tries > 0; tries--, tizen_base_port += 10 ) {\r
-               // redir form [tcp:26101:10.0.2.16:26101]\r
-               sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);\r
-               if(net_slirp_redir((char*)buf) < 0)\r
-                       continue;\r
-\r
-               INFO( "SDBD established on port %d\n", tizen_base_port + 1);\r
-               success = 1;\r
-               break;\r
-       }\r
-\r
-       INFO("redirect [%s] success\n", buf);\r
-       if (!success) {\r
-               ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
-               exit(1);\r
-       }\r
-\r
-       INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);\r
-\r
-       /* for sensort */\r
-       sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );\r
-       if(net_slirp_redir((char*)buf) < 0){\r
-               ERR( "redirect [%s] fail \n", buf);\r
-       }else{\r
-               INFO("redirect [%s] success\n", buf);\r
-       }\r
-}\r
-\r
-int sdb_loopback_client(int port, int type)\r
-{\r
-    struct sockaddr_in addr;\r
-    int s;\r
-\r
-    memset(&addr, 0, sizeof(addr));\r
-    addr.sin_family = AF_INET;\r
-    addr.sin_port = htons(port);\r
-    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\r
-\r
-    s = socket(AF_INET, type, 0);\r
-    if(s < 0) return -1;\r
-\r
-    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\r
-        close(s);\r
-        return -1;\r
-    }\r
-\r
-    return s;\r
-\r
-}\r
-\r
-void notify_sdb_daemon_start(void) {\r
-    int s;\r
-    /* \r
-     * send a simple message to the SDB host server to tell it we just started.\r
-     * it should be listening on port 26099.\r
-     */\r
-    do {\r
-        char tmp[32] = { 0 };\r
-\r
-        // when connecting to loopback:26099, do not use tcp_socket_outgoing function\r
-        // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.\r
-        s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);\r
-        if (s < 0) {\r
-            INFO("can't create socket to talk to the SDB server \n");\r
-            INFO("This emulator will be scaned by the SDB server \n");\r
-            break;\r
-        }\r
-\r
-        /* length is hex: 0x13 = 19 */\r
-        sprintf(tmp, "0013host:emulator:%d", tizen_base_port + 1);\r
-\r
-        if (socket_send(s, tmp, 30) < 0) {\r
-            ERR( "message sending to sdb server error!\n");\r
-        }\r
-\r
-    } while (0);\r
-\r
-    if (s >= 0)\r
-        socket_close(s);\r
-}\r
+/* Copyright (C) 2006-2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else /* !_WIN32 */
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#endif /* !_WIN32 */
+
+#include "net/slirp.h"
+#include "qemu_socket.h"
+#include "sdb.h"
+#include "nbd.h"
+#include "tizen/src/debug_ch.h"
+
+//DEFAULT_DEBUG_CHANNEL(qemu);
+MULTI_DEBUG_CHANNEL(qemu, sdb);
+
+/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
+ * easily in QEMU since we use SIGALRM to implement periodic timers
+ */
+
+#ifdef _WIN32
+#  define  QSOCKET_CALL(_ret,_cmd)   \
+       do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
+#else
+#  define  QSOCKET_CALL(_ret,_cmd)   \
+       do { \
+               errno = 0; \
+               do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
+       } while (0);
+#endif
+
+#ifdef _WIN32
+
+#include <errno.h>
+
+static int  winsock_error;
+
+#define  WINSOCK_ERRORS_LIST \
+       EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
+EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
+EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
+EE(WSAEINTR,EINTR,"interrupted function call") \
+EE(WSAEALREADY,EALREADY,"operation already in progress") \
+EE(WSAEBADF,EBADF,"bad file descriptor") \
+EE(WSAEACCES,EACCES,"permission denied") \
+EE(WSAEFAULT,EFAULT,"bad address") \
+EE(WSAEINVAL,EINVAL,"invalid argument") \
+EE(WSAEMFILE,EMFILE,"too many opened files") \
+EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
+EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
+EE(WSAEALREADY,EAGAIN,"operation already in progress") \
+EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
+EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
+EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
+EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
+EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
+EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
+EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
+EE(WSAENETDOWN,ENETDOWN,"network is down") \
+EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
+EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
+EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
+EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
+EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
+EE(WSAEISCONN,EISCONN,"socket is already connected") \
+EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
+EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
+EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
+EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
+EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
+EE(WSAELOOP,ELOOP,"cannot translate name") \
+EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
+EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
+EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
+
+typedef struct {
+       int          winsock;
+       int          unix;
+       const char*  string;
+} WinsockError;
+
+static const WinsockError  _winsock_errors[] = {
+#define  EE(w,u,s)   { w, u, s },
+       WINSOCK_ERRORS_LIST
+#undef   EE
+       { -1, -1, NULL }
+};
+
+/* this function reads the latest winsock error code and updates
+ * errno to a matching value. It also returns the new value of
+ * errno.
+ */
+static int _fix_errno( void )
+{
+       const WinsockError*  werr = _winsock_errors;
+       int                  unix = EINVAL;  /* generic error code */
+
+       winsock_error = WSAGetLastError();
+
+       for ( ; werr->string != NULL; werr++ ) {
+               if (werr->winsock == winsock_error) {
+                       unix = werr->unix;
+                       break;
+               }
+       }
+       errno = unix;
+       return -1;
+}
+
+#else
+static int _fix_errno( void )
+{
+       return -1;
+}
+
+#endif
+
+#define  SOCKET_CALL(cmd)  \
+       int  ret; \
+QSOCKET_CALL(ret, (cmd)); \
+if (ret < 0) \
+return _fix_errno(); \
+return ret; \
+
+int socket_send(int  fd, const void*  buf, int  buflen)
+{
+       SOCKET_CALL(send(fd, buf, buflen, 0))
+}
+
+#ifdef _WIN32
+
+       static void
+socket_close_handler( void*  _fd )
+{
+       int   fd = (int)_fd;
+       int   ret;
+       char  buff[64];
+
+       /* we want to drain the read side of the socket before closing it */
+       do {
+               ret = recv( fd, buff, sizeof(buff), 0 );
+       } while (ret < 0 && WSAGetLastError() == WSAEINTR);
+
+       if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
+               return;
+
+       qemu_set_fd_handler( fd, NULL, NULL, NULL );
+       closesocket( fd );
+}
+
+       void
+socket_close( int  fd )
+{
+       int  old_errno = errno;
+
+       shutdown( fd, SD_BOTH );
+       /* we want to drain the socket before closing it */
+       qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
+
+       errno = old_errno;
+}
+
+#else /* !_WIN32 */
+
+#include <unistd.h>
+
+       void
+socket_close( int  fd )
+{
+       int  old_errno = errno;
+
+       shutdown( fd, SHUT_RDWR );
+       close( fd );
+
+       errno = old_errno;
+}
+
+#endif /* !_WIN32 */
+
+int inet_strtoip(const char*  str, uint32_t  *ip)
+{
+       int  comp[4];
+
+       if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
+               return -1;
+
+       if ((unsigned)comp[0] >= 256 ||
+                       (unsigned)comp[1] >= 256 ||
+                       (unsigned)comp[2] >= 256 ||
+                       (unsigned)comp[3] >= 256)
+               return -1;
+
+       *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
+                       (comp[2] << 8)  |  comp[3]);
+       return 0;
+}
+
+static int check_port_bind_listen(u_int port)
+{
+       struct sockaddr_in addr;
+       int s, opt = 1;
+       int ret = -1;
+       socklen_t addrlen = sizeof(addr);
+       memset(&addr, 0, addrlen);
+
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = INADDR_ANY;
+       addr.sin_port = htons(port);
+
+       if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
+#ifndef _WIN32
+                       (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||
+#endif
+                       (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||
+                       (listen(s, 1) < 0)) {
+
+               /* fail */
+               ret = -1;
+               ERR( "port(%d) listen  fail \n", port);
+       }else{
+               /*fsucess*/
+               ret = 1;
+               INFO( "port(%d) listen  ok \n", port);
+       }
+
+#ifdef _WIN32
+       closesocket(s);
+#else
+       close(s);
+#endif
+
+       return ret;
+}
+
+int get_sdb_base_port(void)
+{
+       int   tries     = 10;
+       int   success   = 0;
+       u_int port = 26100;
+
+       if(tizen_base_port == 0){
+
+               for ( ; tries > 0; tries--, port += 10 ) {
+                       if(check_port_bind_listen(port + 1) < 0 )
+                               continue;
+
+                       success = 1;
+                       break;
+               }
+
+               if (!success) {
+                       ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
+                       exit(1);
+               }
+
+               tizen_base_port = port;
+               INFO( "sdb port is %d \n", tizen_base_port);
+       }
+
+       return tizen_base_port;
+}
+
+void sdb_setup(void)
+{
+       int   tries     = 10;
+       int   success   = 0;
+       uint32_t  guest_ip;
+       char buf[64] = {0,};
+
+       inet_strtoip("10.0.2.16", &guest_ip);
+
+       for ( ; tries > 0; tries--, tizen_base_port += 10 ) {
+               // redir form [tcp:26101:10.0.2.16:26101]
+               sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);
+               if(net_slirp_redir((char*)buf) < 0)
+                       continue;
+
+               INFO( "SDBD established on port %d\n", tizen_base_port + 1);
+               success = 1;
+               break;
+       }
+
+       INFO("redirect [%s] success\n", buf);
+       if (!success) {
+               ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
+               exit(1);
+       }
+
+       INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);
+
+       /* for sensort */
+       sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );
+       if(net_slirp_redir((char*)buf) < 0){
+               ERR( "redirect [%s] fail \n", buf);
+       }else{
+               INFO("redirect [%s] success\n", buf);
+       }
+}
+
+int sdb_loopback_client(int port, int type)
+{
+    struct sockaddr_in addr;
+    int s;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    s = socket(AF_INET, type, 0);
+    if(s < 0) return -1;
+
+    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+        close(s);
+        return -1;
+    }
+
+    return s;
+
+}
+
+void notify_sdb_daemon_start(void) {
+    int s;
+    /* 
+     * send a simple message to the SDB host server to tell it we just started.
+     * it should be listening on port 26099.
+     */
+    do {
+        char tmp[32] = { 0 };
+
+        // when connecting to loopback:26099, do not use tcp_socket_outgoing function
+        // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.
+        s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);
+        if (s < 0) {
+            INFO("can't create socket to talk to the SDB server \n");
+            INFO("This emulator will be scaned by the SDB server \n");
+            break;
+        }
+
+        /* length is hex: 0x13 = 19 */
+        sprintf(tmp, "0013host:emulator:%d", tizen_base_port + 1);
+
+        if (socket_send(s, tmp, 30) < 0) {
+            ERR( "message sending to sdb server error!\n");
+        }
+
+    } while (0);
+
+    if (s >= 0)
+        socket_close(s);
+}