diff options
Diffstat (limited to 'newlib/libc/sys/linux')
-rw-r--r-- | newlib/libc/sys/linux/Makefile.am | 6 | ||||
-rw-r--r-- | newlib/libc/sys/linux/Makefile.in | 23 | ||||
-rw-r--r-- | newlib/libc/sys/linux/ids.c | 2 | ||||
-rw-r--r-- | newlib/libc/sys/linux/kernel_sigaction.h | 19 | ||||
-rw-r--r-- | newlib/libc/sys/linux/machine/i386/Makefile.am | 2 | ||||
-rw-r--r-- | newlib/libc/sys/linux/machine/i386/Makefile.in | 7 | ||||
-rw-r--r-- | newlib/libc/sys/linux/machine/i386/sigaction.c | 114 | ||||
-rw-r--r-- | newlib/libc/sys/linux/sigaction.c | 77 | ||||
-rw-r--r-- | newlib/libc/sys/linux/signal.c | 35 | ||||
-rw-r--r-- | newlib/libc/sys/linux/sigqueue.c | 56 | ||||
-rw-r--r-- | newlib/libc/sys/linux/sigwait.c | 93 | ||||
-rw-r--r-- | newlib/libc/sys/linux/sys/signal.h | 2 |
12 files changed, 406 insertions, 30 deletions
diff --git a/newlib/libc/sys/linux/Makefile.am b/newlib/libc/sys/linux/Makefile.am index 285baaf46..ce08ba569 100644 --- a/newlib/libc/sys/linux/Makefile.am +++ b/newlib/libc/sys/linux/Makefile.am @@ -14,9 +14,9 @@ LIB_SOURCES = \ getreent.c ids.c inode.c io.c io64.c linux.c mmap.c \ pread.c pread64.c process.c pwrite.c pwrite64.c raise.c realpath.c \ rename.c resource.c sched.c select.c seteuid.c shm_open.c \ - shm_unlink.c signal.c siglongjmp.c socket.c sleep.c stack.c \ - sysconf.c sysctl.c systat.c system.c tcdrain.c tcsendbrk.c termios.c \ - time.c usleep.c wait.c + shm_unlink.c sigaction.c sigqueue.c signal.c siglongjmp.c sigwait.c \ + socket.c sleep.c stack.c sysconf.c sysctl.c systat.c system.c \ + tcdrain.c tcsendbrk.c termios.c time.c usleep.c wait.c # This will handle both /usr/src/linux-2.4/include/asm/signal.h (in Red Hat Linux 7.1) # and also /usr/src/linux/include/asm/signal.h in older versions of Red Hat Linux diff --git a/newlib/libc/sys/linux/Makefile.in b/newlib/libc/sys/linux/Makefile.in index da20d1bb6..81bd8242a 100644 --- a/newlib/libc/sys/linux/Makefile.in +++ b/newlib/libc/sys/linux/Makefile.in @@ -105,9 +105,9 @@ LIB_SOURCES = \ getreent.c ids.c inode.c io.c io64.c linux.c mmap.c \ pread.c pread64.c process.c pwrite.c pwrite64.c raise.c realpath.c \ rename.c resource.c sched.c select.c seteuid.c shm_open.c \ - shm_unlink.c signal.c siglongjmp.c socket.c sleep.c stack.c \ - sysconf.c sysctl.c systat.c system.c tcdrain.c tcsendbrk.c termios.c \ - time.c usleep.c wait.c + shm_unlink.c sigaction.c sigqueue.c signal.c siglongjmp.c sigwait.c \ + socket.c sleep.c stack.c sysconf.c sysctl.c systat.c system.c \ + tcdrain.c tcsendbrk.c termios.c time.c usleep.c wait.c # This will handle both /usr/src/linux-2.4/include/asm/signal.h (in Red Hat Linux 7.1) @@ -142,10 +142,11 @@ LIBS = @LIBS@ @USE_LIBTOOL_FALSE@ids.o inode.o io.o io64.o linux.o mmap.o pread.o \ @USE_LIBTOOL_FALSE@pread64.o process.o pwrite.o pwrite64.o raise.o \ @USE_LIBTOOL_FALSE@realpath.o rename.o resource.o sched.o select.o \ -@USE_LIBTOOL_FALSE@seteuid.o shm_open.o shm_unlink.o signal.o \ -@USE_LIBTOOL_FALSE@siglongjmp.o socket.o sleep.o stack.o sysconf.o \ -@USE_LIBTOOL_FALSE@sysctl.o systat.o system.o tcdrain.o tcsendbrk.o \ -@USE_LIBTOOL_FALSE@termios.o time.o usleep.o wait.o +@USE_LIBTOOL_FALSE@seteuid.o shm_open.o shm_unlink.o sigaction.o \ +@USE_LIBTOOL_FALSE@sigqueue.o signal.o siglongjmp.o sigwait.o socket.o \ +@USE_LIBTOOL_FALSE@sleep.o stack.o sysconf.o sysctl.o systat.o system.o \ +@USE_LIBTOOL_FALSE@tcdrain.o tcsendbrk.o termios.o time.o usleep.o \ +@USE_LIBTOOL_FALSE@wait.o LTLIBRARIES = $(noinst_LTLIBRARIES) @USE_LIBTOOL_TRUE@liblinux_la_DEPENDENCIES = @@ -155,10 +156,10 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) @USE_LIBTOOL_TRUE@mmap.lo pread.lo pread64.lo process.lo pwrite.lo \ @USE_LIBTOOL_TRUE@pwrite64.lo raise.lo realpath.lo rename.lo \ @USE_LIBTOOL_TRUE@resource.lo sched.lo select.lo seteuid.lo shm_open.lo \ -@USE_LIBTOOL_TRUE@shm_unlink.lo signal.lo siglongjmp.lo socket.lo \ -@USE_LIBTOOL_TRUE@sleep.lo stack.lo sysconf.lo sysctl.lo systat.lo \ -@USE_LIBTOOL_TRUE@system.lo tcdrain.lo tcsendbrk.lo termios.lo time.lo \ -@USE_LIBTOOL_TRUE@usleep.lo wait.lo +@USE_LIBTOOL_TRUE@shm_unlink.lo sigaction.lo sigqueue.lo signal.lo \ +@USE_LIBTOOL_TRUE@siglongjmp.lo sigwait.lo socket.lo sleep.lo stack.lo \ +@USE_LIBTOOL_TRUE@sysconf.lo sysctl.lo systat.lo system.lo tcdrain.lo \ +@USE_LIBTOOL_TRUE@tcsendbrk.lo termios.lo time.lo usleep.lo wait.lo CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) diff --git a/newlib/libc/sys/linux/ids.c b/newlib/libc/sys/linux/ids.c index 592d97de2..332ebe2c9 100644 --- a/newlib/libc/sys/linux/ids.c +++ b/newlib/libc/sys/linux/ids.c @@ -19,3 +19,5 @@ _syscall0(gid_t,getegid) _syscall3(int,setresuid,uid_t,ruid,uid_t,euid,uid_t,suid) _syscall2(int,getgroups,int,size,gid_t *,list) _syscall3(int,syslog,int,type,char *,bufp,int,len) + +weak_alias(__libc_getuid,__getuid); diff --git a/newlib/libc/sys/linux/kernel_sigaction.h b/newlib/libc/sys/linux/kernel_sigaction.h new file mode 100644 index 000000000..d005cbce9 --- /dev/null +++ b/newlib/libc/sys/linux/kernel_sigaction.h @@ -0,0 +1,19 @@ +/* This is the sigaction structure from the Linux 2.1.20 kernel. */ + +#define HAVE_SA_RESTORER + +struct old_kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +/* This is the sigaction structure from the Linux 2.1.68 kernel. */ + +struct kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_flags; + void (*sa_restorer) (void); + sigset_t sa_mask; +}; diff --git a/newlib/libc/sys/linux/machine/i386/Makefile.am b/newlib/libc/sys/linux/machine/i386/Makefile.am index a3ceef50a..dbf819cca 100644 --- a/newlib/libc/sys/linux/machine/i386/Makefile.am +++ b/newlib/libc/sys/linux/machine/i386/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -LIB_SOURCES = setjmp.S sigset.c +LIB_SOURCES = setjmp.S sigaction.c sigset.c liblinuxi386_la_LDFLAGS = -Xcompiler -nostdlib diff --git a/newlib/libc/sys/linux/machine/i386/Makefile.in b/newlib/libc/sys/linux/machine/i386/Makefile.in index a167b9b63..cfbb3ccf6 100644 --- a/newlib/libc/sys/linux/machine/i386/Makefile.in +++ b/newlib/libc/sys/linux/machine/i386/Makefile.in @@ -92,7 +92,7 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -LIB_SOURCES = setjmp.S sigset.c +LIB_SOURCES = setjmp.S sigaction.c sigset.c liblinuxi386_la_LDFLAGS = -Xcompiler -nostdlib @@ -116,11 +116,12 @@ DEFS = @DEFS@ -I. -I$(srcdir) CPPFLAGS = @CPPFLAGS@ LIBS = @LIBS@ lib_a_LIBADD = -@USE_LIBTOOL_FALSE@lib_a_OBJECTS = setjmp.o sigset.o +@USE_LIBTOOL_FALSE@lib_a_OBJECTS = setjmp.o sigaction.o sigset.o LTLIBRARIES = $(noinst_LTLIBRARIES) liblinuxi386_la_LIBADD = -@USE_LIBTOOL_TRUE@liblinuxi386_la_OBJECTS = setjmp.lo sigset.lo +@USE_LIBTOOL_TRUE@liblinuxi386_la_OBJECTS = setjmp.lo sigaction.lo \ +@USE_LIBTOOL_TRUE@sigset.lo CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) diff --git a/newlib/libc/sys/linux/machine/i386/sigaction.c b/newlib/libc/sys/linux/machine/i386/sigaction.c new file mode 100644 index 000000000..6edcb0ae7 --- /dev/null +++ b/newlib/libc/sys/linux/machine/i386/sigaction.c @@ -0,0 +1,114 @@ +/* POSIX.1 `sigaction' call for Linux/i386. + Copyright (C) 1991, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#include <errno.h> +#include <stddef.h> +#include <signal.h> +#include <string.h> + +#include <machine/syscall.h> + +/* The difference here is that the sigaction structure used in the + kernel is not the same as we use in the libc. Therefore we must + translate it here. */ +#include <kernel_sigaction.h> + +/* We do not globally define the SA_RESTORER flag so do it here. */ +#define SA_RESTORER 0x04000000 + +#define __NR___rt_sigaction __NR_rt_sigaction + +static _syscall4(int,__rt_sigaction,int,sig,const struct kernel_sigaction *,act, + struct kernel_sigaction *,oact,size_t,size) + +static void restore_rt (void) asm ("__restore_rt"); +static void restore (void) asm ("__restore"); + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +{ + int result; + struct kernel_sigaction kact, koact; + + if (act) + { + kact.k_sa_handler = act->sa_handler; + memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); + kact.sa_flags = act->sa_flags | SA_RESTORER; + + kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) + ? &restore_rt : &restore); + } + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + result = __rt_sigaction(sig, act ? (&kact) : NULL, + oact ? (&koact) : NULL, _NSIG / 8); + + if (oact && result >= 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 result; +} + +weak_alias (__libc_sigaction, __sigaction) +weak_alias (__libc_sigaction, sigaction) + +/* NOTE: Please think twice before making any changes to the bits of + code below. GDB needs some intimate knowledge about it to + recognize them as signal trampolines, and make backtraces through + signal handlers work right. Important are both the names + (__restore and __restore_rt) and the exact instruction sequence. + If you ever feel the need to make any changes, please notify the + appropriate GDB maintainer. */ + +#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE2(name, syscall) \ +asm \ + ( \ + ".text\n" \ + " .align 16\n" \ + "__" #name ":\n" \ + " movl $" #syscall ", %eax\n" \ + " int $0x80" \ + ); + +/* The return code for realtime-signals. */ +RESTORE (restore_rt, __NR_rt_sigreturn) + +/* For the boring old signals. */ +# undef RESTORE2 +# define RESTORE2(name, syscall) \ +asm \ + ( \ + ".text\n" \ + " .align 8\n" \ + "__" #name ":\n" \ + " popl %eax\n" \ + " movl $" #syscall ", %eax\n" \ + " int $0x80" \ + ); + +RESTORE (restore, __NR_sigreturn) diff --git a/newlib/libc/sys/linux/sigaction.c b/newlib/libc/sys/linux/sigaction.c new file mode 100644 index 000000000..a70950276 --- /dev/null +++ b/newlib/libc/sys/linux/sigaction.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* Modified 05/30/02 by Jeff Johnston, Red Hat Inc. */ + +#include <errno.h> +#include <signal.h> +#include <string.h> + +#include <machine/syscall.h> + +/* The difference here is that the sigaction structure used in the + kernel is not the same as we use in the libc. Therefore we must + translate it here. */ +#include <kernel_sigaction.h> + +#define __NR___rt_sigaction __NR_rt_sigaction + +static _syscall4(int,__rt_sigaction,int,sig, + const struct kernel_sigaction *,act, + struct kernel_sigaction *,oact,size_t,size); + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +__libc_sigaction (sig, act, oact) + int sig; + const struct sigaction *act; + struct sigaction *oact; +{ + int result; + struct kernel_sigaction kact, koact; + /* Save the current error value for later. We need not do this + if we are guaranteed to have realtime signals. */ + + if (act) + { + kact.k_sa_handler = act->sa_handler; + memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); + kact.sa_flags = act->sa_flags; + kact.sa_restorer = act->sa_restorer; + } + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + result = __rt_sigaction (sig, + act ? (&kact) : NULL, + oact ? (&koact) : NULL, _NSIG / 8); + + if (oact && result >= 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 result; +} + +weak_alias (__libc_sigaction, __sigaction) +weak_alias (__libc_sigaction, sigaction) diff --git a/newlib/libc/sys/linux/signal.c b/newlib/libc/sys/linux/signal.c index 0855ed9e0..1affe6f24 100644 --- a/newlib/libc/sys/linux/signal.c +++ b/newlib/libc/sys/linux/signal.c @@ -11,40 +11,39 @@ /* avoid name space pollution */ #define __NR___sgetmask __NR_sgetmask #define __NR___ssetmask __NR_ssetmask -#define __NR___sigsuspend __NR_sigsuspend #define __NR___rt_sigtimedwait __NR_rt_sigtimedwait +#define __NR___rt_sigpending __NR_rt_sigpending +#define __NR___rt_sigprocmask __NR_rt_sigprocmask +#define __NR___rt_sigsuspend __NR_rt_sigsuspend _syscall2(int,kill,pid_t,pid,int,sig) _syscall2(__sighandler_t,signal,int,signum,__sighandler_t,handler) -_syscall3(int,sigaction,int,signum,const struct sigaction *,act, - struct sigaction *,oldact) -_syscall1(int,sigpending,sigset_t *,set) _syscall0(int,pause) _syscall1(unsigned int,alarm,unsigned int,seconds) -_syscall3(int,sigprocmask,int,how,const sigset_t *,set,sigset_t *,oldset) static _syscall0(int,__sgetmask) static _syscall1(int,__ssetmask,int,newmask) -static _syscall3(int,__sigsuspend,int,arg1,int,arg2,int,mask) +static _syscall2(int,__rt_sigpending,sigset_t *,set,size_t,size) +static _syscall4(int,__rt_sigprocmask,int,how,const sigset_t *,set,sigset_t *,oldset,size_t,size) +static _syscall2(int,__rt_sigsuspend,const sigset_t *,mask,size_t,size) static _syscall4(int,__rt_sigtimedwait,const sigset_t *,set,siginfo_t *,info,struct timespec *,timeout,size_t,size) -int sigsuspend (const sigset_t *mask) +int __sigsuspend (const sigset_t *mask) { - return __sigsuspend(0,0,((__sigset_t *)mask)->__val[0]); + return __rt_sigsuspend(mask, _NSIG/8); } +weak_alias(__sigsuspend,sigsuspend) int sigsetmask(int newmask) /* BSD */ { return __ssetmask(newmask); } - int sigmask(int signum) /* BSD */ { return 1 << signum; } - int sigblock(int mask) /* BSD */ { return __ssetmask(mask | __sgetmask()); @@ -56,15 +55,27 @@ int __libc_raise(int sig) } weak_alias(__libc_raise,raise) +int __sigpending(sigset_t *set) +{ + return __rt_sigpending(set, _NSIG/8); +} +weak_alias(__sigpending,sigpending) + +int __sigprocmask (int how,const sigset_t *set,sigset_t *oldset) +{ + return __rt_sigprocmask(how, set, oldset, _NSIG/8); +} +weak_alias(__sigprocmask,sigprocmask) + int sigtimedwait(const sigset_t *set, siginfo_t *info, struct timespec *timeout) { - return __rt_sigtimedwait(set, info, timeout, sizeof(sigset_t)); + return __rt_sigtimedwait(set, info, timeout, _NSIG/8); } int sigwaitinfo(const sigset_t *set, siginfo_t *info) { - return __rt_sigtimedwait(set, info, NULL, sizeof(sigset_t)); + return __rt_sigtimedwait(set, info, NULL, _NSIG/8); } const char *const sys_siglist[] = { diff --git a/newlib/libc/sys/linux/sigqueue.c b/newlib/libc/sys/linux/sigqueue.c new file mode 100644 index 000000000..60c4fed20 --- /dev/null +++ b/newlib/libc/sys/linux/sigqueue.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* Modified for newlib by Jeff Johnston, May 30, 2002 */ + +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> + +#include <machine/syscall.h> + +#define __NR___rt_sigqueueinfo __NR_rt_sigqueueinfo + +extern uid_t __getuid(); +extern pid_t __getpid(); + +static _syscall3(int,__rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,info) + +/* Return any pending signal or wait for one for the given time. */ +int +__sigqueue (pid, sig, val) + pid_t pid; + int sig; + const union sigval val; +{ + siginfo_t info; + + /* First, clear the siginfo_t structure, so that we don't pass our + stack content to other tasks. */ + memset (&info, 0, sizeof (siginfo_t)); + /* We must pass the information about the data in a siginfo_t value. */ + info.si_signo = sig; + info.si_code = SI_QUEUE; + info.si_pid = __getpid (); + info.si_uid = __getuid (); + info.si_value = val; + + return __rt_sigqueueinfo(pid, sig, &info); +} +weak_alias (__sigqueue, sigqueue) diff --git a/newlib/libc/sys/linux/sigwait.c b/newlib/libc/sys/linux/sigwait.c new file mode 100644 index 000000000..09a4190e7 --- /dev/null +++ b/newlib/libc/sys/linux/sigwait.c @@ -0,0 +1,93 @@ +/* Implementation of sigwait function from POSIX.1c. + Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + 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. */ + +#include <errno.h> +#include <signal.h> +#include <stddef.h> /* For NULL. */ + +#include <machine/weakalias.h> + +/* This is our dummy signal handler we use here. */ +static void ignore_signal (int sig); + +/* Place where to remember which signal we got. Please note that this + implementation cannot be used for the threaded libc. The + libpthread must provide an own version. */ +static int was_sig; + + +int +__sigwait (const sigset_t *set, int *sig) +{ + sigset_t tmp_mask; + struct sigaction saved[NSIG]; + struct sigaction action; + int save_errno; + int this; + + /* Prepare set. */ + sigfillset (&tmp_mask); + + /* Unblock all signals in the SET and register our nice handler. */ + action.sa_handler = ignore_signal; + action.sa_flags = 0; + sigfillset (&action.sa_mask); /* Block all signals for handler. */ + + /* Make sure we recognize error conditions by setting WAS_SIG to a + value which does not describe a legal signal number. */ + was_sig = -1; + + for (this = 1; this < NSIG; ++this) + if (sigismember (set, this)) + { + /* Unblock this signal. */ + sigdelset (&tmp_mask, this); + + /* Register temporary action handler. */ + if (__sigaction (this, &action, &saved[this]) != 0) + goto restore_handler; + } + + /* Now we can wait for signals. */ + __sigsuspend (&tmp_mask); + + restore_handler: + save_errno = errno; + + while (--this >= 1) + if (sigismember (set, this)) + /* We ignore errors here since we must restore all handlers. */ + __sigaction (this, &saved[this], NULL); + + errno = (save_errno); + + /* Store the result and return. */ + *sig = was_sig; + return was_sig == -1 ? -1 : 0; +} +weak_alias (__sigwait, sigwait) + + +static void +ignore_signal (int sig) +{ + /* Remember the signal. */ + was_sig = sig; +} diff --git a/newlib/libc/sys/linux/sys/signal.h b/newlib/libc/sys/linux/sys/signal.h index 49a661d09..95b561d41 100644 --- a/newlib/libc/sys/linux/sys/signal.h +++ b/newlib/libc/sys/linux/sys/signal.h @@ -9,6 +9,8 @@ #include <sys/types.h> #include <linux/signal.h> #include <bits/sigset.h> +#define _SIGNAL_H +#include <bits/signum.h> /* --- include/signal.h thinks it knows better :-( --- */ |