18dffb485Schristos /* Utility for handling interrupted syscalls by signals. 28dffb485Schristos 3*5ba1f45fSchristos Copyright (C) 2020-2024 Free Software Foundation, Inc. 48dffb485Schristos 58dffb485Schristos This file is part of GDB. 68dffb485Schristos 78dffb485Schristos This program is free software; you can redistribute it and/or modify 88dffb485Schristos it under the terms of the GNU General Public License as published by 98dffb485Schristos the Free Software Foundation; either version 3 of the License, or 108dffb485Schristos (at your option) any later version. 118dffb485Schristos 128dffb485Schristos This program is distributed in the hope that it will be useful, 138dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 148dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158dffb485Schristos GNU General Public License for more details. 168dffb485Schristos 178dffb485Schristos You should have received a copy of the GNU General Public License 188dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 198dffb485Schristos 208dffb485Schristos #ifndef GDBSUPPORT_EINTR_H 218dffb485Schristos #define GDBSUPPORT_EINTR_H 228dffb485Schristos 238dffb485Schristos #include <cerrno> 248dffb485Schristos 258dffb485Schristos namespace gdb 268dffb485Schristos { 278dffb485Schristos /* Repeat a system call interrupted with a signal. 288dffb485Schristos 298dffb485Schristos A utility for handling interrupted syscalls, which return with error 308dffb485Schristos and set the errno to EINTR. The interrupted syscalls can be repeated, 318dffb485Schristos until successful completion. This utility avoids wrapping code with 328dffb485Schristos manual checks for such errors which are highly repetitive. 338dffb485Schristos 348dffb485Schristos For example, with: 358dffb485Schristos 368dffb485Schristos ssize_t ret; 378dffb485Schristos do 388dffb485Schristos { 398dffb485Schristos errno = 0; 408dffb485Schristos ret = ::write (pipe[1], "+", 1); 418dffb485Schristos } 428dffb485Schristos while (ret == -1 && errno == EINTR); 438dffb485Schristos 448dffb485Schristos You could wrap it by writing the wrapped form: 458dffb485Schristos 464b169a6bSchristos ssize_t ret = gdb::handle_eintr (-1, ::write, pipe[1], "+", 1); 478dffb485Schristos 484b169a6bSchristos ERRVAL specifies the failure value indicating that the call to the 494b169a6bSchristos F function with ARGS... arguments was possibly interrupted with a 504b169a6bSchristos signal. */ 518dffb485Schristos 524b169a6bSchristos template<typename ErrorValType, typename Fun, typename... Args> 534b169a6bSchristos inline auto 544b169a6bSchristos handle_eintr (ErrorValType errval, const Fun &f, const Args &... args) 554b169a6bSchristos -> decltype (f (args...)) 568dffb485Schristos { 574b169a6bSchristos decltype (f (args...)) ret; 584b169a6bSchristos 598dffb485Schristos do 608dffb485Schristos { 618dffb485Schristos errno = 0; 624b169a6bSchristos ret = f (args...); 638dffb485Schristos } 644b169a6bSchristos while (ret == errval && errno == EINTR); 654b169a6bSchristos 668dffb485Schristos return ret; 678dffb485Schristos } 684b169a6bSchristos 694b169a6bSchristos } /* namespace gdb */ 708dffb485Schristos 718dffb485Schristos #endif /* GDBSUPPORT_EINTR_H */ 72