From owner-freebsd-bugs Tue Apr 16 02:21:43 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id CAA28060 for bugs-outgoing; Tue, 16 Apr 1996 02:21:43 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id CAA28053 for ; Tue, 16 Apr 1996 02:21:32 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id TAA23895; Tue, 16 Apr 1996 19:20:07 +1000 Date: Tue, 16 Apr 1996 19:20:07 +1000 From: Bruce Evans Message-Id: <199604160920.TAA23895@godzilla.zeta.org.au> To: fenner@parc.xerox.com, freebsd-bugs@freefall.freebsd.org Subject: Re: kern/1144: sig{add, del}set and sigismember fns don't check signo Sender: owner-bugs@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk > >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