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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [ser-mingw.c] - Blame information for rev 309

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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