Subject: Re: POSIX signal macros broken/shakey on 1.0 beta
To: Chris G. Demetriou <cgd@alpha.bostic.com>
From: None <Mark_Weaver@brown.edu>
List: current-users
Date: 08/11/1994 19:47:43
I seem to recall that some core team member said that the POSIX wording
was a bit ambiguous, and it was hard to tell for sure what they meant.
Given this, isn't it better to be safe than sorry?

I quote most of page 292 from "Advanced Programming in the UNIX
Environment" by W. Richard Stevens, which claims to describe POSIX
among other things.  Note the paragraph after the sample implementation:

- - - - - - - - - - - - - BEGIN QUOTE - - - - - - - - - - - - - - - - 
#include <signal.h>
#include <errno.h>

#define SIGBAD(signo)	((signo) <= 0 || (signo) >= NSIG)
   /* <signal.h> usually defines NSIG to include signal number 0 */

int
sigaddset(sigset_t *set, int signo)
{
    if (SIGBAD(signo)) { errno = EINVAL; return(-1); }

    *set |= 1 << (signo - 1);		/* turn bit on */
    return(0);
}

int
sigdelset(sigset_t *set, int signo)
{
    if (SIGBAD(signo)) { errno = EINVAL; return(-1); }

    *set &= ~(1 << (signo - 1));	/* turn bit on */
    return(0);
}

int
sigismember(const sigset_t *set, int signo)
{
    if (SIGBAD(signo)) { errno = EINVAL; return(-1); }

    return( (*set & (1 << (signo - 1))) != 0 );
}

   Program 10.9  An implementation of sigaddset, sigdelset, and sigismember


We might be tempted to implement these three functions as one-line macros
in the <signal.h> header, but POSIX.1 requires us to check the signal number
argument for validity and set errno if it is invalid.  This is harder to do
in a macro than a function.

- - - - - - - - - - - - - END QUOTE - - - - - - - - - - - - - - - - - 

Again, isn't it better to be safe than sorry?  Whether Stevens'
interpretation of the POSIX.1 spec is right or wrong, many programmers
will be following his interpretation because of this excellent
book.

Incidentally, the book does define sigemptyset and sigfillset as
macros in <signal.h> on the previous page:

   #define sigemptyset(ptr)	( *(ptr) = 0 )
   #define sigfillset(ptr)	( *(ptr) = ~(sigset_t)0, 0 )

"Chris G. Demetriou" <cgd@alpha.bostic.com> writes:
> This argument has happened several times before, see the mailing list
> archives...
> 
> Basically, the output of sigismember() is only defined if the signal
> number is valid, and an error has to be returned only if an error
> is detected.  So if the number is invalid, and that's not detected
> (and nothing says that it has to be), the result returned may not
> be what's expected.
> 
> CVS isn't behaving in a POSIX-friendly manner, given its usage
> of sigismember().  (of course, our sigismember() could be considered
> a bit strange, too, but it's not strictly a _bug_.)

	Mark
--------------------------------------------------------------------
Email: Mark_Weaver@brown.edu           | Brown University
PGP Key: finger mhw@cs.brown.edu       | Dept of Computer Science

------------------------------------------------------------------------------