mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
726e13564b
This commit garbage collects the termio and sgtty support. GDB's terminal handling code still has support for the old termio and sgtty interfaces in addition to termios. However, I think it's pretty safe to assume that for a long, long time, Unix-like systems provide termios. GNU/Linux, Solaris, Cygwin, AIX, DJGPP, macOS and the BSDs all have had termios.h for many years. Looking around the web, I found discussions about FreeBSD folks trying to get rid of old sgtty.h a decade ago: https://lists.freebsd.org/pipermail/freebsd-hackers/2007-March/019983.html So I think support for termio and sgtty in GDB is just dead code that is never compiled anywhere and is just getting in the way. For example, serial_noflush_set_tty_state and the raw<->cooked concerns mentioned in inflow.c only exist because of sgtty (see hardwire_noflush_set_tty_state). Regtested on GNU/Linux. Confirmed that I can still build Solaris, DJGPP and AIX GDB and that the resulting GDBs still include the termios.h-guarded code. Confirmed mingw-w64 GDB still builds and skips the termios.h-guarded code. gdb/ChangeLog: 2017-11-06 Pedro Alves <palves@redhat.com> * Makefile.in (SER_HARDWIRE): Update comment. (HFILES_NO_SRCDIR): Remove gdb_termios.h. * common/gdb_termios.h: Delete file. * common/job-control.c: Include termios.h and unistd.h instead of gdb_termios.h. (gdb_setpgid): Remove HAVE_TERMIOS || TIOCGPGRP preprocessor check. (have_job_control): Check HAVE_TERMIOS_H instead of HAVE_TERMIOS. Remove sgtty code. * configure.ac: No longer check for termio.h and sgtty.h. * configure: Regenerate. * inflow.c: Include termios.h instead of gdb_termios.h. Replace PROCESS_GROUP_TYPE checks with HAVE_TERMIOS_H checks throughout. Replace PROCESS_GROUP_TYPE references with pid_t references throughout. (gdb_getpgrp): Delete. (set_initial_gdb_ttystate): Use tcgetpgrp instead of gdb_getpgrp. (child_terminal_inferior): Remove comment. Remove sgtty code. (child_terminal_ours_1): Use tcgetpgrp directly instead of gdb_getpgrp. Use serial_set_tty_state instead aof serial_noflush_set_tty_state. Remove sgtty code. * inflow.h: Include unistd.h instead of gdb_termios.h. Replace PROCESS_GROUP_TYPE check with HAVE_TERMIOS_H check. (inferior_process_group): Now returns pid_t. * ser-base.c (ser_base_noflush_set_tty_state): Delete. * ser-base.h (ser_base_noflush_set_tty_state): Delete. * ser-event.c (serial_event_ops): Update. * ser-go32.c (dos_noflush_set_tty_state): Delete. (dos_ops): Update. * ser-mingw.c (hardwire_ops, tty_ops, pipe_ops, tcp_ops): Update. * ser-pipe.c (pipe_ops): Update. * ser-tcp.c (tcp_ops): Update. * ser-unix.c: Include termios.h instead of gdb_termios.h. Remove HAVE_TERMIOS checks. [HAVE_TERMIO] (struct hardwire_ttystate): Delete. [HAVE_SGTTY] (struct hardwire_ttystate): Delete. (get_tty_state, set_tty_state): Drop termio and sgtty code, and assume termios. (hardwire_noflush_set_tty_state): Delete. (hardwire_print_tty_state, hardwire_drain_output) (hardwire_flush_output, hardwire_flush_input) (hardwire_send_break, hardwire_raw, hardwire_setbaudrate) (hardwire_setstopbits, hardwire_setparity): Drop termio and sgtty code, and assume termios. (hardwire_ops): Update. (_initialize_ser_hardwire): Remove HAVE_TERMIOS check. * serial.c (serial_noflush_set_tty_state): Delete. * serial.h (serial_noflush_set_tty_state): Delete. (serial_ops::noflush_set_tty_state): Delete. gdb/gdbserver/ChangeLog: 2017-11-06 Pedro Alves <palves@redhat.com> * configure.ac: No longer check for termio.h and sgtty.h. * configure: Regenerate. * remote-utils.c: Include termios.h instead of gdb_termios.h. (remote_open): Check HAVE_TERMIOS_H instead of HAVE_TERMIOS. Remove termio and sgtty code.
220 lines
5.4 KiB
C
220 lines
5.4 KiB
C
/* Serial interface for a selectable event.
|
|
Copyright (C) 2016-2017 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include "defs.h"
|
|
#include "ser-event.h"
|
|
#include "serial.h"
|
|
#include "common/filestuff.h"
|
|
|
|
/* On POSIX hosts, a serial_event is basically an abstraction for the
|
|
classical self-pipe trick.
|
|
|
|
On Windows, a serial_event is a wrapper around a native Windows
|
|
event object. Because we want to interface with gdb_select, which
|
|
takes file descriptors, we need to wrap that Windows event object
|
|
in a file descriptor. As _open_osfhandle can not be used with
|
|
event objects, we instead create a dummy file wrap that in a file
|
|
descriptor with _open_osfhandle, and pass that as selectable
|
|
descriptor to callers. As Windows' gdb_select converts file
|
|
descriptors back to Windows handles by calling serial->wait_handle,
|
|
nothing ever actually waits on that file descriptor. */
|
|
|
|
struct serial_event_state
|
|
{
|
|
#ifdef USE_WIN32API
|
|
/* The Windows event object, created with CreateEvent. */
|
|
HANDLE event;
|
|
#else
|
|
/* The write side of the pipe. The read side is in
|
|
serial->fd. */
|
|
int write_fd;
|
|
#endif
|
|
};
|
|
|
|
/* Open a new serial event. */
|
|
|
|
static int
|
|
serial_event_open (struct serial *scb, const char *name)
|
|
{
|
|
struct serial_event_state *state;
|
|
|
|
state = XNEW (struct serial_event_state);
|
|
scb->state = state;
|
|
|
|
#ifndef USE_WIN32API
|
|
{
|
|
int fds[2];
|
|
|
|
if (gdb_pipe_cloexec (fds) == -1)
|
|
internal_error (__FILE__, __LINE__,
|
|
"creating serial event pipe failed.");
|
|
|
|
fcntl (fds[0], F_SETFL, O_NONBLOCK);
|
|
fcntl (fds[1], F_SETFL, O_NONBLOCK);
|
|
|
|
scb->fd = fds[0];
|
|
state->write_fd = fds[1];
|
|
}
|
|
#else
|
|
{
|
|
/* A dummy file object that can be wrapped in a file descriptor.
|
|
We don't need to store this handle because closing the file
|
|
descriptor automatically closes this. */
|
|
HANDLE dummy_file;
|
|
|
|
/* A manual-reset event. */
|
|
state->event = CreateEvent (0, TRUE, FALSE, 0);
|
|
|
|
/* The dummy file handle. Created just so we have something
|
|
wrappable in a file descriptor. */
|
|
dummy_file = CreateFile ("nul", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
scb->fd = _open_osfhandle ((intptr_t) dummy_file, 0);
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
serial_event_close (struct serial *scb)
|
|
{
|
|
struct serial_event_state *state = (struct serial_event_state *) scb->state;
|
|
|
|
close (scb->fd);
|
|
#ifndef USE_WIN32API
|
|
close (state->write_fd);
|
|
#else
|
|
CloseHandle (state->event);
|
|
#endif
|
|
|
|
scb->fd = -1;
|
|
|
|
xfree (state);
|
|
scb->state = NULL;
|
|
}
|
|
|
|
#ifdef USE_WIN32API
|
|
|
|
/* Implementation of the wait_handle method. Returns the native
|
|
Windows event object handle. */
|
|
|
|
static void
|
|
serial_event_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
|
|
{
|
|
struct serial_event_state *state = (struct serial_event_state *) scb->state;
|
|
|
|
*read = state->event;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* The serial_ops for struct serial_event objects. Note we never
|
|
register this serial type with serial_add_interface, because this
|
|
is internal implementation detail never to be used by remote
|
|
targets for protocol transport. */
|
|
|
|
static const struct serial_ops serial_event_ops =
|
|
{
|
|
"event",
|
|
serial_event_open,
|
|
serial_event_close,
|
|
NULL, /* fdopen */
|
|
NULL, /* readchar */
|
|
NULL, /* write */
|
|
NULL, /* flush_output */
|
|
NULL, /* flush_input */
|
|
NULL, /* send_break */
|
|
NULL, /* go_raw */
|
|
NULL, /* get_tty_state */
|
|
NULL, /* copy_tty_state */
|
|
NULL, /* set_tty_state */
|
|
NULL, /* print_tty_state */
|
|
NULL, /* setbaudrate */
|
|
NULL, /* setstopbits */
|
|
NULL, /* setparity */
|
|
NULL, /* drain_output */
|
|
NULL, /* async */
|
|
NULL, /* read_prim */
|
|
NULL, /* write_prim */
|
|
NULL, /* avail */
|
|
#ifdef USE_WIN32API
|
|
serial_event_wait_handle,
|
|
#endif
|
|
};
|
|
|
|
/* See ser-event.h. */
|
|
|
|
struct serial_event *
|
|
make_serial_event (void)
|
|
{
|
|
return (struct serial_event *) serial_open_ops (&serial_event_ops);
|
|
}
|
|
|
|
/* See ser-event.h. */
|
|
|
|
int
|
|
serial_event_fd (struct serial_event *event)
|
|
{
|
|
struct serial *ser = (struct serial *) event;
|
|
|
|
return ser->fd;
|
|
}
|
|
|
|
/* See ser-event.h. */
|
|
|
|
void
|
|
serial_event_set (struct serial_event *event)
|
|
{
|
|
struct serial *ser = (struct serial *) event;
|
|
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
|
#ifndef USE_WIN32API
|
|
int r;
|
|
char c = '+'; /* Anything. */
|
|
|
|
do
|
|
{
|
|
r = write (state->write_fd, &c, 1);
|
|
}
|
|
while (r < 0 && errno == EINTR);
|
|
#else
|
|
SetEvent (state->event);
|
|
#endif
|
|
}
|
|
|
|
/* See ser-event.h. */
|
|
|
|
void
|
|
serial_event_clear (struct serial_event *event)
|
|
{
|
|
struct serial *ser = (struct serial *) event;
|
|
struct serial_event_state *state = (struct serial_event_state *) ser->state;
|
|
#ifndef USE_WIN32API
|
|
int r;
|
|
|
|
do
|
|
{
|
|
char c;
|
|
|
|
r = read (ser->fd, &c, 1);
|
|
}
|
|
while (r > 0 || (r < 0 && errno == EINTR));
|
|
#else
|
|
ResetEvent (state->event);
|
|
#endif
|
|
}
|