OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [ser-mingw.c] - Blame information for rev 840

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.