* gcc.c (getenv_spec_function): New function.
[official-gcc.git] / gcc / ada / s-inmaop-posix.adb
blobe9da380f8517d1c31ddd57f5bafcf2309bccb2ad
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T . --
6 -- O P E R A T I O N S --
7 -- --
8 -- B o d y --
9 -- --
10 -- Copyright (C) 1991-1994, Florida State University --
11 -- Copyright (C) 1995-2006, AdaCore --
12 -- --
13 -- GNARL is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNARL; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
22 -- Boston, MA 02110-1301, USA. --
23 -- --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
30 -- --
31 -- GNARL was developed by the GNARL team at Florida State University. --
32 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
33 -- --
34 ------------------------------------------------------------------------------
36 -- This is a POSIX-like version of this package.
37 -- Note: this file can only be used for POSIX compliant systems.
39 with Interfaces.C;
40 -- used for int
41 -- size_t
42 -- unsigned
44 with System.OS_Interface;
45 -- used for various type, constant, and operations
47 with System.Storage_Elements;
48 -- used for To_Address
49 -- Integer_Address
51 package body System.Interrupt_Management.Operations is
53 use Interfaces.C;
54 use System.OS_Interface;
56 ---------------------
57 -- Local Variables --
58 ---------------------
60 Initial_Action : array (Signal) of aliased struct_sigaction;
62 Default_Action : aliased struct_sigaction;
64 Ignore_Action : aliased struct_sigaction;
66 ----------------------------
67 -- Thread_Block_Interrupt --
68 ----------------------------
70 procedure Thread_Block_Interrupt
71 (Interrupt : Interrupt_ID)
73 Result : Interfaces.C.int;
74 Mask : aliased sigset_t;
75 begin
76 Result := sigemptyset (Mask'Access);
77 pragma Assert (Result = 0);
78 Result := sigaddset (Mask'Access, Signal (Interrupt));
79 pragma Assert (Result = 0);
80 Result := pthread_sigmask (SIG_BLOCK, Mask'Unchecked_Access, null);
81 pragma Assert (Result = 0);
82 end Thread_Block_Interrupt;
84 ------------------------------
85 -- Thread_Unblock_Interrupt --
86 ------------------------------
88 procedure Thread_Unblock_Interrupt
89 (Interrupt : Interrupt_ID)
91 Mask : aliased sigset_t;
92 Result : Interfaces.C.int;
93 begin
94 Result := sigemptyset (Mask'Access);
95 pragma Assert (Result = 0);
96 Result := sigaddset (Mask'Access, Signal (Interrupt));
97 pragma Assert (Result = 0);
98 Result := pthread_sigmask (SIG_UNBLOCK, Mask'Unchecked_Access, null);
99 pragma Assert (Result = 0);
100 end Thread_Unblock_Interrupt;
102 ------------------------
103 -- Set_Interrupt_Mask --
104 ------------------------
106 procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
107 Result : Interfaces.C.int;
108 begin
109 Result := pthread_sigmask (SIG_SETMASK, Mask, null);
110 pragma Assert (Result = 0);
111 end Set_Interrupt_Mask;
113 procedure Set_Interrupt_Mask
114 (Mask : access Interrupt_Mask;
115 OMask : access Interrupt_Mask)
117 Result : Interfaces.C.int;
118 begin
119 Result := pthread_sigmask (SIG_SETMASK, Mask, OMask);
120 pragma Assert (Result = 0);
121 end Set_Interrupt_Mask;
123 ------------------------
124 -- Get_Interrupt_Mask --
125 ------------------------
127 procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
128 Result : Interfaces.C.int;
129 begin
130 Result := pthread_sigmask (SIG_SETMASK, null, Mask);
131 pragma Assert (Result = 0);
132 end Get_Interrupt_Mask;
134 --------------------
135 -- Interrupt_Wait --
136 --------------------
138 function Interrupt_Wait
139 (Mask : access Interrupt_Mask)
140 return Interrupt_ID
142 Result : Interfaces.C.int;
143 Sig : aliased Signal;
144 begin
145 Result := sigwait (Mask, Sig'Access);
147 if Result /= 0 then
148 return 0;
149 end if;
151 return Interrupt_ID (Sig);
152 end Interrupt_Wait;
154 ----------------------------
155 -- Install_Default_Action --
156 ----------------------------
158 procedure Install_Default_Action (Interrupt : Interrupt_ID) is
159 Result : Interfaces.C.int;
160 begin
161 Result := sigaction
162 (Signal (Interrupt),
163 Initial_Action (Signal (Interrupt))'Access, null);
164 pragma Assert (Result = 0);
165 end Install_Default_Action;
167 ---------------------------
168 -- Install_Ignore_Action --
169 ---------------------------
171 procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
172 Result : Interfaces.C.int;
173 begin
174 Result := sigaction (Signal (Interrupt), Ignore_Action'Access, null);
175 pragma Assert (Result = 0);
176 end Install_Ignore_Action;
178 -------------------------
179 -- Fill_Interrupt_Mask --
180 -------------------------
182 procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
183 Result : Interfaces.C.int;
184 begin
185 Result := sigfillset (Mask);
186 pragma Assert (Result = 0);
187 end Fill_Interrupt_Mask;
189 --------------------------
190 -- Empty_Interrupt_Mask --
191 --------------------------
193 procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
194 Result : Interfaces.C.int;
195 begin
196 Result := sigemptyset (Mask);
197 pragma Assert (Result = 0);
198 end Empty_Interrupt_Mask;
200 ---------------------------
201 -- Add_To_Interrupt_Mask --
202 ---------------------------
204 procedure Add_To_Interrupt_Mask
205 (Mask : access Interrupt_Mask;
206 Interrupt : Interrupt_ID)
208 Result : Interfaces.C.int;
209 begin
210 Result := sigaddset (Mask, Signal (Interrupt));
211 pragma Assert (Result = 0);
212 end Add_To_Interrupt_Mask;
214 --------------------------------
215 -- Delete_From_Interrupt_Mask --
216 --------------------------------
218 procedure Delete_From_Interrupt_Mask
219 (Mask : access Interrupt_Mask;
220 Interrupt : Interrupt_ID)
222 Result : Interfaces.C.int;
223 begin
224 Result := sigdelset (Mask, Signal (Interrupt));
225 pragma Assert (Result = 0);
226 end Delete_From_Interrupt_Mask;
228 ---------------
229 -- Is_Member --
230 ---------------
232 function Is_Member
233 (Mask : access Interrupt_Mask;
234 Interrupt : Interrupt_ID) return Boolean
236 Result : Interfaces.C.int;
237 begin
238 Result := sigismember (Mask, Signal (Interrupt));
239 pragma Assert (Result = 0 or else Result = 1);
240 return Result = 1;
241 end Is_Member;
243 -------------------------
244 -- Copy_Interrupt_Mask --
245 -------------------------
247 procedure Copy_Interrupt_Mask
248 (X : out Interrupt_Mask;
249 Y : Interrupt_Mask) is
250 begin
251 X := Y;
252 end Copy_Interrupt_Mask;
254 ----------------------------
255 -- Interrupt_Self_Process --
256 ----------------------------
258 procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
259 Result : Interfaces.C.int;
260 begin
261 Result := kill (getpid, Signal (Interrupt));
262 pragma Assert (Result = 0);
263 end Interrupt_Self_Process;
265 --------------------------
266 -- Setup_Interrupt_Mask --
267 --------------------------
269 procedure Setup_Interrupt_Mask is
270 begin
271 -- Mask task for all signals. The original mask of the Environment task
272 -- will be recovered by Interrupt_Manager task during the elaboration
273 -- of s-interr.adb.
275 Set_Interrupt_Mask (All_Tasks_Mask'Access);
276 end Setup_Interrupt_Mask;
278 begin
279 declare
280 mask : aliased sigset_t;
281 allmask : aliased sigset_t;
282 Result : Interfaces.C.int;
284 begin
285 Interrupt_Management.Initialize;
287 for Sig in 1 .. Signal'Last loop
288 Result := sigaction
289 (Sig, null, Initial_Action (Sig)'Unchecked_Access);
291 -- ??? [assert 1]
292 -- we can't check Result here since sigaction will fail on
293 -- SIGKILL, SIGSTOP, and possibly other signals
294 -- pragma Assert (Result = 0);
296 end loop;
298 -- Setup the masks to be exported
300 Result := sigemptyset (mask'Access);
301 pragma Assert (Result = 0);
303 Result := sigfillset (allmask'Access);
304 pragma Assert (Result = 0);
306 Default_Action.sa_flags := 0;
307 Default_Action.sa_mask := mask;
308 Default_Action.sa_handler :=
309 Storage_Elements.To_Address
310 (Storage_Elements.Integer_Address (SIG_DFL));
312 Ignore_Action.sa_flags := 0;
313 Ignore_Action.sa_mask := mask;
314 Ignore_Action.sa_handler :=
315 Storage_Elements.To_Address
316 (Storage_Elements.Integer_Address (SIG_IGN));
318 for J in Interrupt_ID loop
320 -- We need to check whether J is in Keep_Unmasked because
321 -- the index type of the Keep_Unmasked array is not always
322 -- Interrupt_ID; it may be a subtype of Interrupt_ID.
324 if J in Keep_Unmasked'Range and then Keep_Unmasked (J) then
325 Result := sigaddset (mask'Access, Signal (J));
326 pragma Assert (Result = 0);
327 Result := sigdelset (allmask'Access, Signal (J));
328 pragma Assert (Result = 0);
329 end if;
330 end loop;
332 -- The Keep_Unmasked signals should be unmasked for Environment task
334 Result := pthread_sigmask (SIG_UNBLOCK, mask'Unchecked_Access, null);
335 pragma Assert (Result = 0);
337 -- Get the signal mask of the Environment Task
339 Result := pthread_sigmask (SIG_SETMASK, null, mask'Unchecked_Access);
340 pragma Assert (Result = 0);
342 -- Setup the constants exported
344 Environment_Mask := Interrupt_Mask (mask);
346 All_Tasks_Mask := Interrupt_Mask (allmask);
347 end;
349 end System.Interrupt_Management.Operations;