?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /* Replacement termios functions for MinGW32.  These versions of termios
  2.    functions serialize over a pipe to another process, which adjusts
  3.    the terminal.
  4.  
  5.    Copyright (C) 2008 CodeSourcery, Inc.
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  19.  
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <errno.h>
  23. #include <unistd.h>
  24.  
  25. #include "mingw-termios.h"
  26.  
  27. static HANDLE pipe_handle = INVALID_HANDLE_VALUE;
  28. static HANDLE pipe_mutex = INVALID_HANDLE_VALUE;
  29.  
  30. static int
  31. link_to_wrapper (void)
  32. {
  33.   static int tried = 0;
  34.  
  35.   if (!tried)
  36.     {
  37.       char pipe_name[256];
  38.  
  39.       tried = 1;
  40.  
  41.       /* Connect to the named pipe for communication with the wrapper.  */
  42.       sprintf (pipe_name, "\\\\.\\pipe\\gdb_wrapper_%ld",
  43.                GetCurrentProcessId ());
  44.  
  45.       pipe_handle = CreateFile (pipe_name,
  46.                                 GENERIC_READ | GENERIC_WRITE,
  47.                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
  48.                                 NULL,
  49.                                 OPEN_EXISTING,
  50.                                 0,
  51.                                 NULL);
  52.       if (pipe_handle != INVALID_HANDLE_VALUE)
  53.         pipe_mutex = CreateMutex (NULL, TRUE, NULL);
  54.     }
  55.   else if (pipe_mutex != INVALID_HANDLE_VALUE)
  56.     WaitForSingleObject (pipe_mutex, INFINITE);
  57.  
  58.   return (pipe_handle != INVALID_HANDLE_VALUE);
  59. }
  60.  
  61. static int
  62. cygming_wrapper_cmd (const char *cmd, const void *args, int arglen, int *ret,
  63.                      char **retdata)
  64. {
  65.   if (link_to_wrapper ())
  66.     {
  67.       static char buf[4096] = {0};
  68.       int len = strlen (cmd) + 1;
  69.       DWORD read;
  70.       DWORD written;
  71.  
  72.       memcpy (buf, cmd, len);
  73.       memcpy (buf + len, args, arglen);
  74.       //fprintf (stderr, "%.8lx writing to the wrapper\n", GetCurrentThreadId ());
  75.       if (!WriteFile (pipe_handle, buf, len + arglen, &written, NULL))
  76.         {
  77.           fprintf (stderr, "error writting to cygming wrapper: %ld\n", GetLastError ());
  78.           fflush (stderr);
  79.           ReleaseMutex (pipe_mutex);
  80.           return 0;
  81.         }
  82.  
  83.       if (!ReadFile (pipe_handle, buf, sizeof (buf), &read, NULL))
  84.         {
  85.           fprintf (stderr, "error waiting for cygming wrapper response: %ld",
  86.                    GetLastError ());
  87.           fflush (stderr);
  88.           ReleaseMutex (pipe_mutex);
  89.           return 0;
  90.         }
  91.       //fprintf (stderr, "%.8lx finished read from the wrapper\n", GetCurrentThreadId ());
  92.  
  93.       /* The returned value should be "OK" <number> ';' <bytes>.  */
  94.       if (memcmp (buf, "OK", 2) != 0)
  95.         {
  96.           fprintf (stderr, "error: unexpected wrapper response: %s\n", buf);
  97.           fflush (stderr);
  98.           ReleaseMutex (pipe_mutex);
  99.           return 0;
  100.         }
  101.  
  102.       *ret = strtol (buf + 2, retdata, 0);
  103.       (*retdata)++;
  104.       ReleaseMutex (pipe_mutex);
  105.       return 1;
  106.     }
  107.   else
  108.     return 0;
  109. }
  110.  
  111. int
  112. tcgetattr (int fd, struct termios *buf)
  113. {
  114.   int ret;
  115.   char *retdata;
  116.  
  117.   if (cygming_wrapper_cmd ("tcgetattr", "", 0, &ret, &retdata))
  118.     {
  119.       if (ret == 0)
  120.         memcpy (buf, retdata, sizeof (*buf));
  121.       else
  122.         errno = EINVAL;
  123.       return ret;
  124.     }
  125.   else
  126.     {
  127.       memset (buf, 0, sizeof (*buf));
  128.       /* If FD is a TTY, readline will use getch for it, so we will
  129.          must echo manually - getch does not echo.  If it is not a
  130.          TTY, we must not echo since we have no way to disable the
  131.          typical echo.  */
  132.       if (isatty (fd))
  133.         buf->c_lflag = ECHO;
  134.       return 0;
  135.     }
  136. }
  137.  
  138. int
  139. tcsetattr (int fd, int actions, const struct termios *buf)
  140. {
  141.   int ret;
  142.   char *retdata;
  143.   if (cygming_wrapper_cmd ("tcsetattr", buf, sizeof (*buf), &ret, &retdata))
  144.     {
  145.       if (ret != 0)
  146.         errno = EINVAL;
  147.       return ret;
  148.     }
  149.   else
  150.     {
  151.       errno = EINVAL;
  152.       return -1;
  153.     }
  154. }
  155.  
  156. int
  157. tcdrain (int fd)
  158. {
  159.   int ret;
  160.   char *retdata;
  161.   if (cygming_wrapper_cmd ("tcdrain", "", 0, &ret, &retdata))
  162.     {
  163.       if (ret != 0)
  164.         errno = EINVAL;
  165.       return ret;
  166.     }
  167.   else
  168.     {
  169.       errno = EINVAL;
  170.       return -1;
  171.     }
  172. }
  173.  
  174. int
  175. tcflow (int fd, int action)
  176. {
  177.   errno = ENOTTY;
  178.   return -1;
  179. }
  180.  
  181. int
  182. mingw_getwinsize (struct winsize *window_size)
  183. {
  184.   int ret;
  185.   char *retdata;
  186.   if (cygming_wrapper_cmd ("getwinsize", "", 0, &ret, &retdata))
  187.     {
  188.       if (ret == 0)
  189.         memcpy (window_size, retdata, sizeof (*window_size));
  190.       else
  191.         errno = EINVAL;
  192.       return ret;
  193.     }
  194.   else
  195.     {
  196.       errno = EINVAL;
  197.       return -1;
  198.     }
  199. }
  200.