diff options
author | Kamil Rytarowski <n54@gmx.com> | 2020-09-02 18:20:53 +0200 |
---|---|---|
committer | Kamil Rytarowski <n54@gmx.com> | 2020-09-10 15:35:12 +0200 |
commit | 48c9b4333270c9b4e9c43ba78aea92765e68ccbc (patch) | |
tree | 4d221162fbfd8fa1569d78510db659362ede16b8 /gdbsupport | |
parent | 7ad578807ad20ac19c0b31bf8b97c99eab1ce15e (diff) | |
download | gdb-48c9b4333270c9b4e9c43ba78aea92765e68ccbc.zip gdb-48c9b4333270c9b4e9c43ba78aea92765e68ccbc.tar.gz gdb-48c9b4333270c9b4e9c43ba78aea92765e68ccbc.tar.bz2 |
Add handle_eintr to wrap EINTR handling in syscalls
gdbsupport/ChangeLog:
* eintr.h: New file.
Diffstat (limited to 'gdbsupport')
-rw-r--r-- | gdbsupport/ChangeLog | 4 | ||||
-rw-r--r-- | gdbsupport/eintr.h | 67 |
2 files changed, 71 insertions, 0 deletions
diff --git a/gdbsupport/ChangeLog b/gdbsupport/ChangeLog index a196053..6cda605 100644 --- a/gdbsupport/ChangeLog +++ b/gdbsupport/ChangeLog @@ -1,3 +1,7 @@ +2020-09-10 Kamil Rytarowski <n54@gmx.com> + + * eintr.h: New file. + 2020-08-13 Simon Marchi <simon.marchi@polymtl.ca> * selftest.h (run_tests): Change parameter to array_view. diff --git a/gdbsupport/eintr.h b/gdbsupport/eintr.h new file mode 100644 index 0000000..64ff594 --- /dev/null +++ b/gdbsupport/eintr.h @@ -0,0 +1,67 @@ +/* Utility for handling interrupted syscalls by signals. + + Copyright (C) 2020 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 GDBSUPPORT_EINTR_H +#define GDBSUPPORT_EINTR_H + +#include <cerrno> + +namespace gdb +{ +/* Repeat a system call interrupted with a signal. + + A utility for handling interrupted syscalls, which return with error + and set the errno to EINTR. The interrupted syscalls can be repeated, + until successful completion. This utility avoids wrapping code with + manual checks for such errors which are highly repetitive. + + For example, with: + + ssize_t ret; + do + { + errno = 0; + ret = ::write (pipe[1], "+", 1); + } + while (ret == -1 && errno == EINTR); + + You could wrap it by writing the wrapped form: + + ssize_t ret = gdb::handle_eintr<ssize_t> (-1, ::write, pipe[1], "+", 1); + + The RET typename specifies the return type of the wrapped system call, which + is typically int or ssize_t. The R argument specifies the failure value + indicating the interrupted syscall when calling the F function with + the A... arguments. */ + +template <typename Ret, typename Fun, typename... Args> +inline Ret handle_eintr (const Ret &R, const Fun &F, const Args &... A) +{ + Ret ret; + do + { + errno = 0; + ret = F (A...); + } + while (ret == R && errno == EINTR); + return ret; +} +} + +#endif /* GDBSUPPORT_EINTR_H */ |