GDB (xrefs)
Loading...
Searching...
No Matches
ser-event.c
Go to the documentation of this file.
1/* Serial interface for a selectable event.
2 Copyright (C) 2016-2023 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "defs.h"
20#include "ser-event.h"
21#include "serial.h"
22#include "gdbsupport/filestuff.h"
23
24/* On POSIX hosts, a serial_event is basically an abstraction for the
25 classical self-pipe trick.
26
27 On Windows, a serial_event is a wrapper around a native Windows
28 event object. Because we want to interface with gdb_select, which
29 takes file descriptors, we need to wrap that Windows event object
30 in a file descriptor. As _open_osfhandle can not be used with
31 event objects, we instead create a dummy file wrap that in a file
32 descriptor with _open_osfhandle, and pass that as selectable
33 descriptor to callers. As Windows' gdb_select converts file
34 descriptors back to Windows handles by calling serial->wait_handle,
35 nothing ever actually waits on that file descriptor. */
36
38 {
39#ifdef USE_WIN32API
40 /* The Windows event object, created with CreateEvent. */
41 HANDLE event;
42#else
43 /* The write side of the pipe. The read side is in
44 serial->fd. */
46#endif
47 };
48
49/* Open a new serial event. */
50
51static int
52serial_event_open (struct serial *scb, const char *name)
53{
54 struct serial_event_state *state;
55
56 state = XNEW (struct serial_event_state);
57 scb->state = state;
58
59#ifndef USE_WIN32API
60 {
61 int fds[2];
62
63 if (gdb_pipe_cloexec (fds) == -1)
64 internal_error ("creating serial event pipe failed.");
65
66 fcntl (fds[0], F_SETFL, O_NONBLOCK);
67 fcntl (fds[1], F_SETFL, O_NONBLOCK);
68
69 scb->fd = fds[0];
70 state->write_fd = fds[1];
71 }
72#else
73 {
74 /* A dummy file object that can be wrapped in a file descriptor.
75 We don't need to store this handle because closing the file
76 descriptor automatically closes this. */
77 HANDLE dummy_file;
78
79 /* A manual-reset event. */
80 state->event = CreateEvent (0, TRUE, FALSE, 0);
81
82 /* The dummy file handle. Created just so we have something
83 wrappable in a file descriptor. */
84 dummy_file = CreateFile ("nul", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
85 scb->fd = _open_osfhandle ((intptr_t) dummy_file, 0);
86 }
87#endif
88
89 return 0;
90}
91
92static void
94{
95 struct serial_event_state *state = (struct serial_event_state *) scb->state;
96
97 close (scb->fd);
98#ifndef USE_WIN32API
99 close (state->write_fd);
100#else
101 CloseHandle (state->event);
102#endif
103
104 scb->fd = -1;
105
106 xfree (state);
107 scb->state = NULL;
108}
109
110#ifdef USE_WIN32API
111
112/* Implementation of the wait_handle method. Returns the native
113 Windows event object handle. */
114
115static void
116serial_event_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
117{
118 struct serial_event_state *state = (struct serial_event_state *) scb->state;
119
120 *read = state->event;
121}
122
123#endif
124
125/* The serial_ops for struct serial_event objects. Note we never
126 register this serial type with serial_add_interface, because this
127 is internal implementation detail never to be used by remote
128 targets for protocol transport. */
129
130static const struct serial_ops serial_event_ops =
131{
132 "event",
135 NULL, /* fdopen */
136 NULL, /* readchar */
137 NULL, /* write */
138 NULL, /* flush_output */
139 NULL, /* flush_input */
140 NULL, /* send_break */
141 NULL, /* go_raw */
142 NULL, /* get_tty_state */
143 NULL, /* copy_tty_state */
144 NULL, /* set_tty_state */
145 NULL, /* print_tty_state */
146 NULL, /* setbaudrate */
147 NULL, /* setstopbits */
148 NULL, /* setparity */
149 NULL, /* drain_output */
150 NULL, /* async */
151 NULL, /* read_prim */
152 NULL, /* write_prim */
153 NULL, /* avail */
154#ifdef USE_WIN32API
155 serial_event_wait_handle,
156#endif
157};
158
159/* See ser-event.h. */
160
161struct serial_event *
163{
164 return (struct serial_event *) serial_open_ops (&serial_event_ops);
165}
166
167/* See ser-event.h. */
168
169int
170serial_event_fd (struct serial_event *event)
171{
172 struct serial *ser = (struct serial *) event;
173
174 return ser->fd;
175}
176
177/* See ser-event.h. */
178
179void
180serial_event_set (struct serial_event *event)
181{
182 struct serial *ser = (struct serial *) event;
183 struct serial_event_state *state = (struct serial_event_state *) ser->state;
184#ifndef USE_WIN32API
185 int r;
186 char c = '+'; /* Anything. */
187
188 do
189 {
190 r = write (state->write_fd, &c, 1);
191 }
192 while (r < 0 && errno == EINTR);
193#else
194 SetEvent (state->event);
195#endif
196}
197
198/* See ser-event.h. */
199
200void
201serial_event_clear (struct serial_event *event)
202{
203 struct serial *ser = (struct serial *) event;
204#ifndef USE_WIN32API
205 int r;
206
207 do
208 {
209 char c;
210
211 r = read (ser->fd, &c, 1);
212 }
213 while (r > 0 || (r < 0 && errno == EINTR));
214#else
215 struct serial_event_state *state = (struct serial_event_state *) ser->state;
216 ResetEvent (state->event);
217#endif
218}
const char *const name
void xfree(void *)
ssize_t read(int fd, void *buf, size_t count)
static void serial_event_close(struct serial *scb)
Definition ser-event.c:93
static int serial_event_open(struct serial *scb, const char *name)
Definition ser-event.c:52
static const struct serial_ops serial_event_ops
Definition ser-event.c:130
void serial_event_set(struct serial_event *event)
Definition ser-event.c:180
void serial_event_clear(struct serial_event *event)
Definition ser-event.c:201
struct serial_event * make_serial_event(void)
Definition ser-event.c:162
int serial_event_fd(struct serial_event *event)
Definition ser-event.c:170
struct serial * serial_open_ops(const struct serial_ops *ops)
Definition serial.c:265
int fd
Definition serial.h:238
void * state
Definition serial.h:245