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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 330 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
 
755
      state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
756
      state->is_a_tty = 1;
757
      return state;
758
    }
759
  else
760
    return NULL;
761
}
762
 
763
struct pipe_state
764
{
765
  /* Since we use the pipe_select_thread for our select emulation,
766
     we need to place the state structure it requires at the front
767
     of our state.  */
768
  struct ser_console_state wait;
769
 
770
  /* The pex obj for our (one-stage) pipeline.  */
771
  struct pex_obj *pex;
772
 
773
  /* Streams for the pipeline's input and output.  */
774
  FILE *input, *output;
775
};
776
 
777
static struct pipe_state *
778
make_pipe_state (void)
779
{
780
  struct pipe_state *ps = XMALLOC (struct pipe_state);
781
 
782
  memset (ps, 0, sizeof (*ps));
783
  ps->wait.read_event = INVALID_HANDLE_VALUE;
784
  ps->wait.except_event = INVALID_HANDLE_VALUE;
785
  ps->wait.start_select = INVALID_HANDLE_VALUE;
786
  ps->wait.stop_select = INVALID_HANDLE_VALUE;
787
 
788
  return ps;
789
}
790
 
791
static void
792
free_pipe_state (struct pipe_state *ps)
793
{
794
  int saved_errno = errno;
795
 
796
  if (ps->wait.read_event != INVALID_HANDLE_VALUE)
797
    destroy_select_thread (&ps->wait);
798
 
799
  /* Close the pipe to the child.  We must close the pipe before
800
     calling pex_free because pex_free will wait for the child to exit
801
     and the child will not exit until the pipe is closed.  */
802
  if (ps->input)
803
    fclose (ps->input);
804
  if (ps->pex)
805
    pex_free (ps->pex);
806
  /* pex_free closes ps->output.  */
807
 
808
  xfree (ps);
809
 
810
  errno = saved_errno;
811
}
812
 
813
static void
814
cleanup_pipe_state (void *untyped)
815
{
816
  struct pipe_state *ps = untyped;
817
 
818
  free_pipe_state (ps);
819
}
820
 
821
static int
822
pipe_windows_open (struct serial *scb, const char *name)
823
{
824
  struct pipe_state *ps;
825
  FILE *pex_stderr;
826
  char **argv;
827
  struct cleanup *back_to;
828
 
829
  if (name == NULL)
830
    error_no_arg (_("child command"));
831
 
832
  argv = gdb_buildargv (name);
833
  back_to = make_cleanup_freeargv (argv);
834
 
835
  if (! argv[0] || argv[0][0] == '\0')
836
    error ("missing child command");
837
 
838
  ps = make_pipe_state ();
839
  make_cleanup (cleanup_pipe_state, ps);
840
 
841
  ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
842
  if (! ps->pex)
843
    goto fail;
844
  ps->input = pex_input_pipe (ps->pex, 1);
845
  if (! ps->input)
846
    goto fail;
847
 
848
  {
849
    int err;
850
    const char *err_msg
851
      = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
852
                 | PEX_STDERR_TO_PIPE,
853
                 argv[0], argv, NULL, NULL,
854
                 &err);
855
 
856
    if (err_msg)
857
      {
858
        /* Our caller expects us to return -1, but all they'll do with
859
           it generally is print the message based on errno.  We have
860
           all the same information here, plus err_msg provided by
861
           pex_run, so we just raise the error here.  */
862
        if (err)
863
          error ("error starting child process '%s': %s: %s",
864
                 name, err_msg, safe_strerror (err));
865
        else
866
          error ("error starting child process '%s': %s",
867
                 name, err_msg);
868
      }
869
  }
870
 
871
  ps->output = pex_read_output (ps->pex, 1);
872
  if (! ps->output)
873
    goto fail;
874
  scb->fd = fileno (ps->output);
875
 
876
  pex_stderr = pex_read_err (ps->pex, 1);
877
  if (! pex_stderr)
878
    goto fail;
879
  scb->error_fd = fileno (pex_stderr);
880
 
881
  scb->state = (void *) ps;
882
 
883
  discard_cleanups (back_to);
884
  return 0;
885
 
886
 fail:
887
  do_cleanups (back_to);
888
  return -1;
889
}
890
 
891
 
892
static void
893
pipe_windows_close (struct serial *scb)
894
{
895
  struct pipe_state *ps = scb->state;
896
 
897
  /* In theory, we should try to kill the subprocess here, but the pex
898
     interface doesn't give us enough information to do that.  Usually
899
     closing the input pipe will get the message across.  */
900
 
901
  free_pipe_state (ps);
902
}
903
 
904
 
905
static int
906
pipe_windows_read (struct serial *scb, size_t count)
907
{
908
  HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
909
  DWORD available;
910
  DWORD bytes_read;
911
 
912
  if (pipeline_out == INVALID_HANDLE_VALUE)
913
    return -1;
914
 
915
  if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
916
    return -1;
917
 
918
  if (count > available)
919
    count = available;
920
 
921
  if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
922
    return -1;
923
 
924
  return bytes_read;
925
}
926
 
927
 
928
static int
929
pipe_windows_write (struct serial *scb, const void *buf, size_t count)
930
{
931
  struct pipe_state *ps = scb->state;
932
  HANDLE pipeline_in;
933
  DWORD written;
934
 
935
  int pipeline_in_fd = fileno (ps->input);
936
  if (pipeline_in_fd < 0)
937
    return -1;
938
 
939
  pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
940
  if (pipeline_in == INVALID_HANDLE_VALUE)
941
    return -1;
942
 
943
  if (! WriteFile (pipeline_in, buf, count, &written, NULL))
944
    return -1;
945
 
946
  return written;
947
}
948
 
949
 
950
static void
951
pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
952
{
953
  struct pipe_state *ps = scb->state;
954
 
955
  /* Have we allocated our events yet?  */
956
  if (ps->wait.read_event == INVALID_HANDLE_VALUE)
957
    /* Start the thread.  */
958
    create_select_thread (pipe_select_thread, scb, &ps->wait);
959
 
960
  *read = ps->wait.read_event;
961
  *except = ps->wait.except_event;
962
 
963
  /* Start from a blank state.  */
964
  ResetEvent (ps->wait.read_event);
965
  ResetEvent (ps->wait.except_event);
966
  ResetEvent (ps->wait.stop_select);
967
 
968
  start_select_thread (&ps->wait);
969
}
970
 
971
static void
972
pipe_done_wait_handle (struct serial *scb)
973
{
974
  struct pipe_state *ps = scb->state;
975
 
976
  /* Have we allocated our events yet?  */
977
  if (ps->wait.read_event == INVALID_HANDLE_VALUE)
978
    return;
979
 
980
  stop_select_thread (&ps->wait);
981
}
982
 
983
static int
984
pipe_avail (struct serial *scb, int fd)
985
{
986
  HANDLE h = (HANDLE) _get_osfhandle (fd);
987
  DWORD numBytes;
988
  BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);
989
 
990
  if (r == FALSE)
991
    numBytes = 0;
992
  return numBytes;
993
}
994
 
995
struct net_windows_state
996
{
997
  struct ser_console_state base;
998
 
999
  HANDLE sock_event;
1000
};
1001
 
1002
static DWORD WINAPI
1003
net_windows_select_thread (void *arg)
1004
{
1005
  struct serial *scb = arg;
1006
  struct net_windows_state *state;
1007
  int event_index;
1008
 
1009
  state = scb->state;
1010
 
1011
  while (1)
1012
    {
1013
      HANDLE wait_events[2];
1014
      WSANETWORKEVENTS events;
1015
 
1016
      select_thread_wait (&state->base);
1017
 
1018
      wait_events[0] = state->base.stop_select;
1019
      wait_events[1] = state->sock_event;
1020
 
1021
      event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
1022
 
1023
      if (event_index == WAIT_OBJECT_0
1024
          || WaitForSingleObject (state->base.stop_select, 0) == WAIT_OBJECT_0)
1025
        /* We have been requested to stop.  */
1026
        ;
1027
      else if (event_index != WAIT_OBJECT_0 + 1)
1028
        /* Some error has occured.  Assume that this is an error
1029
           condition.  */
1030
        SetEvent (state->base.except_event);
1031
      else
1032
        {
1033
          /* Enumerate the internal network events, and reset the
1034
             object that signalled us to catch the next event.  */
1035
          WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
1036
 
1037
          gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
1038
 
1039
          if (events.lNetworkEvents & FD_READ)
1040
            SetEvent (state->base.read_event);
1041
 
1042
          if (events.lNetworkEvents & FD_CLOSE)
1043
            SetEvent (state->base.except_event);
1044
        }
1045
 
1046
      SetEvent (state->base.have_stopped);
1047
    }
1048
}
1049
 
1050
static void
1051
net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
1052
{
1053
  struct net_windows_state *state = scb->state;
1054
 
1055
  /* Start from a clean slate.  */
1056
  ResetEvent (state->base.read_event);
1057
  ResetEvent (state->base.except_event);
1058
  ResetEvent (state->base.stop_select);
1059
 
1060
  *read = state->base.read_event;
1061
  *except = state->base.except_event;
1062
 
1063
  /* Check any pending events.  This both avoids starting the thread
1064
     unnecessarily, and handles stray FD_READ events (see below).  */
1065
  if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
1066
    {
1067
      WSANETWORKEVENTS events;
1068
      int any = 0;
1069
 
1070
      /* Enumerate the internal network events, and reset the object that
1071
         signalled us to catch the next event.  */
1072
      WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
1073
 
1074
      /* You'd think that FD_READ or FD_CLOSE would be set here.  But,
1075
         sometimes, neither is.  I suspect that the FD_READ is set and
1076
         the corresponding event signalled while recv is running, and
1077
         the FD_READ is then lowered when recv consumes all the data,
1078
         but there's no way to un-signal the event.  This isn't a
1079
         problem for the call in net_select_thread, since any new
1080
         events after this point will not have been drained by recv.
1081
         It just means that we can't have the obvious assert here.  */
1082
 
1083
      /* If there is a read event, it might be still valid, or it might
1084
         not be - it may have been signalled before we last called
1085
         recv.  Double-check that there is data.  */
1086
      if (events.lNetworkEvents & FD_READ)
1087
        {
1088
          unsigned long available;
1089
 
1090
          if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
1091
              && available > 0)
1092
            {
1093
              SetEvent (state->base.read_event);
1094
              any = 1;
1095
            }
1096
          else
1097
            /* Oops, no data.  This call to recv will cause future
1098
               data to retrigger the event, e.g. while we are
1099
               in net_select_thread.  */
1100
            recv (scb->fd, NULL, 0, 0);
1101
        }
1102
 
1103
      /* If there's a close event, then record it - it is obviously
1104
         still valid, and it will not be resignalled.  */
1105
      if (events.lNetworkEvents & FD_CLOSE)
1106
        {
1107
          SetEvent (state->base.except_event);
1108
          any = 1;
1109
        }
1110
 
1111
      /* If we set either handle, there's no need to wake the thread.  */
1112
      if (any)
1113
        return;
1114
    }
1115
 
1116
  start_select_thread (&state->base);
1117
}
1118
 
1119
static void
1120
net_windows_done_wait_handle (struct serial *scb)
1121
{
1122
  struct net_windows_state *state = scb->state;
1123
 
1124
  stop_select_thread (&state->base);
1125
}
1126
 
1127
static int
1128
net_windows_open (struct serial *scb, const char *name)
1129
{
1130
  struct net_windows_state *state;
1131
  int ret;
1132
  DWORD threadId;
1133
 
1134
  ret = net_open (scb, name);
1135
  if (ret != 0)
1136
    return ret;
1137
 
1138
  state = xmalloc (sizeof (struct net_windows_state));
1139
  memset (state, 0, sizeof (struct net_windows_state));
1140
  scb->state = state;
1141
 
1142
  /* Associate an event with the socket.  */
1143
  state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
1144
  WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
1145
 
1146
  /* Start the thread.  */
1147
  create_select_thread (net_windows_select_thread, scb, &state->base);
1148
 
1149
  return 0;
1150
}
1151
 
1152
 
1153
static void
1154
net_windows_close (struct serial *scb)
1155
{
1156
  struct net_windows_state *state = scb->state;
1157
 
1158
  destroy_select_thread (&state->base);
1159
  CloseHandle (state->sock_event);
1160
 
1161
  xfree (scb->state);
1162
 
1163
  net_close (scb);
1164
}
1165
 
1166
void
1167
_initialize_ser_windows (void)
1168
{
1169
  WSADATA wsa_data;
1170
  struct serial_ops *ops;
1171
 
1172
  /* First register the serial port driver.  */
1173
 
1174
  ops = XMALLOC (struct serial_ops);
1175
  memset (ops, 0, sizeof (struct serial_ops));
1176
  ops->name = "hardwire";
1177
  ops->next = 0;
1178
  ops->open = ser_windows_open;
1179
  ops->close = ser_windows_close;
1180
 
1181
  ops->flush_output = ser_windows_flush_output;
1182
  ops->flush_input = ser_windows_flush_input;
1183
  ops->send_break = ser_windows_send_break;
1184
 
1185
  /* These are only used for stdin; we do not need them for serial
1186
     ports, so supply the standard dummies.  */
1187
  ops->get_tty_state = ser_base_get_tty_state;
1188
  ops->set_tty_state = ser_base_set_tty_state;
1189
  ops->print_tty_state = ser_base_print_tty_state;
1190
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1191
 
1192
  ops->go_raw = ser_windows_raw;
1193
  ops->setbaudrate = ser_windows_setbaudrate;
1194
  ops->setstopbits = ser_windows_setstopbits;
1195
  ops->drain_output = ser_windows_drain_output;
1196
  ops->readchar = ser_base_readchar;
1197
  ops->write = ser_base_write;
1198
  ops->async = ser_base_async;
1199
  ops->read_prim = ser_windows_read_prim;
1200
  ops->write_prim = ser_windows_write_prim;
1201
  ops->wait_handle = ser_windows_wait_handle;
1202
 
1203
  serial_add_interface (ops);
1204
 
1205
  /* Next create the dummy serial driver used for terminals.  We only
1206
     provide the TTY-related methods.  */
1207
 
1208
  ops = XMALLOC (struct serial_ops);
1209
  memset (ops, 0, sizeof (struct serial_ops));
1210
 
1211
  ops->name = "terminal";
1212
  ops->next = 0;
1213
 
1214
  ops->close = ser_console_close;
1215
  ops->get_tty_state = ser_console_get_tty_state;
1216
  ops->set_tty_state = ser_base_set_tty_state;
1217
  ops->print_tty_state = ser_base_print_tty_state;
1218
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1219
  ops->drain_output = ser_base_drain_output;
1220
  ops->wait_handle = ser_console_wait_handle;
1221
  ops->done_wait_handle = ser_console_done_wait_handle;
1222
 
1223
  serial_add_interface (ops);
1224
 
1225
  /* The pipe interface.  */
1226
 
1227
  ops = XMALLOC (struct serial_ops);
1228
  memset (ops, 0, sizeof (struct serial_ops));
1229
  ops->name = "pipe";
1230
  ops->next = 0;
1231
  ops->open = pipe_windows_open;
1232
  ops->close = pipe_windows_close;
1233
  ops->readchar = ser_base_readchar;
1234
  ops->write = ser_base_write;
1235
  ops->flush_output = ser_base_flush_output;
1236
  ops->flush_input = ser_base_flush_input;
1237
  ops->send_break = ser_base_send_break;
1238
  ops->go_raw = ser_base_raw;
1239
  ops->get_tty_state = ser_base_get_tty_state;
1240
  ops->set_tty_state = ser_base_set_tty_state;
1241
  ops->print_tty_state = ser_base_print_tty_state;
1242
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1243
  ops->setbaudrate = ser_base_setbaudrate;
1244
  ops->setstopbits = ser_base_setstopbits;
1245
  ops->drain_output = ser_base_drain_output;
1246
  ops->async = ser_base_async;
1247
  ops->read_prim = pipe_windows_read;
1248
  ops->write_prim = pipe_windows_write;
1249
  ops->wait_handle = pipe_wait_handle;
1250
  ops->done_wait_handle = pipe_done_wait_handle;
1251
  ops->avail = pipe_avail;
1252
 
1253
  serial_add_interface (ops);
1254
 
1255
  /* If WinSock works, register the TCP/UDP socket driver.  */
1256
 
1257
  if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
1258
    /* WinSock is unavailable.  */
1259
    return;
1260
 
1261
  ops = XMALLOC (struct serial_ops);
1262
  memset (ops, 0, sizeof (struct serial_ops));
1263
  ops->name = "tcp";
1264
  ops->next = 0;
1265
  ops->open = net_windows_open;
1266
  ops->close = net_windows_close;
1267
  ops->readchar = ser_base_readchar;
1268
  ops->write = ser_base_write;
1269
  ops->flush_output = ser_base_flush_output;
1270
  ops->flush_input = ser_base_flush_input;
1271
  ops->send_break = ser_tcp_send_break;
1272
  ops->go_raw = ser_base_raw;
1273
  ops->get_tty_state = ser_base_get_tty_state;
1274
  ops->set_tty_state = ser_base_set_tty_state;
1275
  ops->print_tty_state = ser_base_print_tty_state;
1276
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1277
  ops->setbaudrate = ser_base_setbaudrate;
1278
  ops->setstopbits = ser_base_setstopbits;
1279
  ops->drain_output = ser_base_drain_output;
1280
  ops->async = ser_base_async;
1281
  ops->read_prim = net_read_prim;
1282
  ops->write_prim = net_write_prim;
1283
  ops->wait_handle = net_windows_wait_handle;
1284
  ops->done_wait_handle = net_windows_done_wait_handle;
1285
  serial_add_interface (ops);
1286
}

powered by: WebSVN 2.1.0

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