| 1 | /* Preemption of Hurd signals before POSIX.1 semantics take over. |
| 2 | Copyright (C) 1996-2024 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. |
| 4 | |
| 5 | The GNU C Library is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | License as published by the Free Software Foundation; either |
| 8 | version 2.1 of the License, or (at your option) any later version. |
| 9 | |
| 10 | The GNU C Library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | Lesser General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ |
| 18 | |
| 19 | #ifndef _HURD_SIGPREEMPT_H |
| 20 | |
| 21 | #define _HURD_SIGPREEMPT_H 1 |
| 22 | #define __need_size_t |
| 23 | #include <stddef.h> |
| 24 | #include <errno.h> |
| 25 | #include <bits/types/error_t.h> |
| 26 | #include <signal.h> /* For sighandler_t, SIG_ERR. */ |
| 27 | #include <bits/types/sigset_t.h> |
| 28 | struct hurd_sigstate; /* <hurd/signal.h> */ |
| 29 | struct hurd_signal_detail; /* <hurd/signal.h> */ |
| 30 | |
| 31 | struct hurd_signal_preemptor |
| 32 | { |
| 33 | /* These members select which signals this structure will apply to. |
| 34 | The rest of the structure is only consulted if these match. */ |
| 35 | sigset_t signals; /* Signals preempted. */ |
| 36 | unsigned long int first, last; /* Range of sigcode values preempted. */ |
| 37 | |
| 38 | /* This function will be called (with SS->lock held) to decide what to |
| 39 | do with the signal described. It may modify the codes of the signal |
| 40 | passed. If the return value is SIG_ERR, the next matching preemptor |
| 41 | is tried, or the normal handling is done for the signal (which may |
| 42 | have been changed by the preemptor function). Otherwise, the signal |
| 43 | is processed as if the return value were its handler setting. */ |
| 44 | __sighandler_t (*preemptor) (struct hurd_signal_preemptor *preemptor, |
| 45 | struct hurd_sigstate *ss, |
| 46 | int *signo, struct hurd_signal_detail *detail); |
| 47 | /* If PREEMPTOR is null, act as if it returned HANDLER. */ |
| 48 | __sighandler_t handler; |
| 49 | |
| 50 | struct hurd_signal_preemptor *next; /* List structure. */ |
| 51 | }; |
| 52 | |
| 53 | /* The caller must initialize all members of *PREEMPTOR except `next'. |
| 54 | The preemptor is registered on the global list. */ |
| 55 | void hurd_preempt_signals (struct hurd_signal_preemptor *preemptor); |
| 56 | |
| 57 | /* Remove a preemptor registered with hurd_preempt_signals. */ |
| 58 | void hurd_unpreempt_signals (struct hurd_signal_preemptor *preemptor); |
| 59 | |
| 60 | |
| 61 | /* Call *OPERATE and return its value. If a signal in SIGSET with a sigcode |
| 62 | in the range [FIRST,LAST] arrives during the call, catch it. If HANDLER |
| 63 | is a function, it handles the signal in the normal way (i.e. it should |
| 64 | longjmp unless it can restart the insn on return). If it is SIG_ERR, |
| 65 | hurd_catch_signal returns the sc_error value from the signal (or |
| 66 | EGRATUITOUS if that is zero). |
| 67 | |
| 68 | The preemptor structure is passed to *OPERATE, which may modify its |
| 69 | sigcode range or functions at any time during which it is guaranteed no |
| 70 | signal in SIGSET will arrive. */ |
| 71 | |
| 72 | error_t hurd_catch_signal (sigset_t sigset, |
| 73 | unsigned long int first, unsigned long int last, |
| 74 | error_t (*operate) (struct hurd_signal_preemptor *), |
| 75 | __sighandler_t handler); |
| 76 | |
| 77 | |
| 78 | /* Convenience functions using `hurd_catch_signal'. */ |
| 79 | |
| 80 | |
| 81 | /* Like `memset', but catch faults in DEST. */ |
| 82 | error_t hurd_safe_memset (void *dest, int byte, size_t nbytes); |
| 83 | |
| 84 | /* Like `memcpy', but catch faults in SRC. */ |
| 85 | error_t hurd_safe_copyin (void *dest, const void *src, size_t nbytes); |
| 86 | |
| 87 | /* Like `memcpy', but catch faults in DEST. */ |
| 88 | error_t hurd_safe_copyout (void *dest, const void *src, size_t nbytes); |
| 89 | |
| 90 | /* Like `memmove', but catch faults in SRC or DEST. |
| 91 | If only one region is expected to fault, it is more efficient |
| 92 | to use `hurd_safe_copyin' or `hurd_safe_copyout' as appropriate. */ |
| 93 | error_t hurd_safe_memmove (void *dest, const void *src, size_t nbytes); |
| 94 | |
| 95 | |
| 96 | #endif /* hurd/sigpreempt.h */ |
| 97 | |