Date: Wed, 15 Apr 1998 20:49:28 +0100 From: James Raynard <fhackers@jraynard.demon.co.uk> To: rotel@indigo.ie Cc: joelh@gnu.org, freebsd-hackers@FreeBSD.ORG Subject: Re: PR kern/1144 Message-ID: <19980415204928.43540@jraynard.demon.co.uk> In-Reply-To: <199804150103.CAA01392@indigo.ie>; from Niall Smart on Wed, Apr 15, 1998 at 02:03:43AM %2B0000 References: <fhackers@jraynard.demon.co.uk> <199804150103.CAA01392@indigo.ie>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Apr 15, 1998 at 02:03:43AM +0000, Niall Smart wrote:
> On Apr 1n, 9:17pm, James Raynard wrote:
> >
> > In his reply to my original PR, bde posted a macro that did what you
> > suggest for integer arguments (is this not in the PR database?).
>
> Nope. Still got it?
Yep. Note there's a followup as well.
James
Date: Tue, 16 Apr 1996 19:20:07 +1000
From: Bruce Evans <bde@zeta.org.au>
Subject: Re: kern/1144: sig{add, del}set and sigismember fns don't check signo
> >Obviously the macros would be much harder to fix
>
> Would they? How about
>
> #define sigaddset(set, signo) (((signo) <= 0 || (signo) >= NSIG) ?
> (errno = EINVAL, -1) :
> (*(set) |= 1 << ((signo) - 1), 0))
>
> (untested, as usual)
Try it with:
for (signo = 0; signo < 32; )
sigaddset(set, signo++);
or weird and not so weird things like:
void *s = set;
sigaddset(set, 1.234);
sigaddset(s, SIGINT);
which also fail for the standard macro, but would work for a prototyped
function.
It is possible to write it as a safe macro using Gnu C:
#define sigaddset(set, signo) \
({ struct sigaction *__set = set; \
int __signo = (signo); \
int __rv; \
\
/* 32 because NSIG is in application namespace. */ \
if (__signo <= 0 || __signo >= 32) { \
errno = EINVAL; \
__rv = -1; \
} else { \
*__set |= 1 << __signo; \
__rv = 0; \
} \
__rv; })
Untested, as usual.
Who wants all that for a function? It is probably a pessimization to
inline it unless signo is a constant. A larger and uglier gcc macro
could be used to handle the constant case inline and call a function
otherwise. Linux once used inline versions, but switched to function
versions because the macros aren't worth the trouble.
POSIX.1 1990 is unclearly written in this area. I think it allows our
current macros for everything except sigismember(). It doesn't
explictly require detection of errors, but it requires sigismember() to
either fail and return -1 or succeed and return a value other than 0 if
the signal isn't a member of the set. This fits well with most uses of
the macros - you check the signal number using sigismember(), or know
that it is valid, and then checking it in the other macros is a waste of
time.
Bruce
Date: Tue, 16 Apr 1996 22:37:47 +1000
From: Bruce Evans <bde@zeta.org.au>
Subject: Re: kern/1144: sig{add, del}set and sigismember fns don't check signo
I wrote:
>#define sigaddset(set, signo) \
> ({ struct sigaction *__set = set; \
> int __signo = (signo); \
> int __rv; \
> \
> /* 32 because NSIG is in application namespace. */ \
> if (__signo <= 0 || __signo >= 32) { \
> errno = EINVAL; \
Namespace stuff is tricky. I think EINVAL isn't supposed to be
visible if only <signal.h> is included, so it can't be used
directly.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980415204928.43540>
