OSDN Git Service

0976e827c66f37a9f972baff425a6507c3eeeec1
[uclinux-h8/uClibc.git] / libc / signal / sigaction.c
1 /* Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <errno.h>
20 #include <signal.h>
21 #include <string.h>
22
23 #include <sys/syscall.h>
24
25
26 /* The difference here is that the sigaction structure used in the
27    kernel is not the same as we use in the libc.  Therefore we must
28    translate it here.  */
29 #include <bits/kernel_sigaction.h>
30
31 #if defined __NR_rt_sigaction
32
33 /* If ACT is not NULL, change the action for SIG to *ACT.
34    If OACT is not NULL, put the old action for SIG in *OACT.  */
35 int attribute_hidden
36 __sigaction_internal (int sig, const struct sigaction *act, struct sigaction *oact)
37 {
38         int result;
39         struct kernel_sigaction kact, koact;
40
41         if (act) {
42                 kact.k_sa_handler = act->sa_handler;
43                 __memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
44                 kact.sa_flags = act->sa_flags;
45 # ifdef HAVE_SA_RESTORER
46                 kact.sa_restorer = act->sa_restorer;
47 # endif
48         }
49         
50         /* XXX The size argument hopefully will have to be changed to the
51            real size of the user-level sigset_t.  */
52         result = __syscall_rt_sigaction(sig,
53                                act ? __ptrvalue (&kact) : NULL,
54                                oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
55
56         if (oact && result >= 0) {
57                 oact->sa_handler = koact.k_sa_handler;
58                 __memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask));
59                 oact->sa_flags = koact.sa_flags;
60 # ifdef HAVE_SA_RESTORER
61                 oact->sa_restorer = koact.sa_restorer;
62 # endif
63         }
64
65         return result;
66 }
67
68 #else
69
70 /* If ACT is not NULL, change the action for SIG to *ACT.
71    If OACT is not NULL, put the old action for SIG in *OACT.  */
72 int attribute_hidden
73 __sigaction_internal (int sig, const struct sigaction *act, struct sigaction *oact)
74 {
75         int result;
76         struct old_kernel_sigaction kact, koact;
77
78         if (act) {
79                 kact.k_sa_handler = act->sa_handler;
80                 kact.sa_mask = act->sa_mask.__val[0];
81                 kact.sa_flags = act->sa_flags;
82 # ifdef HAVE_SA_RESTORER
83                 kact.sa_restorer = act->sa_restorer;
84 # endif
85         }
86
87         result = __syscall_sigaction(sig,
88                                act ? __ptrvalue (&kact) : NULL,
89                                oact ? __ptrvalue (&koact) : NULL);
90
91         if (oact && result >= 0) {
92                 oact->sa_handler = koact.k_sa_handler;
93                 oact->sa_mask.__val[0] = koact.sa_mask;
94                 oact->sa_flags = koact.sa_flags;
95 # ifdef HAVE_SA_RESTORER
96                 oact->sa_restorer = koact.sa_restorer;
97 # endif
98         }
99
100         return result;
101 }
102
103 #endif
104
105 strong_alias(__sigaction_internal,__libc_sigaction)
106 weak_alias(__sigaction_internal,__sigaction)
107 weak_alias(__sigaction_internal,sigaction)