mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] The `sigpause` function behavior does not fully comply with the POSIX specification
@ 2025-06-08  8:38 Tommy
  2025-06-08 15:43 ` Haelwenn (lanodan) Monnier
  0 siblings, 1 reply; 12+ messages in thread
From: Tommy @ 2025-06-08  8:38 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 682 bytes --]

Hello:
I noticed this commit.
-->
https://git.musl-libc.org/cgit/musl/commit/src/signal/sigpause.c?id=06c5e4e832f4796be02c743270fb554f978de02c

This commit changed the behavior of `sigpause`. When I passed an invalid
`sig` value, the `sigdelset` function returned -1 and set the error code to
EINVAL, which caused `sigpause` to return -1 and set the error code to
EINVAL. In the POSIX specification, `sigpause` can only return -1 if it
returns, and set the error code to `EINTR` (see
https://man7.org/linux/man-pages/man3/sigpause.3.html#RETURN_VALUE). Maybe
the current behavior of the `sigpause` function violates the POSIX
specification, so I would like to ask if this is a bug.

[-- Attachment #2: Type: text/html, Size: 968 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08  8:38 [musl] The `sigpause` function behavior does not fully comply with the POSIX specification Tommy
@ 2025-06-08 15:43 ` Haelwenn (lanodan) Monnier
  2025-06-08 16:53   ` Bobby Bingham
  0 siblings, 1 reply; 12+ messages in thread
From: Haelwenn (lanodan) Monnier @ 2025-06-08 15:43 UTC (permalink / raw)
  To: musl

[2025-06-08 16:38:51+0800] Tommy:
>Hello:
>I noticed this commit.
>-->
>https://git.musl-libc.org/cgit/musl/commit/src/signal/sigpause.c?id=06c5e4e832f4796be02c743270fb554f978de02c
>
>This commit changed the behavior of `sigpause`. When I passed an invalid
>`sig` value, the `sigdelset` function returned -1 and set the error code to
>EINVAL, which caused `sigpause` to return -1 and set the error code to
>EINVAL. In the POSIX specification, `sigpause` can only return -1 if it
>returns, and set the error code to `EINTR` (see
>https://man7.org/linux/man-pages/man3/sigpause.3.html#RETURN_VALUE). Maybe
>the current behavior of the `sigpause` function violates the POSIX
>specification, so I would like to ask if this is a bug.

This manpage isn't the POSIX standard but Linux own manpage (which for C documents glibc behavior).

See https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpause.html for POSIX.1-2018
where EINVAL is allowed and sigpause returns SIG_ERR (defined by musl in <signal.h> to ((void (*)(int))-1) ).

Also should be noted that POSIX.1-2024 removed "sighold(), sigpause(), and sigrelse()" with the following rationale:
"Applications are recommended to use pthread_sigmask() or sigprocmask() instead of these functions."
— https://pubs.opengroup.org/onlinepubs/9799919799/xrat/V4_xsh_chap01.html#tag_22_03_01_13

Best regards


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 15:43 ` Haelwenn (lanodan) Monnier
@ 2025-06-08 16:53   ` Bobby Bingham
  2025-06-08 17:09     ` Rich Felker
  0 siblings, 1 reply; 12+ messages in thread
From: Bobby Bingham @ 2025-06-08 16:53 UTC (permalink / raw)
  To: musl

On 6/8/25 10:43, Haelwenn (lanodan) Monnier wrote:
> 
> This manpage isn't the POSIX standard but Linux own manpage (which for C 
> documents glibc behavior).

Yes.

> 
> See https://pubs.opengroup.org/onlinepubs/9699919799/functions/ 
> sigpause.html for POSIX.1-2018
> where EINVAL is allowed and sigpause returns SIG_ERR (defined by musl in 
> <signal.h> to ((void (*)(int))-1) ).

That page says:

     The sigpause() function shall suspend execution of the thread until
     a signal is received, whereupon it shall return -1 and set errno to
     [EINTR].

This reads to me that sigpause is only permitted to set errno to EINTR, 
and not to return other errors. The list of errors would seem to apply 
to the other functions on the page, which are documented to "use errno 
to indicate the error."

--
Bobby Bingham


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 16:53   ` Bobby Bingham
@ 2025-06-08 17:09     ` Rich Felker
  2025-06-08 18:39       ` Bobby Bingham
  0 siblings, 1 reply; 12+ messages in thread
From: Rich Felker @ 2025-06-08 17:09 UTC (permalink / raw)
  To: Bobby Bingham; +Cc: musl

On Sun, Jun 08, 2025 at 11:53:44AM -0500, Bobby Bingham wrote:
> On 6/8/25 10:43, Haelwenn (lanodan) Monnier wrote:
> > 
> > This manpage isn't the POSIX standard but Linux own manpage (which for C
> > documents glibc behavior).
> 
> Yes.
> 
> > 
> > See https://pubs.opengroup.org/onlinepubs/9699919799/functions/
> > sigpause.html for POSIX.1-2018
> > where EINVAL is allowed and sigpause returns SIG_ERR (defined by musl in
> > <signal.h> to ((void (*)(int))-1) ).
> 
> That page says:
> 
>     The sigpause() function shall suspend execution of the thread until
>     a signal is received, whereupon it shall return -1 and set errno to
>     [EINTR].
> 
> This reads to me that sigpause is only permitted to set errno to EINTR, and
> not to return other errors. The list of errors would seem to apply to the
> other functions on the page, which are documented to "use errno to indicate
> the error."

That's specifying the behavior on successful return, not on errors.

The ERRORS section says:

    These functions shall fail if:

    [EINVAL]
        The sig argument is an illegal signal number. 

Seems pretty clear. This is a "shall fail" (mandatory) not a "may
fail", so detecting the invalid signal number and failing with EINVAL
is mandatory. The old behavior of ignoring it was non-conforming.

See: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpause.html

Rich


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 17:09     ` Rich Felker
@ 2025-06-08 18:39       ` Bobby Bingham
  2025-06-08 18:49         ` Rich Felker
  0 siblings, 1 reply; 12+ messages in thread
From: Bobby Bingham @ 2025-06-08 18:39 UTC (permalink / raw)
  To: musl

On 6/8/25 12:09, Rich Felker wrote:
>>>
>>> See https://pubs.opengroup.org/onlinepubs/9699919799/functions/
>>> sigpause.html for POSIX.1-2018
>>> where EINVAL is allowed and sigpause returns SIG_ERR (defined by musl in
>>> <signal.h> to ((void (*)(int))-1) ).
>>
>> That page says:
>>
>>      The sigpause() function shall suspend execution of the thread until
>>      a signal is received, whereupon it shall return -1 and set errno to
>>      [EINTR].
>>
>> This reads to me that sigpause is only permitted to set errno to EINTR, and
>> not to return other errors. The list of errors would seem to apply to the
>> other functions on the page, which are documented to "use errno to indicate
>> the error."
> 
> That's specifying the behavior on successful return, not on errors.

Quoting the entire RETURN VALUE section:


     Upon successful completion, sigset() shall return SIG_HOLD if the
     signal had been blocked and the signal's previous disposition if it
     had not been blocked. Otherwise, SIG_ERR shall be returned and errno
     set to indicate the error.

     The sigpause() function shall suspend execution of the thread until
     a signal is received, whereupon it shall return -1 and set errno to
     [EINTR].

     For all other functions, upon successful completion, 0 shall be
     returned. Otherwise, -1 shall be returned and errno set to indicate
     the error.


For all the other functions, the documentation clearly distinguishes 
between successful completion and errors, and states what return value 
indicates that an error occurred.  For sigpause, it does not.  As you 
stated, the documentation here specifies what happens on success -- 
there is no mention of what the return value is on failure.

I took this to mean that sigpause cannot report errors, and therefore 
cannot fail.


> 
> The ERRORS section says:
> 
>      These functions shall fail if:
> 
>      [EINVAL]
>          The sig argument is an illegal signal number.
> 
> Seems pretty clear. This is a "shall fail" (mandatory) not a "may
> fail", so detecting the invalid signal number and failing with EINVAL
> is mandatory. The old behavior of ignoring it was non-conforming.


I did read that.  I found it hard to reconcile a "shall fail" error for 
a function that does not have a documented way to report errors, so 
thought perhaps the phrasing "these functions" was intended to refer to 
just those functions on the page _that can report errors_.

One can certainly read between the lines and infer that a return value 
of -1 can indicate an error.  I just expected it to explicitly say so if 
that was the case.  But I'm not an expert at reading the POSIX spec; 
perhaps my expectation is wrong.  Or perhaps the wording for this 
function was just unusually sloppy.


> 
> See: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpause.html
> 
> Rich



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 18:39       ` Bobby Bingham
@ 2025-06-08 18:49         ` Rich Felker
  2025-06-08 19:34           ` Thorsten Glaser
                             ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Rich Felker @ 2025-06-08 18:49 UTC (permalink / raw)
  To: Bobby Bingham; +Cc: musl

On Sun, Jun 08, 2025 at 01:39:17PM -0500, Bobby Bingham wrote:
> On 6/8/25 12:09, Rich Felker wrote:
> > > > 
> > > > See https://pubs.opengroup.org/onlinepubs/9699919799/functions/
> > > > sigpause.html for POSIX.1-2018
> > > > where EINVAL is allowed and sigpause returns SIG_ERR (defined by musl in
> > > > <signal.h> to ((void (*)(int))-1) ).
> > > 
> > > That page says:
> > > 
> > >      The sigpause() function shall suspend execution of the thread until
> > >      a signal is received, whereupon it shall return -1 and set errno to
> > >      [EINTR].
> > > 
> > > This reads to me that sigpause is only permitted to set errno to EINTR, and
> > > not to return other errors. The list of errors would seem to apply to the
> > > other functions on the page, which are documented to "use errno to indicate
> > > the error."
> > 
> > That's specifying the behavior on successful return, not on errors.
> 
> Quoting the entire RETURN VALUE section:
> 
> 
>     Upon successful completion, sigset() shall return SIG_HOLD if the
>     signal had been blocked and the signal's previous disposition if it
>     had not been blocked. Otherwise, SIG_ERR shall be returned and errno
>     set to indicate the error.
> 
>     The sigpause() function shall suspend execution of the thread until
>     a signal is received, whereupon it shall return -1 and set errno to
>     [EINTR].
> 
>     For all other functions, upon successful completion, 0 shall be
>     returned. Otherwise, -1 shall be returned and errno set to indicate
>     the error.
> 
> 
> For all the other functions, the documentation clearly distinguishes between
> successful completion and errors, and states what return value indicates
> that an error occurred.  For sigpause, it does not.  As you stated, the
> documentation here specifies what happens on success -- there is no mention
> of what the return value is on failure.
> 
> I took this to mean that sigpause cannot report errors, and therefore cannot
> fail.
> 
> 
> > 
> > The ERRORS section says:
> > 
> >      These functions shall fail if:
> > 
> >      [EINVAL]
> >          The sig argument is an illegal signal number.
> > 
> > Seems pretty clear. This is a "shall fail" (mandatory) not a "may
> > fail", so detecting the invalid signal number and failing with EINVAL
> > is mandatory. The old behavior of ignoring it was non-conforming.
> 
> 
> I did read that.  I found it hard to reconcile a "shall fail" error for a
> function that does not have a documented way to report errors, so thought
> perhaps the phrasing "these functions" was intended to refer to just those
> functions on the page _that can report errors_.
> 
> One can certainly read between the lines and infer that a return value of -1
> can indicate an error.  I just expected it to explicitly say so if that was
> the case.  But I'm not an expert at reading the POSIX spec; perhaps my
> expectation is wrong.  Or perhaps the wording for this function was just
> unusually sloppy.

This would probably call for an interpretation, except that the
functions were removed from the standard and the standard no longer
has anything to say about them. So I'm not sure what's best to do.

If the historical precedent in other implementations is for not
reporting an error here, and applications are expecting that, perhaps
we should revert the change?

Rich


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 18:49         ` Rich Felker
@ 2025-06-08 19:34           ` Thorsten Glaser
  2025-06-08 20:32           ` Markus Wichmann
  2025-06-09 11:20           ` Valery Ushakov
  2 siblings, 0 replies; 12+ messages in thread
From: Thorsten Glaser @ 2025-06-08 19:34 UTC (permalink / raw)
  To: musl; +Cc: Bobby Bingham

On Sun, 8 Jun 2025, Rich Felker wrote:

>This would probably call for an interpretation, except that the
>functions were removed from the standard and the standard no longer
>has anything to say about them. So I'm not sure what's best to do.

Ask for an interpretation for Issue 7.

I also read this as “in the success case, but there may be other
errors”. The other errors of course exist and you need to handle
them as usual cases pop up every once in a while for us shell
developers…

bye,
//mirabilos
-- 
FWIW, I'm quite impressed with mksh interactively. I thought it was much
*much* more bare bones. But it turns out it beats the living hell out of
ksh93 in that respect. I'd even consider it for my daily use if I hadn't
wasted half my life on my zsh setup. :-) -- Frank Terbeck in #!/bin/mksh


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 18:49         ` Rich Felker
  2025-06-08 19:34           ` Thorsten Glaser
@ 2025-06-08 20:32           ` Markus Wichmann
  2025-06-09 11:20           ` Valery Ushakov
  2 siblings, 0 replies; 12+ messages in thread
From: Markus Wichmann @ 2025-06-08 20:32 UTC (permalink / raw)
  To: musl; +Cc: Bobby Bingham

Am Sun, Jun 08, 2025 at 02:49:32PM -0400 schrieb Rich Felker:
> This would probably call for an interpretation, except that the
> functions were removed from the standard and the standard no longer
> has anything to say about them. So I'm not sure what's best to do.
> 
> If the historical precedent in other implementations is for not
> reporting an error here, and applications are expecting that, perhaps
> we should revert the change?
> 
> Rich

bionic will also return a sigdelset() failure to the caller, as will
glibc. newlib will not, it just silently ignores the error. dietlibc
does not have sigpause(), at least not that I could find.

So it seems like the most popular libc implementations do indeed return
EINVAL for invalid signals.

Ciao,
Markus


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-08 18:49         ` Rich Felker
  2025-06-08 19:34           ` Thorsten Glaser
  2025-06-08 20:32           ` Markus Wichmann
@ 2025-06-09 11:20           ` Valery Ushakov
  2025-06-09 14:06             ` Rich Felker
  2025-06-09 18:15             ` [musl] " Thorsten Glaser
  2 siblings, 2 replies; 12+ messages in thread
From: Valery Ushakov @ 2025-06-09 11:20 UTC (permalink / raw)
  To: musl

On Sun, Jun 08, 2025 at 14:49:32 -0400, Rich Felker wrote:

> This would probably call for an interpretation, except that the
> functions were removed from the standard and the standard no longer
> has anything to say about them. So I'm not sure what's best to do.
> 
> If the historical precedent in other implementations is for not
> reporting an error here, and applications are expecting that, perhaps
> we should revert the change?

sigpause is a 4.3BSD interface and it used to be a system call that
did this:

https://www.retro11.de/ouxr/43bsd/usr/src/sys/sys/kern_sig.c.html#s:_sigpause

sigpause()
{
	struct a {
		int	mask;
	} *uap = (struct a *)u.u_ap;
	register struct proc *p = u.u_procp;

	/*
	 * When returning from sigpause, we want
	 * the old mask to be restored after the
	 * signal handler has finished.  Thus, we
	 * save it here and mark the proc structure
	 * to indicate this (should be in u.).
	 */
	u.u_oldmask = p->p_sigmask;
	p->p_flag |= SOMASK;
	p->p_sigmask = uap->mask &~ cantmask;
	for (;;)
		sleep((caddr_t)&u, PSLEP);
	/*NOTREACHED*/
}


Which also brings up another question.  The current NetBSD man page
documents that behavior in https://man.netbsd.org/sigpause.3 as
(emphasis mine):

  sigpause() ASSIGNS sigmask to the set of masked signals and then waits
  for a signal to arrive;


While POSIX says:

  The sigpause() function shall REMOVE sig from the signal mask of the
  calling process and suspend the calling process until a signal is
  received.

Which is not what historic sigpause(2) did, if i read this text (and
"sigdelset" in implementations) correctly.

-uwe


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-09 11:20           ` Valery Ushakov
@ 2025-06-09 14:06             ` Rich Felker
  2025-06-09 18:15             ` [musl] " Thorsten Glaser
  1 sibling, 0 replies; 12+ messages in thread
From: Rich Felker @ 2025-06-09 14:06 UTC (permalink / raw)
  To: Valery Ushakov; +Cc: musl

On Mon, Jun 09, 2025 at 02:20:52PM +0300, Valery Ushakov wrote:
> On Sun, Jun 08, 2025 at 14:49:32 -0400, Rich Felker wrote:
> 
> > This would probably call for an interpretation, except that the
> > functions were removed from the standard and the standard no longer
> > has anything to say about them. So I'm not sure what's best to do.
> > 
> > If the historical precedent in other implementations is for not
> > reporting an error here, and applications are expecting that, perhaps
> > we should revert the change?
> 
> sigpause is a 4.3BSD interface and it used to be a system call that
> did this:
> 
> https://www.retro11.de/ouxr/43bsd/usr/src/sys/sys/kern_sig.c.html#s:_sigpause
> 
> sigpause()
> {
> 	struct a {
> 		int	mask;
> 	} *uap = (struct a *)u.u_ap;
> 	register struct proc *p = u.u_procp;
> 
> 	/*
> 	 * When returning from sigpause, we want
> 	 * the old mask to be restored after the
> 	 * signal handler has finished.  Thus, we
> 	 * save it here and mark the proc structure
> 	 * to indicate this (should be in u.).
> 	 */
> 	u.u_oldmask = p->p_sigmask;
> 	p->p_flag |= SOMASK;
> 	p->p_sigmask = uap->mask &~ cantmask;
> 	for (;;)
> 		sleep((caddr_t)&u, PSLEP);
> 	/*NOTREACHED*/
> }
> 
> 
> Which also brings up another question.  The current NetBSD man page
> documents that behavior in https://man.netbsd.org/sigpause.3 as
> (emphasis mine):
> 
>   sigpause() ASSIGNS sigmask to the set of masked signals and then waits
>   for a signal to arrive;
> 
> 
> While POSIX says:
> 
>   The sigpause() function shall REMOVE sig from the signal mask of the
>   calling process and suspend the calling process until a signal is
>   received.
> 
> Which is not what historic sigpause(2) did, if i read this text (and
> "sigdelset" in implementations) correctly.

The POSIX text seems to be missing any rationale explaining this, but
I found it's actually explained in the Linux man pages. This is one
place where there were historical mismatched bsd and sysv interfaces
by the same name, and POSIX codified the sysv one. So if we're looking
at historical behaviors, it probably only makes sense to look at
implementions that follow sysv practices.

Rich


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [musl] Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-09 11:20           ` Valery Ushakov
  2025-06-09 14:06             ` Rich Felker
@ 2025-06-09 18:15             ` Thorsten Glaser
  2025-06-10  1:28               ` Valery Ushakov
  1 sibling, 1 reply; 12+ messages in thread
From: Thorsten Glaser @ 2025-06-09 18:15 UTC (permalink / raw)
  To: musl

On Mon, 9 Jun 2025, Valery Ushakov wrote:

>sigpause is a 4.3BSD interface and it used to be a system call that
>did this:

The thing you missed is that there were two mututally incompatible
sigpause functions around.

The 4.3BSD one is obsolete, but still present in BSD libcs, and
merely resolves to:

	int
	sigpause(int mask)
	{
		return (sigsuspend((sigset_t *)&mask));
	}

The incompatible *other* one got standardised for UNIX95 and is
the one removed from latest POSIX. I’d even say drop it the next
time musl bumps the major version anyway.

bye,
//mirabilos
-- 
> Hi, does anyone sell openbsd stickers by themselves and not packaged
> with other products?
No, the only way I've seen them sold is for $40 with a free OpenBSD CD.
	-- Haroon Khalid and Steve Shockley in gmane.os.openbsd.misc

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Re: The `sigpause` function behavior does not fully comply with the POSIX specification
  2025-06-09 18:15             ` [musl] " Thorsten Glaser
@ 2025-06-10  1:28               ` Valery Ushakov
  0 siblings, 0 replies; 12+ messages in thread
From: Valery Ushakov @ 2025-06-10  1:28 UTC (permalink / raw)
  To: musl

On Mon, Jun 09, 2025 at 20:15:33 +0200, Thorsten Glaser wrote:

> On Mon, 9 Jun 2025, Valery Ushakov wrote:
> 
> >sigpause is a 4.3BSD interface and it used to be a system call that
> >did this:
> 
> The thing you missed is that there were two mututally incompatible
> sigpause functions around.

IIRC, in the early 90s there were simultaneously 5 different sets of
APIs to work with signals.  I'm glad I forgot (nearly) everything
about that ... :)

-uwe


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-06-10  1:28 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-08  8:38 [musl] The `sigpause` function behavior does not fully comply with the POSIX specification Tommy
2025-06-08 15:43 ` Haelwenn (lanodan) Monnier
2025-06-08 16:53   ` Bobby Bingham
2025-06-08 17:09     ` Rich Felker
2025-06-08 18:39       ` Bobby Bingham
2025-06-08 18:49         ` Rich Felker
2025-06-08 19:34           ` Thorsten Glaser
2025-06-08 20:32           ` Markus Wichmann
2025-06-09 11:20           ` Valery Ushakov
2025-06-09 14:06             ` Rich Felker
2025-06-09 18:15             ` [musl] " Thorsten Glaser
2025-06-10  1:28               ` Valery Ushakov

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).