1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <hurd/signal.h>
21: #include <hurd/sigpreempt.h>
22: #include <string.h>
23: #include <assert.h>
24:
25: error_t
26: hurd_catch_signal (sigset_t sigset,
27: unsigned long int first, unsigned long int last,
28: error_t (*operate) (struct hurd_signal_preemptor *),
29: sighandler_t handler)
30: {
31: jmp_buf buf;
32: void throw (int signo, long int sigcode, struct sigcontext *scp)
33: { longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
34:
35: struct hurd_signal_preemptor preemptor =
36: {
37: sigset, first, last,
38: NULL, handler == SIG_ERR ? (sighandler_t) &throw : handler,
39: };
40:
41: struct hurd_sigstate *const ss = _hurd_self_sigstate ();
42: error_t error;
43:
44: if (handler == SIG_ERR)
45:
46: error = 0;
47: else
48:
49: error = setjmp (buf);
50:
51: if (error == 0)
52: {
53:
54: __spin_lock (&ss->lock);
55: preemptor.next = ss->preemptors;
56: ss->preemptors = &preemptor;
57: __spin_unlock (&ss->lock);
58:
59:
60: (*operate) (&preemptor);
61: }
62:
63:
64:
65:
66:
67: __spin_lock (&ss->lock);
68: assert (ss->preemptors == &preemptor);
69: ss->preemptors = preemptor.next;
70: __spin_unlock (&ss->lock);
71:
72: return error;
73: }
74:
75:
76: error_t
77: hurd_safe_memset (void *dest, int byte, size_t nbytes)
78: {
79: error_t operate (struct hurd_signal_preemptor *preemptor)
80: {
81: memset (dest, byte, nbytes);
82: return 0;
83: }
84: return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
85: (vm_address_t) dest, (vm_address_t) dest + nbytes,
86: &operate, SIG_ERR);
87: }
88:
89:
90: error_t
91: hurd_safe_copyout (void *dest, const void *src, size_t nbytes)
92: {
93: error_t operate (struct hurd_signal_preemptor *preemptor)
94: {
95: memcpy (dest, src, nbytes);
96: return 0;
97: }
98: return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
99: (vm_address_t) dest, (vm_address_t) dest + nbytes,
100: &operate, SIG_ERR);
101: }
102:
103: error_t
104: hurd_safe_copyin (void *dest, const void *src, size_t nbytes)
105: {
106: error_t operate (struct hurd_signal_preemptor *preemptor)
107: {
108: memcpy (dest, src, nbytes);
109: return 0;
110: }
111: return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
112: (vm_address_t) src, (vm_address_t) src + nbytes,
113: &operate, SIG_ERR);
114: }
115:
116: error_t
117: hurd_safe_memmove (void *dest, const void *src, size_t nbytes)
118: {
119: jmp_buf buf;
120: void throw (int signo, long int sigcode, struct sigcontext *scp)
121: { longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
122:
123: struct hurd_signal_preemptor src_preemptor =
124: {
125: sigmask (SIGBUS) | sigmask (SIGSEGV),
126: (vm_address_t) src, (vm_address_t) src + nbytes,
127: NULL, (sighandler_t) &throw,
128: };
129: struct hurd_signal_preemptor dest_preemptor =
130: {
131: sigmask (SIGBUS) | sigmask (SIGSEGV),
132: (vm_address_t) dest, (vm_address_t) dest + nbytes,
133: NULL, (sighandler_t) &throw,
134: &src_preemptor
135: };
136:
137: struct hurd_sigstate *const ss = _hurd_self_sigstate ();
138: error_t error;
139:
140:
141: error = setjmp (buf);
142:
143: if (error == 0)
144: {
145:
146: __spin_lock (&ss->lock);
147: src_preemptor.next = ss->preemptors;
148: ss->preemptors = &dest_preemptor;
149: __spin_unlock (&ss->lock);
150:
151:
152: memmove (dest, src, nbytes);
153: }
154:
155:
156:
157:
158:
159: __spin_lock (&ss->lock);
160: assert (ss->preemptors == &dest_preemptor);
161: ss->preemptors = src_preemptor.next;
162: __spin_unlock (&ss->lock);
163:
164: return error;
165: }