Home | History | Annotate | Line # | Download | only in gdb
ser-mingw.c revision 1.1.1.7
      1      1.1  christos /* Serial interface for local (hardwired) serial ports on Windows systems
      2      1.1  christos 
      3  1.1.1.7  christos    Copyright (C) 2006-2020 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "defs.h"
     21      1.1  christos #include "serial.h"
     22      1.1  christos #include "ser-base.h"
     23      1.1  christos #include "ser-tcp.h"
     24      1.1  christos 
     25      1.1  christos #include <windows.h>
     26      1.1  christos #include <conio.h>
     27      1.1  christos 
     28      1.1  christos #include <fcntl.h>
     29      1.1  christos #include <unistd.h>
     30      1.1  christos #include <sys/types.h>
     31      1.1  christos 
     32      1.1  christos #include "command.h"
     33      1.1  christos 
     34      1.1  christos struct ser_windows_state
     35      1.1  christos {
     36      1.1  christos   int in_progress;
     37      1.1  christos   OVERLAPPED ov;
     38      1.1  christos   DWORD lastCommMask;
     39      1.1  christos   HANDLE except_event;
     40      1.1  christos };
     41      1.1  christos 
     42      1.1  christos /* CancelIo is not available for Windows 95 OS, so we need to use
     43      1.1  christos    LoadLibrary/GetProcAddress to avoid a startup failure.  */
     44      1.1  christos #define CancelIo dyn_CancelIo
     45  1.1.1.4  christos typedef BOOL WINAPI (CancelIo_ftype) (HANDLE);
     46  1.1.1.4  christos static CancelIo_ftype *CancelIo;
     47      1.1  christos 
     48      1.1  christos /* Open up a real live device for serial I/O.  */
     49      1.1  christos 
     50      1.1  christos static int
     51      1.1  christos ser_windows_open (struct serial *scb, const char *name)
     52      1.1  christos {
     53      1.1  christos   HANDLE h;
     54      1.1  christos   struct ser_windows_state *state;
     55      1.1  christos   COMMTIMEOUTS timeouts;
     56      1.1  christos 
     57      1.1  christos   h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
     58      1.1  christos 		  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
     59      1.1  christos   if (h == INVALID_HANDLE_VALUE)
     60      1.1  christos     {
     61      1.1  christos       errno = ENOENT;
     62      1.1  christos       return -1;
     63      1.1  christos     }
     64      1.1  christos 
     65      1.1  christos   scb->fd = _open_osfhandle ((intptr_t) h, O_RDWR);
     66      1.1  christos   if (scb->fd < 0)
     67      1.1  christos     {
     68      1.1  christos       errno = ENOENT;
     69      1.1  christos       return -1;
     70      1.1  christos     }
     71      1.1  christos 
     72      1.1  christos   if (!SetCommMask (h, EV_RXCHAR))
     73      1.1  christos     {
     74      1.1  christos       errno = EINVAL;
     75      1.1  christos       return -1;
     76      1.1  christos     }
     77      1.1  christos 
     78      1.1  christos   timeouts.ReadIntervalTimeout = MAXDWORD;
     79      1.1  christos   timeouts.ReadTotalTimeoutConstant = 0;
     80      1.1  christos   timeouts.ReadTotalTimeoutMultiplier = 0;
     81      1.1  christos   timeouts.WriteTotalTimeoutConstant = 0;
     82      1.1  christos   timeouts.WriteTotalTimeoutMultiplier = 0;
     83      1.1  christos   if (!SetCommTimeouts (h, &timeouts))
     84      1.1  christos     {
     85      1.1  christos       errno = EINVAL;
     86      1.1  christos       return -1;
     87      1.1  christos     }
     88      1.1  christos 
     89  1.1.1.4  christos   state = XCNEW (struct ser_windows_state);
     90      1.1  christos   scb->state = state;
     91      1.1  christos 
     92      1.1  christos   /* Create a manual reset event to watch the input buffer.  */
     93      1.1  christos   state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);
     94      1.1  christos 
     95      1.1  christos   /* Create a (currently unused) handle to record exceptions.  */
     96      1.1  christos   state->except_event = CreateEvent (0, TRUE, FALSE, 0);
     97      1.1  christos 
     98      1.1  christos   return 0;
     99      1.1  christos }
    100      1.1  christos 
    101      1.1  christos /* Wait for the output to drain away, as opposed to flushing (discarding)
    102      1.1  christos    it.  */
    103      1.1  christos 
    104      1.1  christos static int
    105      1.1  christos ser_windows_drain_output (struct serial *scb)
    106      1.1  christos {
    107      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    108      1.1  christos 
    109      1.1  christos   return (FlushFileBuffers (h) != 0) ? 0 : -1;
    110      1.1  christos }
    111      1.1  christos 
    112      1.1  christos static int
    113      1.1  christos ser_windows_flush_output (struct serial *scb)
    114      1.1  christos {
    115      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    116      1.1  christos 
    117      1.1  christos   return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
    118      1.1  christos }
    119      1.1  christos 
    120      1.1  christos static int
    121      1.1  christos ser_windows_flush_input (struct serial *scb)
    122      1.1  christos {
    123      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    124      1.1  christos 
    125      1.1  christos   return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
    126      1.1  christos }
    127      1.1  christos 
    128      1.1  christos static int
    129      1.1  christos ser_windows_send_break (struct serial *scb)
    130      1.1  christos {
    131      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    132      1.1  christos 
    133      1.1  christos   if (SetCommBreak (h) == 0)
    134      1.1  christos     return -1;
    135      1.1  christos 
    136      1.1  christos   /* Delay for 250 milliseconds.  */
    137      1.1  christos   Sleep (250);
    138      1.1  christos 
    139      1.1  christos   if (ClearCommBreak (h))
    140      1.1  christos     return -1;
    141      1.1  christos 
    142      1.1  christos   return 0;
    143      1.1  christos }
    144      1.1  christos 
    145      1.1  christos static void
    146      1.1  christos ser_windows_raw (struct serial *scb)
    147      1.1  christos {
    148      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    149      1.1  christos   DCB state;
    150      1.1  christos 
    151      1.1  christos   if (GetCommState (h, &state) == 0)
    152      1.1  christos     return;
    153      1.1  christos 
    154      1.1  christos   state.fOutxCtsFlow = FALSE;
    155      1.1  christos   state.fOutxDsrFlow = FALSE;
    156      1.1  christos   state.fDtrControl = DTR_CONTROL_ENABLE;
    157      1.1  christos   state.fDsrSensitivity = FALSE;
    158      1.1  christos   state.fOutX = FALSE;
    159      1.1  christos   state.fInX = FALSE;
    160      1.1  christos   state.fNull = FALSE;
    161      1.1  christos   state.fAbortOnError = FALSE;
    162      1.1  christos   state.ByteSize = 8;
    163      1.1  christos 
    164      1.1  christos   if (SetCommState (h, &state) == 0)
    165      1.1  christos     warning (_("SetCommState failed"));
    166      1.1  christos }
    167      1.1  christos 
    168      1.1  christos static int
    169      1.1  christos ser_windows_setstopbits (struct serial *scb, int num)
    170      1.1  christos {
    171      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    172      1.1  christos   DCB state;
    173      1.1  christos 
    174      1.1  christos   if (GetCommState (h, &state) == 0)
    175      1.1  christos     return -1;
    176      1.1  christos 
    177      1.1  christos   switch (num)
    178      1.1  christos     {
    179      1.1  christos     case SERIAL_1_STOPBITS:
    180      1.1  christos       state.StopBits = ONESTOPBIT;
    181      1.1  christos       break;
    182      1.1  christos     case SERIAL_1_AND_A_HALF_STOPBITS:
    183      1.1  christos       state.StopBits = ONE5STOPBITS;
    184      1.1  christos       break;
    185      1.1  christos     case SERIAL_2_STOPBITS:
    186      1.1  christos       state.StopBits = TWOSTOPBITS;
    187      1.1  christos       break;
    188      1.1  christos     default:
    189      1.1  christos       return 1;
    190      1.1  christos     }
    191      1.1  christos 
    192      1.1  christos   return (SetCommState (h, &state) != 0) ? 0 : -1;
    193      1.1  christos }
    194      1.1  christos 
    195  1.1.1.3  christos /* Implement the "setparity" serial_ops callback.  */
    196  1.1.1.3  christos 
    197  1.1.1.3  christos static int
    198  1.1.1.3  christos ser_windows_setparity (struct serial *scb, int parity)
    199  1.1.1.3  christos {
    200  1.1.1.3  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    201  1.1.1.3  christos   DCB state;
    202  1.1.1.3  christos 
    203  1.1.1.3  christos   if (GetCommState (h, &state) == 0)
    204  1.1.1.3  christos     return -1;
    205  1.1.1.3  christos 
    206  1.1.1.3  christos   switch (parity)
    207  1.1.1.3  christos     {
    208  1.1.1.3  christos     case GDBPARITY_NONE:
    209  1.1.1.3  christos       state.Parity = NOPARITY;
    210  1.1.1.3  christos       state.fParity = FALSE;
    211  1.1.1.3  christos       break;
    212  1.1.1.3  christos     case GDBPARITY_ODD:
    213  1.1.1.3  christos       state.Parity = ODDPARITY;
    214  1.1.1.3  christos       state.fParity = TRUE;
    215  1.1.1.3  christos       break;
    216  1.1.1.3  christos     case GDBPARITY_EVEN:
    217  1.1.1.3  christos       state.Parity = EVENPARITY;
    218  1.1.1.3  christos       state.fParity = TRUE;
    219  1.1.1.3  christos       break;
    220  1.1.1.3  christos     default:
    221  1.1.1.3  christos       internal_warning (__FILE__, __LINE__,
    222  1.1.1.3  christos 			"Incorrect parity value: %d", parity);
    223  1.1.1.3  christos       return -1;
    224  1.1.1.3  christos     }
    225  1.1.1.3  christos 
    226  1.1.1.3  christos   return (SetCommState (h, &state) != 0) ? 0 : -1;
    227  1.1.1.3  christos }
    228  1.1.1.3  christos 
    229      1.1  christos static int
    230      1.1  christos ser_windows_setbaudrate (struct serial *scb, int rate)
    231      1.1  christos {
    232      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    233      1.1  christos   DCB state;
    234      1.1  christos 
    235      1.1  christos   if (GetCommState (h, &state) == 0)
    236      1.1  christos     return -1;
    237      1.1  christos 
    238      1.1  christos   state.BaudRate = rate;
    239      1.1  christos 
    240      1.1  christos   return (SetCommState (h, &state) != 0) ? 0 : -1;
    241      1.1  christos }
    242      1.1  christos 
    243      1.1  christos static void
    244      1.1  christos ser_windows_close (struct serial *scb)
    245      1.1  christos {
    246      1.1  christos   struct ser_windows_state *state;
    247      1.1  christos 
    248      1.1  christos   /* Stop any pending selects.  On Windows 95 OS, CancelIo function does
    249      1.1  christos      not exist.  In that case, it can be replaced by a call to CloseHandle,
    250      1.1  christos      but this is not necessary here as we do close the Windows handle
    251      1.1  christos      by calling close (scb->fd) below.  */
    252      1.1  christos   if (CancelIo)
    253      1.1  christos     CancelIo ((HANDLE) _get_osfhandle (scb->fd));
    254  1.1.1.4  christos   state = (struct ser_windows_state *) scb->state;
    255      1.1  christos   CloseHandle (state->ov.hEvent);
    256      1.1  christos   CloseHandle (state->except_event);
    257      1.1  christos 
    258      1.1  christos   if (scb->fd < 0)
    259      1.1  christos     return;
    260      1.1  christos 
    261      1.1  christos   close (scb->fd);
    262      1.1  christos   scb->fd = -1;
    263      1.1  christos 
    264      1.1  christos   xfree (scb->state);
    265      1.1  christos }
    266      1.1  christos 
    267      1.1  christos static void
    268      1.1  christos ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
    269      1.1  christos {
    270      1.1  christos   struct ser_windows_state *state;
    271      1.1  christos   COMSTAT status;
    272      1.1  christos   DWORD errors;
    273      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
    274      1.1  christos 
    275  1.1.1.4  christos   state = (struct ser_windows_state *) scb->state;
    276      1.1  christos 
    277      1.1  christos   *except = state->except_event;
    278      1.1  christos   *read = state->ov.hEvent;
    279      1.1  christos 
    280      1.1  christos   if (state->in_progress)
    281      1.1  christos     return;
    282      1.1  christos 
    283      1.1  christos   /* Reset the mask - we are only interested in any characters which
    284      1.1  christos      arrive after this point, not characters which might have arrived
    285      1.1  christos      and already been read.  */
    286      1.1  christos 
    287      1.1  christos   /* This really, really shouldn't be necessary - just the second one.
    288      1.1  christos      But otherwise an internal flag for EV_RXCHAR does not get
    289      1.1  christos      cleared, and we get a duplicated event, if the last batch
    290      1.1  christos      of characters included at least two arriving close together.  */
    291      1.1  christos   if (!SetCommMask (h, 0))
    292      1.1  christos     warning (_("ser_windows_wait_handle: reseting mask failed"));
    293      1.1  christos 
    294      1.1  christos   if (!SetCommMask (h, EV_RXCHAR))
    295      1.1  christos     warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
    296      1.1  christos 
    297      1.1  christos   /* There's a potential race condition here; we must check cbInQue
    298      1.1  christos      and not wait if that's nonzero.  */
    299      1.1  christos 
    300      1.1  christos   ClearCommError (h, &errors, &status);
    301      1.1  christos   if (status.cbInQue > 0)
    302      1.1  christos     {
    303      1.1  christos       SetEvent (state->ov.hEvent);
    304      1.1  christos       return;
    305      1.1  christos     }
    306      1.1  christos 
    307      1.1  christos   state->in_progress = 1;
    308      1.1  christos   ResetEvent (state->ov.hEvent);
    309      1.1  christos   state->lastCommMask = -2;
    310      1.1  christos   if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
    311      1.1  christos     {
    312      1.1  christos       gdb_assert (state->lastCommMask & EV_RXCHAR);
    313      1.1  christos       SetEvent (state->ov.hEvent);
    314      1.1  christos     }
    315      1.1  christos   else
    316      1.1  christos     gdb_assert (GetLastError () == ERROR_IO_PENDING);
    317      1.1  christos }
    318      1.1  christos 
    319      1.1  christos static int
    320      1.1  christos ser_windows_read_prim (struct serial *scb, size_t count)
    321      1.1  christos {
    322      1.1  christos   struct ser_windows_state *state;
    323      1.1  christos   OVERLAPPED ov;
    324  1.1.1.6  christos   DWORD bytes_read;
    325      1.1  christos   HANDLE h;
    326      1.1  christos 
    327  1.1.1.4  christos   state = (struct ser_windows_state *) scb->state;
    328      1.1  christos   if (state->in_progress)
    329      1.1  christos     {
    330      1.1  christos       WaitForSingleObject (state->ov.hEvent, INFINITE);
    331      1.1  christos       state->in_progress = 0;
    332      1.1  christos       ResetEvent (state->ov.hEvent);
    333      1.1  christos     }
    334      1.1  christos 
    335      1.1  christos   memset (&ov, 0, sizeof (OVERLAPPED));
    336      1.1  christos   ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
    337      1.1  christos   h = (HANDLE) _get_osfhandle (scb->fd);
    338      1.1  christos 
    339      1.1  christos   if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
    340      1.1  christos     {
    341      1.1  christos       if (GetLastError () != ERROR_IO_PENDING
    342      1.1  christos 	  || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
    343      1.1  christos 	bytes_read = -1;
    344      1.1  christos     }
    345      1.1  christos 
    346      1.1  christos   CloseHandle (ov.hEvent);
    347      1.1  christos   return bytes_read;
    348      1.1  christos }
    349      1.1  christos 
    350      1.1  christos static int
    351      1.1  christos ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
    352      1.1  christos {
    353      1.1  christos   OVERLAPPED ov;
    354      1.1  christos   DWORD bytes_written;
    355      1.1  christos   HANDLE h;
    356      1.1  christos 
    357      1.1  christos   memset (&ov, 0, sizeof (OVERLAPPED));
    358      1.1  christos   ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
    359      1.1  christos   h = (HANDLE) _get_osfhandle (scb->fd);
    360      1.1  christos   if (!WriteFile (h, buf, len, &bytes_written, &ov))
    361      1.1  christos     {
    362      1.1  christos       if (GetLastError () != ERROR_IO_PENDING
    363      1.1  christos 	  || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
    364      1.1  christos 	bytes_written = -1;
    365      1.1  christos     }
    366      1.1  christos 
    367      1.1  christos   CloseHandle (ov.hEvent);
    368      1.1  christos   return bytes_written;
    369      1.1  christos }
    370      1.1  christos 
    371      1.1  christos /* On Windows, gdb_select is implemented using WaitForMulpleObjects.
    372      1.1  christos    A "select thread" is created for each file descriptor.  These
    373      1.1  christos    threads looks for activity on the corresponding descriptor, using
    374      1.1  christos    whatever techniques are appropriate for the descriptor type.  When
    375      1.1  christos    that activity occurs, the thread signals an appropriate event,
    376      1.1  christos    which wakes up WaitForMultipleObjects.
    377      1.1  christos 
    378      1.1  christos    Each select thread is in one of two states: stopped or started.
    379      1.1  christos    Select threads begin in the stopped state.  When gdb_select is
    380      1.1  christos    called, threads corresponding to the descriptors of interest are
    381      1.1  christos    started by calling a wait_handle function.  Each thread that
    382      1.1  christos    notices activity signals the appropriate event and then reenters
    383      1.1  christos    the stopped state.  Before gdb_select returns it calls the
    384      1.1  christos    wait_handle_done functions, which return the threads to the stopped
    385      1.1  christos    state.  */
    386      1.1  christos 
    387      1.1  christos enum select_thread_state {
    388      1.1  christos   STS_STARTED,
    389      1.1  christos   STS_STOPPED
    390      1.1  christos };
    391      1.1  christos 
    392      1.1  christos struct ser_console_state
    393      1.1  christos {
    394      1.1  christos   /* Signaled by the select thread to indicate that data is available
    395      1.1  christos      on the file descriptor.  */
    396      1.1  christos   HANDLE read_event;
    397      1.1  christos   /* Signaled by the select thread to indicate that an exception has
    398      1.1  christos      occurred on the file descriptor.  */
    399      1.1  christos   HANDLE except_event;
    400      1.1  christos   /* Signaled by the select thread to indicate that it has entered the
    401      1.1  christos      started state.  HAVE_STARTED and HAVE_STOPPED are never signaled
    402      1.1  christos      simultaneously.  */
    403      1.1  christos   HANDLE have_started;
    404      1.1  christos   /* Signaled by the select thread to indicate that it has stopped,
    405      1.1  christos      either because data is available (and READ_EVENT is signaled),
    406      1.1  christos      because an exception has occurred (and EXCEPT_EVENT is signaled),
    407      1.1  christos      or because STOP_SELECT was signaled.  */
    408      1.1  christos   HANDLE have_stopped;
    409      1.1  christos 
    410      1.1  christos   /* Signaled by the main program to tell the select thread to enter
    411      1.1  christos      the started state.  */
    412      1.1  christos   HANDLE start_select;
    413      1.1  christos   /* Signaled by the main program to tell the select thread to enter
    414      1.1  christos      the stopped state.  */
    415      1.1  christos   HANDLE stop_select;
    416      1.1  christos   /* Signaled by the main program to tell the select thread to
    417      1.1  christos      exit.  */
    418      1.1  christos   HANDLE exit_select;
    419      1.1  christos 
    420      1.1  christos   /* The handle for the select thread.  */
    421      1.1  christos   HANDLE thread;
    422      1.1  christos   /* The state of the select thread.  This field is only accessed in
    423      1.1  christos      the main program, never by the select thread itself.  */
    424      1.1  christos   enum select_thread_state thread_state;
    425      1.1  christos };
    426      1.1  christos 
    427      1.1  christos /* Called by a select thread to enter the stopped state.  This
    428      1.1  christos    function does not return until the thread has re-entered the
    429      1.1  christos    started state.  */
    430      1.1  christos static void
    431      1.1  christos select_thread_wait (struct ser_console_state *state)
    432      1.1  christos {
    433      1.1  christos   HANDLE wait_events[2];
    434      1.1  christos 
    435      1.1  christos   /* There are two things that can wake us up: a request that we enter
    436      1.1  christos      the started state, or that we exit this thread.  */
    437      1.1  christos   wait_events[0] = state->start_select;
    438      1.1  christos   wait_events[1] = state->exit_select;
    439      1.1  christos   if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE)
    440      1.1  christos       != WAIT_OBJECT_0)
    441      1.1  christos     /* Either the EXIT_SELECT event was signaled (requesting that the
    442      1.1  christos        thread exit) or an error has occurred.  In either case, we exit
    443      1.1  christos        the thread.  */
    444      1.1  christos     ExitThread (0);
    445      1.1  christos 
    446      1.1  christos   /* We are now in the started state.  */
    447      1.1  christos   SetEvent (state->have_started);
    448      1.1  christos }
    449      1.1  christos 
    450      1.1  christos typedef DWORD WINAPI (*thread_fn_type)(void *);
    451      1.1  christos 
    452      1.1  christos /* Create a new select thread for SCB executing THREAD_FN.  The STATE
    453      1.1  christos    will be filled in by this function before return.  */
    454      1.1  christos static void
    455      1.1  christos create_select_thread (thread_fn_type thread_fn,
    456      1.1  christos 		      struct serial *scb,
    457      1.1  christos 		      struct ser_console_state *state)
    458      1.1  christos {
    459      1.1  christos   DWORD threadId;
    460      1.1  christos 
    461      1.1  christos   /* Create all of the events.  These are all auto-reset events.  */
    462      1.1  christos   state->read_event = CreateEvent (NULL, FALSE, FALSE, NULL);
    463      1.1  christos   state->except_event = CreateEvent (NULL, FALSE, FALSE, NULL);
    464      1.1  christos   state->have_started = CreateEvent (NULL, FALSE, FALSE, NULL);
    465      1.1  christos   state->have_stopped = CreateEvent (NULL, FALSE, FALSE, NULL);
    466      1.1  christos   state->start_select = CreateEvent (NULL, FALSE, FALSE, NULL);
    467      1.1  christos   state->stop_select = CreateEvent (NULL, FALSE, FALSE, NULL);
    468      1.1  christos   state->exit_select = CreateEvent (NULL, FALSE, FALSE, NULL);
    469      1.1  christos 
    470      1.1  christos   state->thread = CreateThread (NULL, 0, thread_fn, scb, 0, &threadId);
    471      1.1  christos   /* The thread begins in the stopped state.  */
    472      1.1  christos   state->thread_state = STS_STOPPED;
    473      1.1  christos }
    474      1.1  christos 
    475      1.1  christos /* Destroy the select thread indicated by STATE.  */
    476      1.1  christos static void
    477      1.1  christos destroy_select_thread (struct ser_console_state *state)
    478      1.1  christos {
    479      1.1  christos   /* Ask the thread to exit.  */
    480      1.1  christos   SetEvent (state->exit_select);
    481      1.1  christos   /* Wait until it does.  */
    482      1.1  christos   WaitForSingleObject (state->thread, INFINITE);
    483      1.1  christos 
    484      1.1  christos   /* Destroy the events.  */
    485      1.1  christos   CloseHandle (state->read_event);
    486      1.1  christos   CloseHandle (state->except_event);
    487      1.1  christos   CloseHandle (state->have_started);
    488      1.1  christos   CloseHandle (state->have_stopped);
    489      1.1  christos   CloseHandle (state->start_select);
    490      1.1  christos   CloseHandle (state->stop_select);
    491      1.1  christos   CloseHandle (state->exit_select);
    492      1.1  christos }
    493      1.1  christos 
    494      1.1  christos /* Called by gdb_select to start the select thread indicated by STATE.
    495      1.1  christos    This function does not return until the thread has started.  */
    496      1.1  christos static void
    497      1.1  christos start_select_thread (struct ser_console_state *state)
    498      1.1  christos {
    499      1.1  christos   /* Ask the thread to start.  */
    500      1.1  christos   SetEvent (state->start_select);
    501      1.1  christos   /* Wait until it does.  */
    502      1.1  christos   WaitForSingleObject (state->have_started, INFINITE);
    503      1.1  christos   /* The thread is now started.  */
    504      1.1  christos   state->thread_state = STS_STARTED;
    505      1.1  christos }
    506      1.1  christos 
    507      1.1  christos /* Called by gdb_select to stop the select thread indicated by STATE.
    508      1.1  christos    This function does not return until the thread has stopped.  */
    509      1.1  christos static void
    510      1.1  christos stop_select_thread (struct ser_console_state *state)
    511      1.1  christos {
    512      1.1  christos   /* If the thread is already in the stopped state, we have nothing to
    513      1.1  christos      do.  Some of the wait_handle functions avoid calling
    514      1.1  christos      start_select_thread if they notice activity on the relevant file
    515      1.1  christos      descriptors.  The wait_handle_done functions still call
    516      1.1  christos      stop_select_thread -- but it is already stopped.  */
    517      1.1  christos   if (state->thread_state != STS_STARTED)
    518      1.1  christos     return;
    519      1.1  christos   /* Ask the thread to stop.  */
    520      1.1  christos   SetEvent (state->stop_select);
    521      1.1  christos   /* Wait until it does.  */
    522      1.1  christos   WaitForSingleObject (state->have_stopped, INFINITE);
    523      1.1  christos   /* The thread is now stopped.  */
    524      1.1  christos   state->thread_state = STS_STOPPED;
    525      1.1  christos }
    526      1.1  christos 
    527      1.1  christos static DWORD WINAPI
    528      1.1  christos console_select_thread (void *arg)
    529      1.1  christos {
    530  1.1.1.4  christos   struct serial *scb = (struct serial *) arg;
    531      1.1  christos   struct ser_console_state *state;
    532      1.1  christos   int event_index;
    533      1.1  christos   HANDLE h;
    534      1.1  christos 
    535  1.1.1.4  christos   state = (struct ser_console_state *) scb->state;
    536      1.1  christos   h = (HANDLE) _get_osfhandle (scb->fd);
    537      1.1  christos 
    538      1.1  christos   while (1)
    539      1.1  christos     {
    540      1.1  christos       HANDLE wait_events[2];
    541      1.1  christos       INPUT_RECORD record;
    542      1.1  christos       DWORD n_records;
    543      1.1  christos 
    544      1.1  christos       select_thread_wait (state);
    545      1.1  christos 
    546      1.1  christos       while (1)
    547      1.1  christos 	{
    548      1.1  christos 	  wait_events[0] = state->stop_select;
    549      1.1  christos 	  wait_events[1] = h;
    550      1.1  christos 
    551      1.1  christos 	  event_index = WaitForMultipleObjects (2, wait_events,
    552      1.1  christos 						FALSE, INFINITE);
    553      1.1  christos 
    554      1.1  christos 	  if (event_index == WAIT_OBJECT_0
    555      1.1  christos 	      || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
    556      1.1  christos 	    break;
    557      1.1  christos 
    558      1.1  christos 	  if (event_index != WAIT_OBJECT_0 + 1)
    559      1.1  christos 	    {
    560      1.1  christos 	      /* Wait must have failed; assume an error has occured, e.g.
    561      1.1  christos 		 the handle has been closed.  */
    562      1.1  christos 	      SetEvent (state->except_event);
    563      1.1  christos 	      break;
    564      1.1  christos 	    }
    565      1.1  christos 
    566      1.1  christos 	  /* We've got a pending event on the console.  See if it's
    567      1.1  christos 	     of interest.  */
    568      1.1  christos 	  if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
    569      1.1  christos 	    {
    570      1.1  christos 	      /* Something went wrong.  Maybe the console is gone.  */
    571      1.1  christos 	      SetEvent (state->except_event);
    572      1.1  christos 	      break;
    573      1.1  christos 	    }
    574      1.1  christos 
    575      1.1  christos 	  if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
    576      1.1  christos 	    {
    577      1.1  christos 	      WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;
    578      1.1  christos 
    579      1.1  christos 	      /* Ignore events containing only control keys.  We must
    580      1.1  christos 		 recognize "enhanced" keys which we are interested in
    581      1.1  christos 		 reading via getch, if they do not map to ASCII.  But we
    582      1.1  christos 		 do not want to report input available for e.g. the
    583      1.1  christos 		 control key alone.  */
    584      1.1  christos 
    585      1.1  christos 	      if (record.Event.KeyEvent.uChar.AsciiChar != 0
    586      1.1  christos 		  || keycode == VK_PRIOR
    587      1.1  christos 		  || keycode == VK_NEXT
    588      1.1  christos 		  || keycode == VK_END
    589      1.1  christos 		  || keycode == VK_HOME
    590      1.1  christos 		  || keycode == VK_LEFT
    591      1.1  christos 		  || keycode == VK_UP
    592      1.1  christos 		  || keycode == VK_RIGHT
    593      1.1  christos 		  || keycode == VK_DOWN
    594      1.1  christos 		  || keycode == VK_INSERT
    595      1.1  christos 		  || keycode == VK_DELETE)
    596      1.1  christos 		{
    597      1.1  christos 		  /* This is really a keypress.  */
    598      1.1  christos 		  SetEvent (state->read_event);
    599      1.1  christos 		  break;
    600      1.1  christos 		}
    601      1.1  christos 	    }
    602      1.1  christos 
    603      1.1  christos 	  /* Otherwise discard it and wait again.  */
    604      1.1  christos 	  ReadConsoleInput (h, &record, 1, &n_records);
    605      1.1  christos 	}
    606      1.1  christos 
    607      1.1  christos       SetEvent(state->have_stopped);
    608      1.1  christos     }
    609      1.1  christos   return 0;
    610      1.1  christos }
    611      1.1  christos 
    612      1.1  christos static int
    613      1.1  christos fd_is_pipe (int fd)
    614      1.1  christos {
    615      1.1  christos   if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
    616      1.1  christos     return 1;
    617      1.1  christos   else
    618      1.1  christos     return 0;
    619      1.1  christos }
    620      1.1  christos 
    621      1.1  christos static int
    622      1.1  christos fd_is_file (int fd)
    623      1.1  christos {
    624      1.1  christos   if (GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_DISK)
    625      1.1  christos     return 1;
    626      1.1  christos   else
    627      1.1  christos     return 0;
    628      1.1  christos }
    629      1.1  christos 
    630      1.1  christos static DWORD WINAPI
    631      1.1  christos pipe_select_thread (void *arg)
    632      1.1  christos {
    633  1.1.1.4  christos   struct serial *scb = (struct serial *) arg;
    634      1.1  christos   struct ser_console_state *state;
    635      1.1  christos   HANDLE h;
    636      1.1  christos 
    637  1.1.1.4  christos   state = (struct ser_console_state *) scb->state;
    638      1.1  christos   h = (HANDLE) _get_osfhandle (scb->fd);
    639      1.1  christos 
    640      1.1  christos   while (1)
    641      1.1  christos     {
    642      1.1  christos       DWORD n_avail;
    643      1.1  christos 
    644      1.1  christos       select_thread_wait (state);
    645      1.1  christos 
    646      1.1  christos       /* Wait for something to happen on the pipe.  */
    647      1.1  christos       while (1)
    648      1.1  christos 	{
    649      1.1  christos 	  if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
    650      1.1  christos 	    {
    651      1.1  christos 	      SetEvent (state->except_event);
    652      1.1  christos 	      break;
    653      1.1  christos 	    }
    654      1.1  christos 
    655      1.1  christos 	  if (n_avail > 0)
    656      1.1  christos 	    {
    657      1.1  christos 	      SetEvent (state->read_event);
    658      1.1  christos 	      break;
    659      1.1  christos 	    }
    660      1.1  christos 
    661      1.1  christos 	  /* Delay 10ms before checking again, but allow the stop
    662      1.1  christos 	     event to wake us.  */
    663      1.1  christos 	  if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
    664      1.1  christos 	    break;
    665      1.1  christos 	}
    666      1.1  christos 
    667      1.1  christos       SetEvent (state->have_stopped);
    668      1.1  christos     }
    669      1.1  christos   return 0;
    670      1.1  christos }
    671      1.1  christos 
    672      1.1  christos static DWORD WINAPI
    673      1.1  christos file_select_thread (void *arg)
    674      1.1  christos {
    675  1.1.1.4  christos   struct serial *scb = (struct serial *) arg;
    676      1.1  christos   struct ser_console_state *state;
    677      1.1  christos   HANDLE h;
    678      1.1  christos 
    679  1.1.1.4  christos   state = (struct ser_console_state *) scb->state;
    680      1.1  christos   h = (HANDLE) _get_osfhandle (scb->fd);
    681      1.1  christos 
    682      1.1  christos   while (1)
    683      1.1  christos     {
    684      1.1  christos       select_thread_wait (state);
    685      1.1  christos 
    686      1.1  christos       if (SetFilePointer (h, 0, NULL, FILE_CURRENT)
    687      1.1  christos 	  == INVALID_SET_FILE_POINTER)
    688      1.1  christos 	SetEvent (state->except_event);
    689      1.1  christos       else
    690      1.1  christos 	SetEvent (state->read_event);
    691      1.1  christos 
    692      1.1  christos       SetEvent (state->have_stopped);
    693      1.1  christos     }
    694      1.1  christos   return 0;
    695      1.1  christos }
    696      1.1  christos 
    697      1.1  christos static void
    698      1.1  christos ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
    699      1.1  christos {
    700  1.1.1.4  christos   struct ser_console_state *state = (struct ser_console_state *) scb->state;
    701      1.1  christos 
    702      1.1  christos   if (state == NULL)
    703      1.1  christos     {
    704      1.1  christos       thread_fn_type thread_fn;
    705      1.1  christos       int is_tty;
    706      1.1  christos 
    707      1.1  christos       is_tty = isatty (scb->fd);
    708      1.1  christos       if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd))
    709      1.1  christos 	{
    710      1.1  christos 	  *read = NULL;
    711      1.1  christos 	  *except = NULL;
    712      1.1  christos 	  return;
    713      1.1  christos 	}
    714      1.1  christos 
    715  1.1.1.4  christos       state = XCNEW (struct ser_console_state);
    716      1.1  christos       scb->state = state;
    717      1.1  christos 
    718      1.1  christos       if (is_tty)
    719      1.1  christos 	thread_fn = console_select_thread;
    720      1.1  christos       else if (fd_is_pipe (scb->fd))
    721      1.1  christos 	thread_fn = pipe_select_thread;
    722      1.1  christos       else
    723      1.1  christos 	thread_fn = file_select_thread;
    724      1.1  christos 
    725      1.1  christos       create_select_thread (thread_fn, scb, state);
    726      1.1  christos     }
    727      1.1  christos 
    728      1.1  christos   *read = state->read_event;
    729      1.1  christos   *except = state->except_event;
    730      1.1  christos 
    731      1.1  christos   /* Start from a blank state.  */
    732      1.1  christos   ResetEvent (state->read_event);
    733      1.1  christos   ResetEvent (state->except_event);
    734      1.1  christos   ResetEvent (state->stop_select);
    735      1.1  christos 
    736      1.1  christos   /* First check for a key already in the buffer.  If there is one,
    737      1.1  christos      we don't need a thread.  This also catches the second key of
    738      1.1  christos      multi-character returns from getch, for instance for arrow
    739      1.1  christos      keys.  The second half is in a C library internal buffer,
    740      1.1  christos      and PeekConsoleInput will not find it.  */
    741      1.1  christos   if (_kbhit ())
    742      1.1  christos     {
    743      1.1  christos       SetEvent (state->read_event);
    744      1.1  christos       return;
    745      1.1  christos     }
    746      1.1  christos 
    747      1.1  christos   /* Otherwise, start the select thread.  */
    748      1.1  christos   start_select_thread (state);
    749      1.1  christos }
    750      1.1  christos 
    751      1.1  christos static void
    752      1.1  christos ser_console_done_wait_handle (struct serial *scb)
    753      1.1  christos {
    754  1.1.1.4  christos   struct ser_console_state *state = (struct ser_console_state *) scb->state;
    755      1.1  christos 
    756      1.1  christos   if (state == NULL)
    757      1.1  christos     return;
    758      1.1  christos 
    759      1.1  christos   stop_select_thread (state);
    760      1.1  christos }
    761      1.1  christos 
    762      1.1  christos static void
    763      1.1  christos ser_console_close (struct serial *scb)
    764      1.1  christos {
    765  1.1.1.4  christos   struct ser_console_state *state = (struct ser_console_state *) scb->state;
    766      1.1  christos 
    767      1.1  christos   if (scb->state)
    768      1.1  christos     {
    769      1.1  christos       destroy_select_thread (state);
    770      1.1  christos       xfree (scb->state);
    771      1.1  christos     }
    772      1.1  christos }
    773      1.1  christos 
    774      1.1  christos struct ser_console_ttystate
    775      1.1  christos {
    776      1.1  christos   int is_a_tty;
    777      1.1  christos };
    778      1.1  christos 
    779      1.1  christos static serial_ttystate
    780      1.1  christos ser_console_get_tty_state (struct serial *scb)
    781      1.1  christos {
    782      1.1  christos   if (isatty (scb->fd))
    783      1.1  christos     {
    784      1.1  christos       struct ser_console_ttystate *state;
    785      1.1  christos 
    786  1.1.1.4  christos       state = XNEW (struct ser_console_ttystate);
    787      1.1  christos       state->is_a_tty = 1;
    788      1.1  christos       return state;
    789      1.1  christos     }
    790      1.1  christos   else
    791      1.1  christos     return NULL;
    792      1.1  christos }
    793      1.1  christos 
    794      1.1  christos struct pipe_state
    795      1.1  christos {
    796      1.1  christos   /* Since we use the pipe_select_thread for our select emulation,
    797      1.1  christos      we need to place the state structure it requires at the front
    798      1.1  christos      of our state.  */
    799      1.1  christos   struct ser_console_state wait;
    800      1.1  christos 
    801      1.1  christos   /* The pex obj for our (one-stage) pipeline.  */
    802      1.1  christos   struct pex_obj *pex;
    803      1.1  christos 
    804      1.1  christos   /* Streams for the pipeline's input and output.  */
    805      1.1  christos   FILE *input, *output;
    806      1.1  christos };
    807      1.1  christos 
    808      1.1  christos static struct pipe_state *
    809      1.1  christos make_pipe_state (void)
    810      1.1  christos {
    811  1.1.1.4  christos   struct pipe_state *ps = XCNEW (struct pipe_state);
    812      1.1  christos 
    813      1.1  christos   ps->wait.read_event = INVALID_HANDLE_VALUE;
    814      1.1  christos   ps->wait.except_event = INVALID_HANDLE_VALUE;
    815      1.1  christos   ps->wait.start_select = INVALID_HANDLE_VALUE;
    816      1.1  christos   ps->wait.stop_select = INVALID_HANDLE_VALUE;
    817      1.1  christos 
    818      1.1  christos   return ps;
    819      1.1  christos }
    820      1.1  christos 
    821      1.1  christos static void
    822      1.1  christos free_pipe_state (struct pipe_state *ps)
    823      1.1  christos {
    824      1.1  christos   int saved_errno = errno;
    825      1.1  christos 
    826      1.1  christos   if (ps->wait.read_event != INVALID_HANDLE_VALUE)
    827      1.1  christos     destroy_select_thread (&ps->wait);
    828      1.1  christos 
    829      1.1  christos   /* Close the pipe to the child.  We must close the pipe before
    830      1.1  christos      calling pex_free because pex_free will wait for the child to exit
    831      1.1  christos      and the child will not exit until the pipe is closed.  */
    832      1.1  christos   if (ps->input)
    833      1.1  christos     fclose (ps->input);
    834      1.1  christos   if (ps->pex)
    835      1.1  christos     {
    836      1.1  christos       pex_free (ps->pex);
    837      1.1  christos       /* pex_free closes ps->output.  */
    838      1.1  christos     }
    839      1.1  christos   else if (ps->output)
    840      1.1  christos     fclose (ps->output);
    841      1.1  christos 
    842      1.1  christos   xfree (ps);
    843      1.1  christos 
    844      1.1  christos   errno = saved_errno;
    845      1.1  christos }
    846      1.1  christos 
    847  1.1.1.6  christos struct pipe_state_destroyer
    848      1.1  christos {
    849  1.1.1.6  christos   void operator() (pipe_state *ps) const
    850  1.1.1.6  christos   {
    851  1.1.1.6  christos     free_pipe_state (ps);
    852  1.1.1.6  christos   }
    853  1.1.1.6  christos };
    854      1.1  christos 
    855  1.1.1.6  christos typedef std::unique_ptr<pipe_state, pipe_state_destroyer> pipe_state_up;
    856      1.1  christos 
    857      1.1  christos static int
    858      1.1  christos pipe_windows_open (struct serial *scb, const char *name)
    859      1.1  christos {
    860      1.1  christos   FILE *pex_stderr;
    861      1.1  christos 
    862      1.1  christos   if (name == NULL)
    863      1.1  christos     error_no_arg (_("child command"));
    864      1.1  christos 
    865  1.1.1.6  christos   gdb_argv argv (name);
    866      1.1  christos 
    867      1.1  christos   if (! argv[0] || argv[0][0] == '\0')
    868      1.1  christos     error (_("missing child command"));
    869      1.1  christos 
    870  1.1.1.6  christos   pipe_state_up ps (make_pipe_state ());
    871      1.1  christos 
    872      1.1  christos   ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
    873      1.1  christos   if (! ps->pex)
    874  1.1.1.6  christos     return -1;
    875      1.1  christos   ps->input = pex_input_pipe (ps->pex, 1);
    876      1.1  christos   if (! ps->input)
    877  1.1.1.6  christos     return -1;
    878      1.1  christos 
    879      1.1  christos   {
    880      1.1  christos     int err;
    881      1.1  christos     const char *err_msg
    882      1.1  christos       = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
    883      1.1  christos 		 | PEX_STDERR_TO_PIPE,
    884  1.1.1.6  christos                  argv[0], argv.get (), NULL, NULL,
    885      1.1  christos                  &err);
    886      1.1  christos 
    887      1.1  christos     if (err_msg)
    888      1.1  christos       {
    889      1.1  christos         /* Our caller expects us to return -1, but all they'll do with
    890      1.1  christos            it generally is print the message based on errno.  We have
    891      1.1  christos            all the same information here, plus err_msg provided by
    892      1.1  christos            pex_run, so we just raise the error here.  */
    893      1.1  christos         if (err)
    894      1.1  christos           error (_("error starting child process '%s': %s: %s"),
    895      1.1  christos                  name, err_msg, safe_strerror (err));
    896      1.1  christos         else
    897      1.1  christos           error (_("error starting child process '%s': %s"),
    898      1.1  christos                  name, err_msg);
    899      1.1  christos       }
    900      1.1  christos   }
    901      1.1  christos 
    902      1.1  christos   ps->output = pex_read_output (ps->pex, 1);
    903      1.1  christos   if (! ps->output)
    904  1.1.1.6  christos     return -1;
    905      1.1  christos   scb->fd = fileno (ps->output);
    906      1.1  christos 
    907      1.1  christos   pex_stderr = pex_read_err (ps->pex, 1);
    908      1.1  christos   if (! pex_stderr)
    909  1.1.1.6  christos     return -1;
    910      1.1  christos   scb->error_fd = fileno (pex_stderr);
    911      1.1  christos 
    912  1.1.1.6  christos   scb->state = ps.release ();
    913      1.1  christos 
    914      1.1  christos   return 0;
    915      1.1  christos }
    916      1.1  christos 
    917      1.1  christos static int
    918      1.1  christos pipe_windows_fdopen (struct serial *scb, int fd)
    919      1.1  christos {
    920      1.1  christos   struct pipe_state *ps;
    921      1.1  christos 
    922      1.1  christos   ps = make_pipe_state ();
    923      1.1  christos 
    924      1.1  christos   ps->input = fdopen (fd, "r+");
    925      1.1  christos   if (! ps->input)
    926      1.1  christos     goto fail;
    927      1.1  christos 
    928      1.1  christos   ps->output = fdopen (fd, "r+");
    929      1.1  christos   if (! ps->output)
    930      1.1  christos     goto fail;
    931      1.1  christos 
    932      1.1  christos   scb->fd = fd;
    933      1.1  christos   scb->state = (void *) ps;
    934      1.1  christos 
    935      1.1  christos   return 0;
    936      1.1  christos 
    937      1.1  christos  fail:
    938      1.1  christos   free_pipe_state (ps);
    939      1.1  christos   return -1;
    940      1.1  christos }
    941      1.1  christos 
    942      1.1  christos static void
    943      1.1  christos pipe_windows_close (struct serial *scb)
    944      1.1  christos {
    945  1.1.1.4  christos   struct pipe_state *ps = (struct pipe_state *) scb->state;
    946      1.1  christos 
    947      1.1  christos   /* In theory, we should try to kill the subprocess here, but the pex
    948      1.1  christos      interface doesn't give us enough information to do that.  Usually
    949      1.1  christos      closing the input pipe will get the message across.  */
    950      1.1  christos 
    951      1.1  christos   free_pipe_state (ps);
    952      1.1  christos }
    953      1.1  christos 
    954      1.1  christos 
    955      1.1  christos static int
    956      1.1  christos pipe_windows_read (struct serial *scb, size_t count)
    957      1.1  christos {
    958      1.1  christos   HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
    959      1.1  christos   DWORD available;
    960      1.1  christos   DWORD bytes_read;
    961      1.1  christos 
    962      1.1  christos   if (pipeline_out == INVALID_HANDLE_VALUE)
    963      1.1  christos     return -1;
    964      1.1  christos 
    965      1.1  christos   if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
    966      1.1  christos     return -1;
    967      1.1  christos 
    968      1.1  christos   if (count > available)
    969      1.1  christos     count = available;
    970      1.1  christos 
    971      1.1  christos   if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
    972      1.1  christos     return -1;
    973      1.1  christos 
    974      1.1  christos   return bytes_read;
    975      1.1  christos }
    976      1.1  christos 
    977      1.1  christos 
    978      1.1  christos static int
    979      1.1  christos pipe_windows_write (struct serial *scb, const void *buf, size_t count)
    980      1.1  christos {
    981  1.1.1.4  christos   struct pipe_state *ps = (struct pipe_state *) scb->state;
    982      1.1  christos   HANDLE pipeline_in;
    983      1.1  christos   DWORD written;
    984      1.1  christos 
    985      1.1  christos   int pipeline_in_fd = fileno (ps->input);
    986      1.1  christos   if (pipeline_in_fd < 0)
    987      1.1  christos     return -1;
    988      1.1  christos 
    989      1.1  christos   pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
    990      1.1  christos   if (pipeline_in == INVALID_HANDLE_VALUE)
    991      1.1  christos     return -1;
    992      1.1  christos 
    993      1.1  christos   if (! WriteFile (pipeline_in, buf, count, &written, NULL))
    994      1.1  christos     return -1;
    995      1.1  christos 
    996      1.1  christos   return written;
    997      1.1  christos }
    998      1.1  christos 
    999      1.1  christos 
   1000      1.1  christos static void
   1001      1.1  christos pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
   1002      1.1  christos {
   1003  1.1.1.4  christos   struct pipe_state *ps = (struct pipe_state *) scb->state;
   1004      1.1  christos 
   1005      1.1  christos   /* Have we allocated our events yet?  */
   1006      1.1  christos   if (ps->wait.read_event == INVALID_HANDLE_VALUE)
   1007      1.1  christos     /* Start the thread.  */
   1008      1.1  christos     create_select_thread (pipe_select_thread, scb, &ps->wait);
   1009      1.1  christos 
   1010      1.1  christos   *read = ps->wait.read_event;
   1011      1.1  christos   *except = ps->wait.except_event;
   1012      1.1  christos 
   1013      1.1  christos   /* Start from a blank state.  */
   1014      1.1  christos   ResetEvent (ps->wait.read_event);
   1015      1.1  christos   ResetEvent (ps->wait.except_event);
   1016      1.1  christos   ResetEvent (ps->wait.stop_select);
   1017      1.1  christos 
   1018      1.1  christos   start_select_thread (&ps->wait);
   1019      1.1  christos }
   1020      1.1  christos 
   1021      1.1  christos static void
   1022      1.1  christos pipe_done_wait_handle (struct serial *scb)
   1023      1.1  christos {
   1024  1.1.1.4  christos   struct pipe_state *ps = (struct pipe_state *) scb->state;
   1025      1.1  christos 
   1026      1.1  christos   /* Have we allocated our events yet?  */
   1027      1.1  christos   if (ps->wait.read_event == INVALID_HANDLE_VALUE)
   1028      1.1  christos     return;
   1029      1.1  christos 
   1030      1.1  christos   stop_select_thread (&ps->wait);
   1031      1.1  christos }
   1032      1.1  christos 
   1033      1.1  christos static int
   1034      1.1  christos pipe_avail (struct serial *scb, int fd)
   1035      1.1  christos {
   1036      1.1  christos   HANDLE h = (HANDLE) _get_osfhandle (fd);
   1037      1.1  christos   DWORD numBytes;
   1038      1.1  christos   BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);
   1039      1.1  christos 
   1040      1.1  christos   if (r == FALSE)
   1041      1.1  christos     numBytes = 0;
   1042      1.1  christos   return numBytes;
   1043      1.1  christos }
   1044      1.1  christos 
   1045      1.1  christos int
   1046      1.1  christos gdb_pipe (int pdes[2])
   1047      1.1  christos {
   1048      1.1  christos   if (_pipe (pdes, 512, _O_BINARY | _O_NOINHERIT) == -1)
   1049      1.1  christos     return -1;
   1050      1.1  christos   return 0;
   1051      1.1  christos }
   1052      1.1  christos 
   1053      1.1  christos struct net_windows_state
   1054      1.1  christos {
   1055      1.1  christos   struct ser_console_state base;
   1056      1.1  christos 
   1057      1.1  christos   HANDLE sock_event;
   1058      1.1  christos };
   1059      1.1  christos 
   1060  1.1.1.2  christos /* Check whether the socket has any pending data to be read.  If so,
   1061  1.1.1.2  christos    set the select thread's read event.  On error, set the select
   1062  1.1.1.2  christos    thread's except event.  If any event was set, return true,
   1063  1.1.1.2  christos    otherwise return false.  */
   1064  1.1.1.2  christos 
   1065  1.1.1.2  christos static int
   1066  1.1.1.2  christos net_windows_socket_check_pending (struct serial *scb)
   1067  1.1.1.2  christos {
   1068  1.1.1.4  christos   struct net_windows_state *state = (struct net_windows_state *) scb->state;
   1069  1.1.1.2  christos   unsigned long available;
   1070  1.1.1.2  christos 
   1071  1.1.1.2  christos   if (ioctlsocket (scb->fd, FIONREAD, &available) != 0)
   1072  1.1.1.2  christos     {
   1073  1.1.1.2  christos       /* The socket closed, or some other error.  */
   1074  1.1.1.2  christos       SetEvent (state->base.except_event);
   1075  1.1.1.2  christos       return 1;
   1076  1.1.1.2  christos     }
   1077  1.1.1.2  christos   else if (available > 0)
   1078  1.1.1.2  christos     {
   1079  1.1.1.2  christos       SetEvent (state->base.read_event);
   1080  1.1.1.2  christos       return 1;
   1081  1.1.1.2  christos     }
   1082  1.1.1.2  christos 
   1083  1.1.1.2  christos   return 0;
   1084  1.1.1.2  christos }
   1085  1.1.1.2  christos 
   1086      1.1  christos static DWORD WINAPI
   1087      1.1  christos net_windows_select_thread (void *arg)
   1088      1.1  christos {
   1089  1.1.1.4  christos   struct serial *scb = (struct serial *) arg;
   1090      1.1  christos   struct net_windows_state *state;
   1091      1.1  christos   int event_index;
   1092      1.1  christos 
   1093  1.1.1.4  christos   state = (struct net_windows_state *) scb->state;
   1094      1.1  christos 
   1095      1.1  christos   while (1)
   1096      1.1  christos     {
   1097      1.1  christos       HANDLE wait_events[2];
   1098      1.1  christos       WSANETWORKEVENTS events;
   1099      1.1  christos 
   1100      1.1  christos       select_thread_wait (&state->base);
   1101      1.1  christos 
   1102      1.1  christos       wait_events[0] = state->base.stop_select;
   1103      1.1  christos       wait_events[1] = state->sock_event;
   1104      1.1  christos 
   1105  1.1.1.2  christos       /* Wait for something to happen on the socket.  */
   1106  1.1.1.2  christos       while (1)
   1107      1.1  christos 	{
   1108  1.1.1.2  christos 	  event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
   1109  1.1.1.2  christos 
   1110  1.1.1.2  christos 	  if (event_index == WAIT_OBJECT_0
   1111  1.1.1.2  christos 	      || WaitForSingleObject (state->base.stop_select, 0) == WAIT_OBJECT_0)
   1112  1.1.1.2  christos 	    {
   1113  1.1.1.2  christos 	      /* We have been requested to stop.  */
   1114  1.1.1.2  christos 	      break;
   1115  1.1.1.2  christos 	    }
   1116  1.1.1.2  christos 
   1117  1.1.1.2  christos 	  if (event_index != WAIT_OBJECT_0 + 1)
   1118  1.1.1.2  christos 	    {
   1119  1.1.1.2  christos 	      /* Some error has occured.  Assume that this is an error
   1120  1.1.1.2  christos 		 condition.  */
   1121  1.1.1.2  christos 	      SetEvent (state->base.except_event);
   1122  1.1.1.2  christos 	      break;
   1123  1.1.1.2  christos 	    }
   1124  1.1.1.2  christos 
   1125      1.1  christos 	  /* Enumerate the internal network events, and reset the
   1126      1.1  christos 	     object that signalled us to catch the next event.  */
   1127  1.1.1.2  christos 	  if (WSAEnumNetworkEvents (scb->fd, state->sock_event, &events) != 0)
   1128  1.1.1.2  christos 	    {
   1129  1.1.1.2  christos 	      /* Something went wrong.  Maybe the socket is gone.  */
   1130  1.1.1.2  christos 	      SetEvent (state->base.except_event);
   1131  1.1.1.2  christos 	      break;
   1132  1.1.1.2  christos 	    }
   1133  1.1.1.2  christos 
   1134      1.1  christos 	  if (events.lNetworkEvents & FD_READ)
   1135  1.1.1.2  christos 	    {
   1136  1.1.1.2  christos 	      if (net_windows_socket_check_pending (scb))
   1137  1.1.1.2  christos 		break;
   1138  1.1.1.2  christos 
   1139  1.1.1.2  christos 	      /* Spurious wakeup.  That is, the socket's event was
   1140  1.1.1.2  christos 		 signalled before we last called recv.  */
   1141  1.1.1.2  christos 	    }
   1142  1.1.1.2  christos 
   1143      1.1  christos 	  if (events.lNetworkEvents & FD_CLOSE)
   1144  1.1.1.2  christos 	    {
   1145  1.1.1.2  christos 	      SetEvent (state->base.except_event);
   1146  1.1.1.2  christos 	      break;
   1147  1.1.1.2  christos 	    }
   1148      1.1  christos 	}
   1149      1.1  christos 
   1150      1.1  christos       SetEvent (state->base.have_stopped);
   1151      1.1  christos     }
   1152  1.1.1.2  christos   return 0;
   1153      1.1  christos }
   1154      1.1  christos 
   1155      1.1  christos static void
   1156      1.1  christos net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
   1157      1.1  christos {
   1158  1.1.1.4  christos   struct net_windows_state *state = (struct net_windows_state *) scb->state;
   1159      1.1  christos 
   1160      1.1  christos   /* Start from a clean slate.  */
   1161      1.1  christos   ResetEvent (state->base.read_event);
   1162      1.1  christos   ResetEvent (state->base.except_event);
   1163      1.1  christos   ResetEvent (state->base.stop_select);
   1164      1.1  christos 
   1165      1.1  christos   *read = state->base.read_event;
   1166      1.1  christos   *except = state->base.except_event;
   1167      1.1  christos 
   1168  1.1.1.2  christos   /* Check any pending events.  Otherwise, start the select
   1169  1.1.1.2  christos      thread.  */
   1170  1.1.1.2  christos   if (!net_windows_socket_check_pending (scb))
   1171  1.1.1.2  christos     start_select_thread (&state->base);
   1172      1.1  christos }
   1173      1.1  christos 
   1174      1.1  christos static void
   1175      1.1  christos net_windows_done_wait_handle (struct serial *scb)
   1176      1.1  christos {
   1177  1.1.1.4  christos   struct net_windows_state *state = (struct net_windows_state *) scb->state;
   1178      1.1  christos 
   1179      1.1  christos   stop_select_thread (&state->base);
   1180      1.1  christos }
   1181      1.1  christos 
   1182      1.1  christos static int
   1183      1.1  christos net_windows_open (struct serial *scb, const char *name)
   1184      1.1  christos {
   1185      1.1  christos   struct net_windows_state *state;
   1186      1.1  christos   int ret;
   1187      1.1  christos 
   1188      1.1  christos   ret = net_open (scb, name);
   1189      1.1  christos   if (ret != 0)
   1190      1.1  christos     return ret;
   1191      1.1  christos 
   1192  1.1.1.4  christos   state = XCNEW (struct net_windows_state);
   1193      1.1  christos   scb->state = state;
   1194      1.1  christos 
   1195      1.1  christos   /* Associate an event with the socket.  */
   1196      1.1  christos   state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
   1197      1.1  christos   WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
   1198      1.1  christos 
   1199      1.1  christos   /* Start the thread.  */
   1200      1.1  christos   create_select_thread (net_windows_select_thread, scb, &state->base);
   1201      1.1  christos 
   1202      1.1  christos   return 0;
   1203      1.1  christos }
   1204      1.1  christos 
   1205      1.1  christos 
   1206      1.1  christos static void
   1207      1.1  christos net_windows_close (struct serial *scb)
   1208      1.1  christos {
   1209  1.1.1.4  christos   struct net_windows_state *state = (struct net_windows_state *) scb->state;
   1210      1.1  christos 
   1211      1.1  christos   destroy_select_thread (&state->base);
   1212      1.1  christos   CloseHandle (state->sock_event);
   1213      1.1  christos 
   1214      1.1  christos   xfree (scb->state);
   1215      1.1  christos 
   1216      1.1  christos   net_close (scb);
   1217      1.1  christos }
   1218      1.1  christos 
   1219      1.1  christos /* The serial port driver.  */
   1220      1.1  christos 
   1221      1.1  christos static const struct serial_ops hardwire_ops =
   1222      1.1  christos {
   1223      1.1  christos   "hardwire",
   1224      1.1  christos   ser_windows_open,
   1225      1.1  christos   ser_windows_close,
   1226      1.1  christos   NULL,
   1227      1.1  christos   ser_base_readchar,
   1228      1.1  christos   ser_base_write,
   1229      1.1  christos   ser_windows_flush_output,
   1230      1.1  christos   ser_windows_flush_input,
   1231      1.1  christos   ser_windows_send_break,
   1232      1.1  christos   ser_windows_raw,
   1233      1.1  christos   /* These are only used for stdin; we do not need them for serial
   1234      1.1  christos      ports, so supply the standard dummies.  */
   1235      1.1  christos   ser_base_get_tty_state,
   1236      1.1  christos   ser_base_copy_tty_state,
   1237      1.1  christos   ser_base_set_tty_state,
   1238      1.1  christos   ser_base_print_tty_state,
   1239      1.1  christos   ser_windows_setbaudrate,
   1240      1.1  christos   ser_windows_setstopbits,
   1241  1.1.1.3  christos   ser_windows_setparity,
   1242      1.1  christos   ser_windows_drain_output,
   1243      1.1  christos   ser_base_async,
   1244      1.1  christos   ser_windows_read_prim,
   1245      1.1  christos   ser_windows_write_prim,
   1246      1.1  christos   NULL,
   1247      1.1  christos   ser_windows_wait_handle
   1248      1.1  christos };
   1249      1.1  christos 
   1250      1.1  christos /* The dummy serial driver used for terminals.  We only provide the
   1251      1.1  christos    TTY-related methods.  */
   1252      1.1  christos 
   1253      1.1  christos static const struct serial_ops tty_ops =
   1254      1.1  christos {
   1255      1.1  christos   "terminal",
   1256      1.1  christos   NULL,
   1257      1.1  christos   ser_console_close,
   1258      1.1  christos   NULL,
   1259      1.1  christos   NULL,
   1260      1.1  christos   NULL,
   1261      1.1  christos   NULL,
   1262      1.1  christos   NULL,
   1263      1.1  christos   NULL,
   1264      1.1  christos   NULL,
   1265      1.1  christos   ser_console_get_tty_state,
   1266      1.1  christos   ser_base_copy_tty_state,
   1267      1.1  christos   ser_base_set_tty_state,
   1268      1.1  christos   ser_base_print_tty_state,
   1269      1.1  christos   NULL,
   1270      1.1  christos   NULL,
   1271  1.1.1.3  christos   NULL,
   1272      1.1  christos   ser_base_drain_output,
   1273      1.1  christos   NULL,
   1274      1.1  christos   NULL,
   1275      1.1  christos   NULL,
   1276      1.1  christos   NULL,
   1277      1.1  christos   ser_console_wait_handle,
   1278      1.1  christos   ser_console_done_wait_handle
   1279      1.1  christos };
   1280      1.1  christos 
   1281      1.1  christos /* The pipe interface.  */
   1282      1.1  christos 
   1283      1.1  christos static const struct serial_ops pipe_ops =
   1284      1.1  christos {
   1285      1.1  christos   "pipe",
   1286      1.1  christos   pipe_windows_open,
   1287      1.1  christos   pipe_windows_close,
   1288      1.1  christos   pipe_windows_fdopen,
   1289      1.1  christos   ser_base_readchar,
   1290      1.1  christos   ser_base_write,
   1291      1.1  christos   ser_base_flush_output,
   1292      1.1  christos   ser_base_flush_input,
   1293      1.1  christos   ser_base_send_break,
   1294      1.1  christos   ser_base_raw,
   1295      1.1  christos   ser_base_get_tty_state,
   1296      1.1  christos   ser_base_copy_tty_state,
   1297      1.1  christos   ser_base_set_tty_state,
   1298      1.1  christos   ser_base_print_tty_state,
   1299      1.1  christos   ser_base_setbaudrate,
   1300      1.1  christos   ser_base_setstopbits,
   1301  1.1.1.3  christos   ser_base_setparity,
   1302      1.1  christos   ser_base_drain_output,
   1303      1.1  christos   ser_base_async,
   1304      1.1  christos   pipe_windows_read,
   1305      1.1  christos   pipe_windows_write,
   1306      1.1  christos   pipe_avail,
   1307      1.1  christos   pipe_wait_handle,
   1308      1.1  christos   pipe_done_wait_handle
   1309      1.1  christos };
   1310      1.1  christos 
   1311      1.1  christos /* The TCP/UDP socket driver.  */
   1312      1.1  christos 
   1313      1.1  christos static const struct serial_ops tcp_ops =
   1314      1.1  christos {
   1315      1.1  christos   "tcp",
   1316      1.1  christos   net_windows_open,
   1317      1.1  christos   net_windows_close,
   1318      1.1  christos   NULL,
   1319      1.1  christos   ser_base_readchar,
   1320      1.1  christos   ser_base_write,
   1321      1.1  christos   ser_base_flush_output,
   1322      1.1  christos   ser_base_flush_input,
   1323      1.1  christos   ser_tcp_send_break,
   1324      1.1  christos   ser_base_raw,
   1325      1.1  christos   ser_base_get_tty_state,
   1326      1.1  christos   ser_base_copy_tty_state,
   1327      1.1  christos   ser_base_set_tty_state,
   1328      1.1  christos   ser_base_print_tty_state,
   1329      1.1  christos   ser_base_setbaudrate,
   1330      1.1  christos   ser_base_setstopbits,
   1331  1.1.1.3  christos   ser_base_setparity,
   1332      1.1  christos   ser_base_drain_output,
   1333      1.1  christos   ser_base_async,
   1334      1.1  christos   net_read_prim,
   1335      1.1  christos   net_write_prim,
   1336      1.1  christos   NULL,
   1337      1.1  christos   net_windows_wait_handle,
   1338      1.1  christos   net_windows_done_wait_handle
   1339      1.1  christos };
   1340      1.1  christos 
   1341  1.1.1.7  christos void _initialize_ser_windows ();
   1342      1.1  christos void
   1343  1.1.1.7  christos _initialize_ser_windows ()
   1344      1.1  christos {
   1345      1.1  christos   WSADATA wsa_data;
   1346      1.1  christos 
   1347      1.1  christos   HMODULE hm = NULL;
   1348      1.1  christos 
   1349      1.1  christos   /* First find out if kernel32 exports CancelIo function.  */
   1350      1.1  christos   hm = LoadLibrary ("kernel32.dll");
   1351      1.1  christos   if (hm)
   1352      1.1  christos     {
   1353  1.1.1.4  christos       CancelIo = (CancelIo_ftype *) GetProcAddress (hm, "CancelIo");
   1354      1.1  christos       FreeLibrary (hm);
   1355      1.1  christos     }
   1356      1.1  christos   else
   1357      1.1  christos     CancelIo = NULL;
   1358      1.1  christos 
   1359      1.1  christos   serial_add_interface (&hardwire_ops);
   1360      1.1  christos   serial_add_interface (&tty_ops);
   1361      1.1  christos   serial_add_interface (&pipe_ops);
   1362      1.1  christos 
   1363      1.1  christos   /* If WinSock works, register the TCP/UDP socket driver.  */
   1364      1.1  christos 
   1365      1.1  christos   if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
   1366      1.1  christos     /* WinSock is unavailable.  */
   1367      1.1  christos     return;
   1368      1.1  christos 
   1369      1.1  christos   serial_add_interface (&tcp_ops);
   1370      1.1  christos }
   1371