selftest = selftest.cc
endif
+if HAVE_PIPE_OR_PIPE2
+eventpipe = event-pipe.cc
+endif
+
libgdbsupport_a_SOURCES = \
agent.cc \
btrace-common.cc \
tdesc.cc \
thread-pool.cc \
xml-utils.cc \
+ ${eventpipe} \
$(selftest)
# Double-check that no defines are missing from our configury.
am__v_AR_1 =
libgdbsupport_a_AR = $(AR) $(ARFLAGS)
libgdbsupport_a_LIBADD =
-@SELFTEST_TRUE@am__objects_1 = selftest.$(OBJEXT)
+@HAVE_PIPE_OR_PIPE2_TRUE@am__objects_1 = event-pipe.$(OBJEXT)
+@SELFTEST_TRUE@am__objects_2 = selftest.$(OBJEXT)
am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \
buffer.$(OBJEXT) cleanups.$(OBJEXT) common-debug.$(OBJEXT) \
common-exceptions.$(OBJEXT) common-inferior.$(OBJEXT) \
safe-strerror.$(OBJEXT) scoped_mmap.$(OBJEXT) search.$(OBJEXT) \
signals.$(OBJEXT) signals-state-save-restore.$(OBJEXT) \
tdesc.$(OBJEXT) thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) \
- $(am__objects_1)
+ $(am__objects_1) $(am__objects_2)
libgdbsupport_a_OBJECTS = $(am_libgdbsupport_a_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
AM_CXXFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
noinst_LIBRARIES = libgdbsupport.a
@SELFTEST_TRUE@selftest = selftest.cc
+@HAVE_PIPE_OR_PIPE2_TRUE@eventpipe = event-pipe.cc
libgdbsupport_a_SOURCES = \
agent.cc \
btrace-common.cc \
tdesc.cc \
thread-pool.cc \
xml-utils.cc \
+ ${eventpipe} \
$(selftest)
all: config.h
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event-pipe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filestuff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@
LIBOBJS
WERROR_CFLAGS
WARN_CFLAGS
+HAVE_PIPE_OR_PIPE2_FALSE
+HAVE_PIPE_OR_PIPE2_TRUE
SELFTEST_FALSE
SELFTEST_TRUE
LTLIBIPT
fi
+ if test x$ac_cv_func_pipe = xyes -o x$ac_cv_func_pipe2 = xyes ; then
+ HAVE_PIPE_OR_PIPE2_TRUE=
+ HAVE_PIPE_OR_PIPE2_FALSE='#'
+else
+ HAVE_PIPE_OR_PIPE2_TRUE='#'
+ HAVE_PIPE_OR_PIPE2_FALSE=
+fi
+
+
# Check the return and argument types of ptrace.
as_fn_error $? "conditional \"SELFTEST\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_PIPE_OR_PIPE2_TRUE}" && test -z "${HAVE_PIPE_OR_PIPE2_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_PIPE_OR_PIPE2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
GDB_AC_SELFTEST
AM_CONDITIONAL(SELFTEST, $enable_unittests)
+AM_CONDITIONAL(HAVE_PIPE_OR_PIPE2,
+ [test x$ac_cv_func_pipe = xyes -o x$ac_cv_func_pipe2 = xyes ])
+
# Check the return and argument types of ptrace.
GDB_AC_PTRACE
--- /dev/null
+/* Event pipe for GDB, the GNU debugger.
+
+ Copyright (C) 2021 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 "gdbsupport/common-defs.h"
+#include "gdbsupport/event-pipe.h"
+#include "gdbsupport/filestuff.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+event_pipe::~event_pipe ()
+{
+ if (is_open ())
+ close ();
+}
+
+/* See event-pipe.h. */
+
+bool
+event_pipe::open ()
+{
+ if (is_open ())
+ return false;
+
+ if (gdb_pipe_cloexec (m_fds) == -1)
+ return false;
+
+ if (fcntl (m_fds[0], F_SETFL, O_NONBLOCK) == -1
+ || fcntl (m_fds[1], F_SETFL, O_NONBLOCK) == -1)
+ {
+ close ();
+ return false;
+ }
+
+ return true;
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::close ()
+{
+ ::close (m_fds[0]);
+ ::close (m_fds[1]);
+ m_fds[0] = -1;
+ m_fds[1] = -1;
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::flush ()
+{
+ int ret;
+ char buf;
+
+ do
+ {
+ ret = read (m_fds[0], &buf, 1);
+ }
+ while (ret >= 0 || (ret == -1 && errno == EINTR));
+}
+
+/* See event-pipe.h. */
+
+void
+event_pipe::mark ()
+{
+ int ret;
+
+ /* It doesn't really matter what the pipe contains, as long we end
+ up with something in it. Might as well flush the previous
+ left-overs. */
+ flush ();
+
+ do
+ {
+ ret = write (m_fds[1], "+", 1);
+ }
+ while (ret == -1 && errno == EINTR);
+
+ /* Ignore EAGAIN. If the pipe is full, the event loop will already
+ be awakened anyway. */
+}
--- /dev/null
+/* Event pipe for GDB, the GNU debugger.
+
+ Copyright (C) 2021 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/>. */
+
+#ifndef COMMON_EVENT_PIPE_H
+#define COMMON_EVENT_PIPE_H
+
+/* An event pipe used as a waitable file in the event loop in place of
+ some other event associated with a signal. The handler for the
+ signal marks the event pipe to force a wakeup in the event loop.
+ This uses the well-known self-pipe trick. */
+
+class event_pipe
+{
+public:
+ event_pipe() = default;
+ ~event_pipe();
+
+ DISABLE_COPY_AND_ASSIGN (event_pipe);
+
+ /* Create a new pipe. */
+ bool open ();
+
+ /* Close the pipe. */
+ void close ();
+
+ /* True if the event pipe has been opened. */
+ bool is_open () const
+ { return m_fds[0] != -1; }
+
+ /* The file descriptor of the waitable file to use in the event
+ loop. */
+ int event_fd () const
+ { return m_fds[0]; }
+
+ /* Flush the event pipe. */
+ void flush ();
+
+ /* Put something in the pipe, so the event loop wakes up. */
+ void mark ();
+private:
+ int m_fds[2] = { -1, -1 };
+};
+
+#endif /* COMMON_EVENT_PIPE_H */