mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
[gdb] Handle EINTR in ser-event.c
Use gdb syscall wrappers to handle EINTR in ser-event.c. Tested on aarch64-linux.
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "ser-event.h"
|
#include "ser-event.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "gdbsupport/filestuff.h"
|
#include "gdbsupport/filestuff.h"
|
||||||
|
#include "gdbsupport/eintr.h"
|
||||||
|
|
||||||
/* On POSIX hosts, a serial_event is basically an abstraction for the
|
/* On POSIX hosts, a serial_event is basically an abstraction for the
|
||||||
classical self-pipe trick.
|
classical self-pipe trick.
|
||||||
@@ -62,8 +63,8 @@ serial_event_open (struct serial *scb, const char *name)
|
|||||||
if (gdb_pipe_cloexec (fds) == -1)
|
if (gdb_pipe_cloexec (fds) == -1)
|
||||||
internal_error ("creating serial event pipe failed.");
|
internal_error ("creating serial event pipe failed.");
|
||||||
|
|
||||||
fcntl (fds[0], F_SETFL, O_NONBLOCK);
|
gdb::fcntl (fds[0], F_SETFL, O_NONBLOCK);
|
||||||
fcntl (fds[1], F_SETFL, O_NONBLOCK);
|
gdb::fcntl (fds[1], F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
scb->fd = fds[0];
|
scb->fd = fds[0];
|
||||||
state->write_fd = fds[1];
|
state->write_fd = fds[1];
|
||||||
@@ -91,9 +92,9 @@ serial_event_close (struct serial *scb)
|
|||||||
{
|
{
|
||||||
struct serial_event_state *state = (struct serial_event_state *) scb->state;
|
struct serial_event_state *state = (struct serial_event_state *) scb->state;
|
||||||
|
|
||||||
close (scb->fd);
|
gdb::close (scb->fd);
|
||||||
#ifndef USE_WIN32API
|
#ifndef USE_WIN32API
|
||||||
close (state->write_fd);
|
gdb::close (state->write_fd);
|
||||||
#else
|
#else
|
||||||
CloseHandle (state->event);
|
CloseHandle (state->event);
|
||||||
#endif
|
#endif
|
||||||
@@ -179,14 +180,9 @@ serial_event_set (struct serial_event *event)
|
|||||||
struct serial *ser = (struct serial *) event;
|
struct serial *ser = (struct serial *) event;
|
||||||
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
||||||
#ifndef USE_WIN32API
|
#ifndef USE_WIN32API
|
||||||
int r;
|
|
||||||
char c = '+'; /* Anything. */
|
char c = '+'; /* Anything. */
|
||||||
|
|
||||||
do
|
gdb::write (state->write_fd, &c, 1);
|
||||||
{
|
|
||||||
r = write (state->write_fd, &c, 1);
|
|
||||||
}
|
|
||||||
while (r < 0 && errno == EINTR);
|
|
||||||
#else
|
#else
|
||||||
SetEvent (state->event);
|
SetEvent (state->event);
|
||||||
#endif
|
#endif
|
||||||
@@ -205,9 +201,9 @@ serial_event_clear (struct serial_event *event)
|
|||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
r = read (ser->fd, &c, 1);
|
r = gdb::read (ser->fd, &c, 1);
|
||||||
}
|
}
|
||||||
while (r > 0 || (r < 0 && errno == EINTR));
|
while (r > 0);
|
||||||
#else
|
#else
|
||||||
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
||||||
ResetEvent (state->event);
|
ResetEvent (state->event);
|
||||||
|
|||||||
@@ -101,6 +101,17 @@ read (int fd, void *buf, size_t count)
|
|||||||
return gdb::handle_eintr (-1, ::read, fd, buf, count);
|
return gdb::handle_eintr (-1, ::read, fd, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Args> int fcntl (int fd, int op, Args... args)
|
||||||
|
{
|
||||||
|
return gdb::handle_eintr (-1, ::fcntl, fd, op, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t
|
||||||
|
write (int fd, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
return gdb::handle_eintr (-1, ::write, fd, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace gdb */
|
} /* namespace gdb */
|
||||||
|
|
||||||
#endif /* GDBSUPPORT_EINTR_H */
|
#endif /* GDBSUPPORT_EINTR_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user