1 /* Serial interface for a selectable event.
2 Copyright (C) 2016-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
20 #include "ser-event.h"
22 #include "gdbsupport/filestuff.h"
24 /* On POSIX hosts, a serial_event is basically an abstraction for the
25 classical self-pipe trick.
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. */
37 struct serial_event_state
40 /* The Windows event object, created with CreateEvent. */
43 /* The write side of the pipe. The read side is in
49 /* Open a new serial event. */
52 serial_event_open (struct serial
*scb
, const char *name
)
54 struct serial_event_state
*state
;
56 state
= XNEW (struct serial_event_state
);
63 if (gdb_pipe_cloexec (fds
) == -1)
64 internal_error ("creating serial event pipe failed.");
66 fcntl (fds
[0], F_SETFL
, O_NONBLOCK
);
67 fcntl (fds
[1], F_SETFL
, O_NONBLOCK
);
70 state
->write_fd
= fds
[1];
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. */
79 /* A manual-reset event. */
80 state
->event
= CreateEvent (0, TRUE
, FALSE
, 0);
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);
91 serial_event_close (struct serial
*scb
)
93 struct serial_event_state
*state
= (struct serial_event_state
*) scb
->state
;
97 close (state
->write_fd
);
99 CloseHandle (state
->event
);
110 /* Implementation of the wait_handle method. Returns the native
111 Windows event object handle. */
114 serial_event_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
116 struct serial_event_state
*state
= (struct serial_event_state
*) scb
->state
;
118 *read
= state
->event
;
123 /* The serial_ops for struct serial_event objects. Note we never
124 register this serial type with serial_add_interface, because this
125 is internal implementation detail never to be used by remote
126 targets for protocol transport. */
128 static const struct serial_ops serial_event_ops
=
136 NULL
, /* flush_output */
137 NULL
, /* flush_input */
138 NULL
, /* send_break */
140 NULL
, /* get_tty_state */
141 NULL
, /* copy_tty_state */
142 NULL
, /* set_tty_state */
143 NULL
, /* print_tty_state */
144 NULL
, /* setbaudrate */
145 NULL
, /* setstopbits */
146 NULL
, /* setparity */
147 NULL
, /* drain_output */
149 NULL
, /* read_prim */
150 NULL
, /* write_prim */
153 serial_event_wait_handle
,
157 /* See ser-event.h. */
159 struct serial_event
*
160 make_serial_event (void)
162 return (struct serial_event
*) serial_open_ops (&serial_event_ops
);
165 /* See ser-event.h. */
168 serial_event_fd (struct serial_event
*event
)
170 struct serial
*ser
= (struct serial
*) event
;
175 /* See ser-event.h. */
178 serial_event_set (struct serial_event
*event
)
180 struct serial
*ser
= (struct serial
*) event
;
181 struct serial_event_state
*state
= (struct serial_event_state
*) ser
->state
;
184 char c
= '+'; /* Anything. */
188 r
= write (state
->write_fd
, &c
, 1);
190 while (r
< 0 && errno
== EINTR
);
192 SetEvent (state
->event
);
196 /* See ser-event.h. */
199 serial_event_clear (struct serial_event
*event
)
201 struct serial
*ser
= (struct serial
*) event
;
209 r
= read (ser
->fd
, &c
, 1);
211 while (r
> 0 || (r
< 0 && errno
== EINTR
));
213 struct serial_event_state
*state
= (struct serial_event_state
*) ser
->state
;
214 ResetEvent (state
->event
);