diff options
Diffstat (limited to 'libc/sysdeps/linux/sparc')
| -rw-r--r-- | libc/sysdeps/linux/sparc/Makefile.arch | 2 | ||||
| -rw-r--r-- | libc/sysdeps/linux/sparc/sigaction.c | 94 | 
2 files changed, 95 insertions, 1 deletions
| diff --git a/libc/sysdeps/linux/sparc/Makefile.arch b/libc/sysdeps/linux/sparc/Makefile.arch index 4562eaba5..346f13fe7 100644 --- a/libc/sysdeps/linux/sparc/Makefile.arch +++ b/libc/sysdeps/linux/sparc/Makefile.arch @@ -5,7 +5,7 @@  # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.  # -CSRC := brk.c __syscall_error.c qp_ops.c +CSRC := brk.c __syscall_error.c qp_ops.c sigaction.c  SSRC := \  	__longjmp.S fork.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ diff --git a/libc/sysdeps/linux/sparc/sigaction.c b/libc/sysdeps/linux/sparc/sigaction.c new file mode 100644 index 000000000..9dee63b6c --- /dev/null +++ b/libc/sysdeps/linux/sparc/sigaction.c @@ -0,0 +1,94 @@ +/* POSIX.1 sigaction call for Linux/SPARC. +   Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx), 1997. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA. + +       Ported to uClibc from glibc: 090520: +               Jan Buchholz, KIP, Uni Heidelberg <jan.buchholz@kip.uni-heidelberg.de> +               Austin Foxley, Ceton Corporation <austinf@cetoncorp.com> +*/ + +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <sys/syscall.h> +#include <bits/kernel_sigaction.h> + + +_syscall5(int, rt_sigaction, int, a, int, b, int, c, int, d, int, e); +static void __rt_sigreturn_stub (void); +static void __sigreturn_stub (void); + +int +__libc_sigaction (int sig, __const struct sigaction *act, struct sigaction *oact) +{ +    int ret; +	struct old_kernel_sigaction kact, koact; +    unsigned long stub = 0; +    int saved_errno = errno; +     +    if (act) +    { +        kact.k_sa_handler = act->sa_handler; +        memcpy (&kact.sa_mask, &act->sa_mask, sizeof(sigset_t)); +        if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO)!= 0) +            stub = (unsigned long) &__rt_sigreturn_stub; +        else +            stub = (unsigned long) &__sigreturn_stub; +        stub -= 8; +        kact.sa_restorer = NULL; +    } +    /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t.  */ +    ret = rt_sigaction(sig, act ? &kact : NULL, oact ? &koact : NULL, stub, _NSIG / 8); + +    if (ret >= 0 || errno != ENOSYS) +    { +        if (oact && ret >= 0) +        { +            oact->sa_handler = koact.k_sa_handler; +            memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); +            oact->sa_flags = koact.sa_flags; +            oact->sa_restorer = koact.sa_restorer; +        } +        return ret; +    } +    __set_errno (saved_errno); +    return -1; +} + +#ifndef LIBC_SIGACTION +weak_alias(__libc_sigaction,sigaction) +libc_hidden_weak(sigaction) +#endif + +static void +__rt_sigreturn_stub (void) +{ +  __asm__ ("mov %0, %%g1\n\t" +          "ta  0x10\n\t" +          : /* no outputs */ +          : "i" (__NR_rt_sigreturn)); +} +static void +__sigreturn_stub (void) +{ +  __asm__ ("mov %0, %%g1\n\t" +          "ta  0x10\n\t" +          : /* no outputs */ +          : "i" (__NR_sigreturn)); +} | 
