diff --git a/ChangeLog b/ChangeLog index c8bf7838a4..ccdf3e7873 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2014-11-14 Roland McGrath + + * signal/signal.h [__USE_MISC] + (struct sigvec): Remove type. + (SV_ONSTACK, SV_INTERRUPT, SV_RESETHAND): Remove macros. + (sigvec): Remove declaration. + * sysdeps/posix/sigvec.c: Moved ... + * signal/sigvec.c: ... here, replacing old file. + (struct sigvec): New type, copied from old signal.h definition. + (SV_ONSTACK, SV_INTERRUPT, SV_RESETHAND): New macros, likewise copied. + (__sigvec): Convert definition to prototype. + (sigvec): Replace weak_alias with compat_symbol. + * signal/Versions (libc: GLIBC_2.21): New version set. + * include/signal.h: Remove __sigvec declaration. + * sysdeps/unix/bsd/sigvec.c: Remove file. + * sysdeps/unix/bsd/syscalls.list: Remove sigvec. + * manual/signal.texi (BSD Handler): Remove subsection. + Move siginterrupt up to ... + (BSD Signal Handling): ... here. Mark it as XPG rather than BSD. + (Blocking in BSD): Fold subsection into its parent. + * NEWS: Mention sigvec removal. + 2014-11-14 Joseph Myers * sysdeps/x86_64/fpu/dla.h [__FMA4__ && __GNUC_PREREQ (4, 6)] diff --git a/NEWS b/NEWS index 867d659afb..6ad946454a 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,11 @@ Version 2.21 still be used to compile programs using the GNU C Library. * New locales: tu_IN, bh_IN. + +* The obsolete sigvec function has been removed. This was the original + 4.2BSD interface that inspired the POSIX.1 sigaction interface, which + programs have been using instead for about 25 years. Of course, ABI + compatibility for old binaries using sigvec remains intact. Version 2.20 diff --git a/include/signal.h b/include/signal.h index f7a9de01ff..f631a62043 100644 --- a/include/signal.h +++ b/include/signal.h @@ -41,8 +41,6 @@ extern int __sigtimedwait (const sigset_t *__set, siginfo_t *__info, libc_hidden_proto (__sigtimedwait) extern int __sigqueue (__pid_t __pid, int __sig, const union sigval __val); -extern int __sigvec (int __sig, const struct sigvec *__vec, - struct sigvec *__ovec); extern int __sigreturn (struct sigcontext *__scp); extern int __sigaltstack (const struct sigaltstack *__ss, struct sigaltstack *__oss); diff --git a/manual/signal.texi b/manual/signal.texi index ac84c5ec66..3ed05c7c1a 100644 --- a/manual/signal.texi +++ b/manual/signal.texi @@ -3306,101 +3306,15 @@ BSD Unix. There are many similarities between the BSD and POSIX signal handling facilities, because the POSIX facilities were inspired by the BSD facilities. Besides having different names for all the functions to -avoid conflicts, the main differences between the two are: - -@itemize @bullet -@item -BSD Unix represents signal masks as an @code{int} bit mask, rather than -as a @code{sigset_t} object. - -@item -The BSD facilities use a different default for whether an interrupted -primitive should fail or resume. The POSIX facilities make system -calls fail unless you specify that they should resume. With the BSD -facility, the default is to make system calls resume unless you say they -should fail. @xref{Interrupted Primitives}. -@end itemize +avoid conflicts, the main difference between the two is that BSD Unix +represents signal masks as an @code{int} bit mask, rather than as a +@code{sigset_t} object. The BSD facilities are declared in @file{signal.h}. @pindex signal.h -@menu -* BSD Handler:: BSD Function to Establish a Handler. -* Blocking in BSD:: BSD Functions for Blocking Signals. -@end menu - -@node BSD Handler -@subsection BSD Function to Establish a Handler - @comment signal.h -@comment BSD -@deftp {Data Type} {struct sigvec} -This data type is the BSD equivalent of @code{struct sigaction} -(@pxref{Advanced Signal Handling}); it is used to specify signal actions -to the @code{sigvec} function. It contains the following members: - -@table @code -@item sighandler_t sv_handler -This is the handler function. - -@item int sv_mask -This is the mask of additional signals to be blocked while the handler -function is being called. - -@item int sv_flags -This is a bit mask used to specify various flags which affect the -behavior of the signal. You can also refer to this field as -@code{sv_onstack}. -@end table -@end deftp - -These symbolic constants can be used to provide values for the -@code{sv_flags} field of a @code{sigvec} structure. This field is a bit -mask value, so you bitwise-OR the flags of interest to you together. - -@comment signal.h -@comment BSD -@deftypevr Macro int SV_ONSTACK -If this bit is set in the @code{sv_flags} field of a @code{sigvec} -structure, it means to use the signal stack when delivering the signal. -@end deftypevr - -@comment signal.h -@comment BSD -@deftypevr Macro int SV_INTERRUPT -If this bit is set in the @code{sv_flags} field of a @code{sigvec} -structure, it means that system calls interrupted by this kind of signal -should not be restarted if the handler returns; instead, the system -calls should return with a @code{EINTR} error status. @xref{Interrupted -Primitives}. -@end deftypevr - -@comment signal.h -@comment Sun -@deftypevr Macro int SV_RESETHAND -If this bit is set in the @code{sv_flags} field of a @code{sigvec} -structure, it means to reset the action for the signal back to -@code{SIG_DFL} when the signal is received. -@end deftypevr - -@comment signal.h -@comment BSD -@deftypefun int sigvec (int @var{signum}, const struct sigvec *@var{action}, struct sigvec *@var{old-action}) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -@c This is mostly a safe wrapper for sigaction. The exception are -@c systems that lack SA_RESETHAND, in which a signal handler wrapper is -@c used that calls sigaction to reset the handler before calling the -@c user-supplied handler; it's unlikely that this emulation is used -@c anywhere, for user-supplied flags and mask don't seem to be used -@c the way one would expect. -This function is the equivalent of @code{sigaction} (@pxref{Advanced Signal -Handling}); it installs the action @var{action} for the signal @var{signum}, -returning information about the previous action in effect for that signal -in @var{old-action}. -@end deftypefun - -@comment signal.h -@comment BSD +@comment XPG @deftypefun int siginterrupt (int @var{signum}, int @var{failflag}) @safety{@prelim{}@mtunsafe{@mtasuconst{:@mtssigintr{}}}@asunsafe{}@acunsafe{@acucorrupt{}}} @c This calls sigaction twice, once to get the current sigaction for the @@ -3417,9 +3331,6 @@ true, handling @var{signum} causes these primitives to fail with error code @code{EINTR}. @xref{Interrupted Primitives}. @end deftypefun -@node Blocking in BSD -@subsection BSD Functions for Blocking Signals - @comment signal.h @comment BSD @deftypefn Macro int sigmask (int @var{signum}) diff --git a/signal/Versions b/signal/Versions index 0217a4089d..4d86930ec6 100644 --- a/signal/Versions +++ b/signal/Versions @@ -49,4 +49,6 @@ libc { # Needed to provide a pointer to the XPG sigpause function. __xpg_sigpause; } + GLIBC_2.21 { + } } diff --git a/signal/signal.h b/signal/signal.h index f1bbad04d3..fd23ad6554 100644 --- a/signal/signal.h +++ b/signal/signal.h @@ -303,30 +303,6 @@ extern int sigqueue (__pid_t __pid, int __sig, const union sigval __val) extern const char *const _sys_siglist[_NSIG]; extern const char *const sys_siglist[_NSIG]; -/* Structure passed to `sigvec'. */ -struct sigvec - { - __sighandler_t sv_handler; /* Signal handler. */ - int sv_mask; /* Mask of signals to be blocked. */ - - int sv_flags; /* Flags (see below). */ -# define sv_onstack sv_flags /* 4.2 BSD compatibility. */ - }; - -/* Bits in `sv_flags'. */ -# define SV_ONSTACK (1 << 0)/* Take the signal on the signal stack. */ -# define SV_INTERRUPT (1 << 1)/* Do not restart system calls. */ -# define SV_RESETHAND (1 << 2)/* Reset handler to SIG_DFL on receipt. */ - - -/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member - of VEC. The signals in `sv_mask' will be blocked while the handler runs. - If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be - reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, - it is filled in with the old information for SIG. */ -extern int sigvec (int __sig, const struct sigvec *__vec, - struct sigvec *__ovec) __THROW; - /* Get machine-dependent `struct sigcontext' and signal subcodes. */ # include diff --git a/signal/sigvec.c b/signal/sigvec.c index e3ffb281a8..d4921536e9 100644 --- a/signal/sigvec.c +++ b/signal/sigvec.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* ABI compatibility for obsolete sigvec function from 4.2BSD. + Copyright (C) 1991-2014 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 @@ -15,8 +16,47 @@ License along with the GNU C Library; if not, see . */ -#include -#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_21) + +# include +# include +# include + + +/* These are the struct sigvec and SV_* bit definitions that + used to be in . The whole interface now exists + solely for ABI compatibility, so it can just be here. */ +struct sigvec + { + __sighandler_t sv_handler; /* Signal handler. */ + int sv_mask; /* Mask of signals to be blocked. */ + + int sv_flags; /* Flags (see below). */ + }; +# define SV_ONSTACK (1 << 0)/* Take the signal on the signal stack. */ +# define SV_INTERRUPT (1 << 1)/* Do not restart system calls. */ +# define SV_RESETHAND (1 << 2)/* Reset handler to SIG_DFL on receipt. */ + + +/* Include macros to convert between `sigset_t' and old-style mask. */ +# include + +# ifndef SA_RESETHAND +/* When sigaction lacks the extension bit for it, + we use a wrapper handler to support SV_RESETHAND. */ +struct sigvec_wrapper_data +{ + __sighandler_t sw_handler; + unsigned int sw_mask; +}; + +static void sigvec_wrapper_handler (int sig) __THROW; + +static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG]; +# endif + /* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member of VEC. The signals in `sv_mask' will be blocked while the handler runs. @@ -24,14 +64,140 @@ reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, it is filled in with the old information for SIG. */ int -__sigvec (sig, vec, ovec) - int sig; - const struct sigvec *vec; - struct sigvec *ovec; +__sigvec (int sig, + const struct sigvec *vec, + struct sigvec *ovec) { - __set_errno (ENOSYS); - return -1; -} -stub_warning (sigvec) + struct sigaction old; -weak_alias (__sigvec, sigvec) +# ifndef SA_RESETHAND + if (vec == NULL || !(vec->sv_flags & SV_RESETHAND)) +# endif + { + struct sigaction new, *n; + + if (vec == NULL) + n = NULL; + else + { + __sighandler_t handler; + unsigned int mask; + unsigned int sv_flags; + unsigned int sa_flags; + + handler = vec->sv_handler; + mask = vec->sv_mask; + sv_flags = vec->sv_flags; + sa_flags = 0; + if (sv_flags & SV_ONSTACK) + { +# ifdef SA_ONSTACK + sa_flags |= SA_ONSTACK; +# else + __set_errno (ENOSYS); + return -1; +# endif + } +# ifdef SA_RESTART + if (!(sv_flags & SV_INTERRUPT)) + sa_flags |= SA_RESTART; +# endif +# ifdef SA_RESETHAND + if (sv_flags & SV_RESETHAND) + sa_flags |= SA_RESETHAND; +# endif + n = &new; + new.sa_handler = handler; + if (sigset_set_old_mask (&new.sa_mask, mask) < 0) + return -1; + new.sa_flags = sa_flags; + } + + if (__sigaction (sig, n, &old) < 0) + return -1; + } +# ifndef SA_RESETHAND + else + { + __sighandler_t handler; + unsigned int mask; + struct sigvec_wrapper_data *data; + struct sigaction wrapper; + + handler = vec->sv_handler; + mask = (unsigned int)vec->sv_mask; + data = &sigvec_wrapper_data[sig]; + wrapper.sa_handler = sigvec_wrapper_handler; + /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */ + data->sw_handler = handler; + data->sw_mask = mask; + + if (__sigaction (sig, &wrapper, &old) < 0) + return -1; + } +# endif + + if (ovec != NULL) + { + __sighandler_t handler; + unsigned int sv_flags; + unsigned int sa_flags; + unsigned int mask; + + handler = old.sa_handler; + sv_flags = 0; + sa_flags = old.sa_flags; +# ifndef SA_RESETHAND + if (handler == sigvec_wrapper_handler) + { + handler = sigvec_wrapper_data[sig].sw_handler; + /* should we use data->sw_mask?? */ + sv_flags |= SV_RESETHAND; + } +# else + if (sa_flags & SA_RESETHAND) + sv_flags |= SV_RESETHAND; +# endif + mask = sigset_get_old_mask (&old.sa_mask); +# ifdef SA_ONSTACK + if (sa_flags & SA_ONSTACK) + sv_flags |= SV_ONSTACK; +# endif +# ifdef SA_RESTART + if (!(sa_flags & SA_RESTART)) +# endif + sv_flags |= SV_INTERRUPT; + ovec->sv_handler = handler; + ovec->sv_mask = (int)mask; + ovec->sv_flags = (int)sv_flags; + } + + return 0; +} + +compat_symbol (libc, __sigvec, sigvec, GLIBC_2_0); + +# ifndef SA_RESETHAND +static void +sigvec_wrapper_handler (sig) + int sig; +{ + struct sigvec_wrapper_data *data; + struct sigaction act; + int save; + __sighandler_t handler; + + data = &sigvec_wrapper_data[sig]; + act.sa_handler = SIG_DFL; + act.sa_flags = 0; + sigset_set_old_mask (&act.sa_mask, data->sw_mask); + handler = data->sw_handler; + save = errno; + (void) __sigaction (sig, &act, (struct sigaction *) NULL); + __set_errno (save); + + (*handler) (sig); +} +# endif /* No SA_RESETHAND. */ + +#endif /* SHLIB_COMPAT */ diff --git a/sysdeps/posix/sigvec.c b/sysdeps/posix/sigvec.c deleted file mode 100644 index 83ba75546f..0000000000 --- a/sysdeps/posix/sigvec.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (C) 1991-2014 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, see - . */ - -#include -#include -#include - -/* Include macros to convert between `sigset_t' and old-style mask. */ -#include - -#ifndef SA_RESETHAND -/* When sigaction lacks the extension bit for it, - we use a wrapper handler to support SV_RESETHAND. */ -struct sigvec_wrapper_data -{ - __sighandler_t sw_handler; - unsigned int sw_mask; -}; - -static void sigvec_wrapper_handler (int sig) __THROW; - -static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG]; -#endif - - -/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member - of VEC. The signals in `sv_mask' will be blocked while the handler runs. - If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be - reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, - it is filled in with the old information for SIG. */ -int -__sigvec (sig, vec, ovec) - int sig; - const struct sigvec *vec; - struct sigvec *ovec; -{ - struct sigaction old; - -#ifndef SA_RESETHAND - if (vec == NULL || !(vec->sv_flags & SV_RESETHAND)) -#endif - { - struct sigaction new, *n; - - if (vec == NULL) - n = NULL; - else - { - __sighandler_t handler; - unsigned int mask; - unsigned int sv_flags; - unsigned int sa_flags; - - handler = vec->sv_handler; - mask = vec->sv_mask; - sv_flags = vec->sv_flags; - sa_flags = 0; - if (sv_flags & SV_ONSTACK) - { -#ifdef SA_ONSTACK - sa_flags |= SA_ONSTACK; -#else - __set_errno (ENOSYS); - return -1; -#endif - } -#ifdef SA_RESTART - if (!(sv_flags & SV_INTERRUPT)) - sa_flags |= SA_RESTART; -#endif -#ifdef SA_RESETHAND - if (sv_flags & SV_RESETHAND) - sa_flags |= SA_RESETHAND; -#endif - n = &new; - new.sa_handler = handler; - if (sigset_set_old_mask (&new.sa_mask, mask) < 0) - return -1; - new.sa_flags = sa_flags; - } - - if (__sigaction (sig, n, &old) < 0) - return -1; - } -#ifndef SA_RESETHAND - else - { - __sighandler_t handler; - unsigned int mask; - struct sigvec_wrapper_data *data; - struct sigaction wrapper; - - handler = vec->sv_handler; - mask = (unsigned int)vec->sv_mask; - data = &sigvec_wrapper_data[sig]; - wrapper.sa_handler = sigvec_wrapper_handler; - /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */ - data->sw_handler = handler; - data->sw_mask = mask; - - if (__sigaction (sig, &wrapper, &old) < 0) - return -1; - } -#endif - - if (ovec != NULL) - { - __sighandler_t handler; - unsigned int sv_flags; - unsigned int sa_flags; - unsigned int mask; - - handler = old.sa_handler; - sv_flags = 0; - sa_flags = old.sa_flags; -#ifndef SA_RESETHAND - if (handler == sigvec_wrapper_handler) - { - handler = sigvec_wrapper_data[sig].sw_handler; - /* should we use data->sw_mask?? */ - sv_flags |= SV_RESETHAND; - } -#else - if (sa_flags & SA_RESETHAND) - sv_flags |= SV_RESETHAND; -#endif - mask = sigset_get_old_mask (&old.sa_mask); -#ifdef SA_ONSTACK - if (sa_flags & SA_ONSTACK) - sv_flags |= SV_ONSTACK; -#endif -#ifdef SA_RESTART - if (!(sa_flags & SA_RESTART)) -#endif - sv_flags |= SV_INTERRUPT; - ovec->sv_handler = handler; - ovec->sv_mask = (int)mask; - ovec->sv_flags = (int)sv_flags; - } - - return 0; -} - -weak_alias (__sigvec, sigvec) - -#ifndef SA_RESETHAND -static void -sigvec_wrapper_handler (sig) - int sig; -{ - struct sigvec_wrapper_data *data; - struct sigaction act; - int save; - __sighandler_t handler; - - data = &sigvec_wrapper_data[sig]; - act.sa_handler = SIG_DFL; - act.sa_flags = 0; - sigset_set_old_mask (&act.sa_mask, data->sw_mask); - handler = data->sw_handler; - save = errno; - (void) __sigaction (sig, &act, (struct sigaction *) NULL); - __set_errno (save); - - (*handler) (sig); -} -#endif diff --git a/sysdeps/unix/bsd/sigvec.c b/sysdeps/unix/bsd/sigvec.c deleted file mode 100644 index d03d9bb3df..0000000000 --- a/sysdeps/unix/bsd/sigvec.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/bsd/syscalls.list b/sysdeps/unix/bsd/syscalls.list index 9f48a144d4..0b4d5fcd54 100644 --- a/sysdeps/unix/bsd/syscalls.list +++ b/sysdeps/unix/bsd/syscalls.list @@ -12,5 +12,4 @@ setlogin - setlogin 2 setlogin sigaltstack - sigaltstack 2 __sigaltstack sigaltstack sigpause - sigpause 1 __sigpause sigpause sigstack - sigstack 2 sigstack -sigvec - sigvec 3 __sigvec sigvec wait4 - wait4 4 __wait4 wait4