xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/event-pipe.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
1 /* Event pipe for GDB, the GNU debugger.
2 
3    Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "gdbsupport/event-pipe.h"
21 #include "gdbsupport/filestuff.h"
22 
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 
27 event_pipe::~event_pipe ()
28 {
29   if (is_open ())
30     close_pipe ();
31 }
32 
33 /* See event-pipe.h.  */
34 
35 bool
36 event_pipe::open_pipe ()
37 {
38   if (is_open ())
39     return false;
40 
41   if (gdb_pipe_cloexec (m_fds) == -1)
42     return false;
43 
44   if (fcntl (m_fds[0], F_SETFL, O_NONBLOCK) == -1
45       || fcntl (m_fds[1], F_SETFL, O_NONBLOCK) == -1)
46     {
47       close_pipe ();
48       return false;
49     }
50 
51   return true;
52 }
53 
54 /* See event-pipe.h.  */
55 
56 void
57 event_pipe::close_pipe ()
58 {
59   ::close (m_fds[0]);
60   ::close (m_fds[1]);
61   m_fds[0] = -1;
62   m_fds[1] = -1;
63 }
64 
65 /* See event-pipe.h.  */
66 
67 void
68 event_pipe::flush ()
69 {
70   int ret;
71   char buf;
72 
73   do
74     {
75       ret = read (m_fds[0], &buf, 1);
76     }
77   while (ret >= 0 || (ret == -1 && errno == EINTR));
78 }
79 
80 /* See event-pipe.h.  */
81 
82 void
83 event_pipe::mark ()
84 {
85   int ret;
86 
87   /* It doesn't really matter what the pipe contains, as long we end
88      up with something in it.  Might as well flush the previous
89      left-overs.  */
90   flush ();
91 
92   do
93     {
94       ret = write (m_fds[1], "+", 1);
95     }
96   while (ret == -1 && errno == EINTR);
97 
98   /* Ignore EAGAIN.  If the pipe is full, the event loop will already
99      be awakened anyway.  */
100 }
101