Back to index

glibc  2.9
sigaction.c
Go to the documentation of this file.
00001 /* POSIX.1 sigaction call for Linux/SPARC64.
00002    Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx) and
00005                 Jakub Jelinek (jj@ultra.linux.cz).
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 #include <string.h>
00023 #include <syscall.h>
00024 #include <sysdep.h>
00025 #include <sys/signal.h>
00026 #include <errno.h>
00027 
00028 #include <kernel_sigaction.h>
00029 
00030 /* SPARC 64bit userland requires a kernel that has rt signals anyway. */
00031 
00032 static void __rt_sigreturn_stub (void);
00033 
00034 int
00035 __libc_sigaction (int sig, __const struct sigaction *act,
00036                 struct sigaction *oact)
00037 {
00038   int ret;
00039   struct kernel_sigaction kact, koact;
00040   unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8;
00041 
00042   if (act)
00043     {
00044       kact.k_sa_handler = act->sa_handler;
00045       memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
00046       kact.sa_flags = act->sa_flags;
00047       kact.sa_restorer = NULL;
00048     }
00049 
00050   /* XXX The size argument hopefully will have to be changed to the
00051      real size of the user-level sigset_t.  */
00052   ret = INLINE_SYSCALL (rt_sigaction, 5, sig,
00053                      act ? __ptrvalue (&kact) : 0,
00054                      oact ? __ptrvalue (&koact) : 0, stub, _NSIG / 8);
00055 
00056   if (oact && ret >= 0)
00057     {
00058       oact->sa_handler = koact.k_sa_handler;
00059       memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
00060       oact->sa_flags = koact.sa_flags;
00061       oact->sa_restorer = koact.sa_restorer;
00062     }
00063 
00064   return ret;
00065 }
00066 libc_hidden_def (__libc_sigaction)
00067 
00068 #ifdef WRAPPER_INCLUDE
00069 # include WRAPPER_INCLUDE
00070 #endif
00071 
00072 #ifndef LIBC_SIGACTION
00073 weak_alias (__libc_sigaction, __sigaction);
00074 libc_hidden_weak (__sigaction)
00075 weak_alias (__libc_sigaction, sigaction);
00076 #endif
00077 
00078 static void
00079 __rt_sigreturn_stub (void)
00080 {
00081   __asm__ ("mov %0, %%g1\n\t"
00082           "ta 0x6d\n\t"
00083           : /* no outputs */
00084           : "i" (__NR_rt_sigreturn));
00085 }