Bug 26003 - getgroups(2) lists NGROUPS_MAX but not syslimits.h
Summary: getgroups(2) lists NGROUPS_MAX but not syslimits.h
Status: Closed Overcome By Events
Alias: None
Product: Documentation
Classification: Unclassified
Component: Manual Pages (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2001-03-22 17:40 UTC by Robert Watson
Modified: 2018-04-13 00:31 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Watson freebsd_committer freebsd_triage 2001-03-22 17:40:01 UTC
man getgroups notes that no more than NGROUPS_MAX will be returned by the
function, suggesting that this is an upper bound on the gidset array that can
be used by an application.  However, the man page lists only sys/types.h and
unistd.h as required include files, and NGROUPS_MAX is not defined in either
of those.  To get NGROUPS_MAX, it is necessary to include sys/syslimits.h.

SYNOPSIS
     #include <sys/types.h>
     #include <unistd.h>

     int
     getgroups(int gidsetlen, gid_t *gidset)
...
     number of entries that may be placed in gidset.  Getgroups() returns the
     actual number of groups returned in gidset.  No more than NGROUPS_MAX
     will ever be returned.  If gidsetlen is zero, getgroups() returns the
     number of supplementary group IDs associated with the calling process
     without modifying the array pointed to by gidset.

Fix: 

Modify man page to include syslimits.h, replicate value into types.h,
other bogosities of namespace, remove reference to NGROUPS_MAX in the man
page.  Note clear which is the worst.  What does POSIX say about
getgroups()?
How-To-Repeat: 
# cat > test.c
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
	gid_t gidset[NGROUPS_MAX];
	int error;

	error = getgroups(NGROUPS_MAX, gidset);
	if (error)
		perror("getgroups");
	return (0);
}
<Ctrl-D>
# gcc -o test test.c
test.c: In function `main':
test.c:7: `NGROUPS_MAX' undeclared (first use in this function)
test.c:7: (Each undeclared identifier is reported only once
test.c:7: for each function it appears in.)
Comment 1 dima 2001-03-24 22:51:48 UTC
rwatson@freebsd.org writes:
> 
> >Number:         26003
> >Category:       docs
> >Synopsis:       getgroups(2) lists NGROUPS_MAX but not syslimits.h
> >Fix:
> 
> Modify man page to include syslimits.h, replicate value into types.h,
> other bogosities of namespace, remove reference to NGROUPS_MAX in the man
> page.  Note clear which is the worst.  

I think mentioning syslimits.h in the man page is the best option.
NGROUPS_MAX seems to fit in there nicely.  If that's acceptable for
you, I'll go ahead and fix that.

>                                        What does POSIX say about
> getgroups()?

I don't know, but wollman's "POSIX header file update" doesn't touch
it (leaves it in syslimits.h), so it can't be that bad.

Thanks

					Dima Dorfman
					dima@unixfreak.org
Comment 2 dd freebsd_committer freebsd_triage 2001-04-01 02:50:15 UTC
State Changed
From-To: open->feedback

Is mentioning syslimits.h in the man page sufficient?
Comment 3 Jeroen Ruigrok/Asmodai 2001-07-30 21:01:47 UTC
-On [20010401 13:00], Bruce Evans (bde@zeta.org.au) wrote:
>On Sat, 31 Mar 2001, Robert Watson wrote:
>
>> Dunno -- I guess this leads to a number of questions of specification-land
>> -- is NGROUPS_MAX supposed to be exposed to the application, if so, how
>> should the application go about including things to get the value, etc. 
>> Bruce might have a good answer, if not a correct one, so I've CC'd him
>> :-). 
>
>In POSIX.1-1996:
>
>1) NGROUPS_MAX is defined in <limits.h>.  (<sys/syslimits.h> is BSD
>   implementation detail, so it shouldn't be documented.)
>
>2) NGROUPS_MAX is a "Run-Time Increasable Value".  This means that
>   applications may find that the actual maximum number of groups is
>   larger than their compile time value of NGROUPS_MAX.  The run time
>   maximum is given by sysconf(_SC_NGROUPS_MAX).
>
>3) Unlike some other POSIX limits, NGROUPS_MAX must be defined at
>   compile time, although its value is almost useless if its run time
>   value is larger.  A footnote says that future revisions of POSIX.1
>   are expected to permit omitting the definition of NGROUPS_MAX from
>   <limits.h> to indicate that its value is variable.

Latest POSIX draft specifies:

SYNOPSIS
	#include <unistd.h>

	int getgroups(int gidsetsize, gid_t grouplist[]);

[...]

Applications writers should note that {NGROUPS_MAX} is not
necessarily a constant on all implementations.

[...]

Issue 6
	In the SYNOPSIS, the optional include of the <sys/types.h>
	header is removed.

	The following new requirements on POSIX implementations derive
	from alignment with the Single UNIX Specification:

	  · The requirement to include <sys/types.h> has been removed.
	    Although <sys/types.h> was required for conforming
	    implementations of previous POSIX specifications, it was not
	    required for UNIX applications.
	  · A return value of 0 is not permitted, because {NGROUPS_MAX}
	    cannot be 0. This is a FIPS requirement.

-- 
Jeroen Ruigrok van der Werven/Asmodai asmodai@[wxs.nl|freebsd.org|xmach.org]
Documentation nutter/C-rated Coder, finger asmodai@ninth-circle.dnsalias.net
http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/
The human race is challenged more than ever before to demonstrate our
mastery -- not over nature but of ourselves...
Comment 4 Jeroen Ruigrok/Asmodai 2001-07-30 21:01:47 UTC
-On [20010401 13:00], Bruce Evans (bde@zeta.org.au) wrote:
>On Sat, 31 Mar 2001, Robert Watson wrote:
>
>> Dunno -- I guess this leads to a number of questions of specification-land
>> -- is NGROUPS_MAX supposed to be exposed to the application, if so, how
>> should the application go about including things to get the value, etc. 
>> Bruce might have a good answer, if not a correct one, so I've CC'd him
>> :-). 
>
>In POSIX.1-1996:
>
>1) NGROUPS_MAX is defined in <limits.h>.  (<sys/syslimits.h> is BSD
>   implementation detail, so it shouldn't be documented.)
>
>2) NGROUPS_MAX is a "Run-Time Increasable Value".  This means that
>   applications may find that the actual maximum number of groups is
>   larger than their compile time value of NGROUPS_MAX.  The run time
>   maximum is given by sysconf(_SC_NGROUPS_MAX).
>
>3) Unlike some other POSIX limits, NGROUPS_MAX must be defined at
>   compile time, although its value is almost useless if its run time
>   value is larger.  A footnote says that future revisions of POSIX.1
>   are expected to permit omitting the definition of NGROUPS_MAX from
>   <limits.h> to indicate that its value is variable.

Latest POSIX draft specifies:

SYNOPSIS
	#include <unistd.h>

	int getgroups(int gidsetsize, gid_t grouplist[]);

[...]

Applications writers should note that {NGROUPS_MAX} is not
necessarily a constant on all implementations.

[...]

Issue 6
	In the SYNOPSIS, the optional include of the <sys/types.h>
	header is removed.

	The following new requirements on POSIX implementations derive
	from alignment with the Single UNIX Specification:

	  · The requirement to include <sys/types.h> has been removed.
	    Although <sys/types.h> was required for conforming
	    implementations of previous POSIX specifications, it was not
	    required for UNIX applications.
	  · A return value of 0 is not permitted, because {NGROUPS_MAX}
	    cannot be 0. This is a FIPS requirement.

-- 
Jeroen Ruigrok van der Werven/Asmodai asmodai@[wxs.nl|freebsd.org|xmach.org]
Documentation nutter/C-rated Coder, finger asmodai@ninth-circle.dnsalias.net
http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/
The human race is challenged more than ever before to demonstrate our
mastery -- not over nature but of ourselves...
Comment 5 nik freebsd_committer freebsd_triage 2002-01-09 13:29:06 UTC
Responsible Changed
From-To: freebsd-doc->rwatson

Reading the audit trail it doesn't look as though this is a doc bug.  It 
seems we may need to change the headers and/or examples if we want POSIX 
compliance.  What do you think, Robert?
Comment 6 Robert Watson freebsd_committer freebsd_triage 2008-01-27 11:01:32 UTC
State Changed
From-To: feedback->analyzed

It seems like we understand the problem, but still no conclusion on the 
exact fix--perhaps unistd.h needs to find NGROUPS_MAX somehow without 
polluting the namespace too much more? 



Comment 7 Robert Watson freebsd_committer freebsd_triage 2008-01-27 11:01:32 UTC
Responsible Changed
From-To: rwatson->freebsd-standards

Assign to freebsd-standards as they may have a better sense of how to 
deal with this one.
Comment 8 Bruce Evans freebsd_committer freebsd_triage 2008-01-27 15:10:50 UTC
On Sun, 27 Jan 2008 rwatson@freebsd.org wrote:

> Synopsis: getgroups(2) lists NGROUPS_MAX but not syslimits.h

> It seems like we understand the problem, but still no conclusion on the
> exact fix--perhaps unistd.h needs to find NGROUPS_MAX somehow without
> polluting the namespace too much more?

Of course not.  There are only man page bugs.  There is a good interface
for determining the size of the array needed, and it doesn't involve
{NGROUPS_MAX} -- just call getgroups() with gidsetlen == 0 to determine
the size.  Synopses shouldn't mention includes that are only needed
for some uses of interfaces, especially here since the use is a bad
one (to be unportable by hard-coding NGROUPS_MAX).  The includes are
already sufficient for using {NGROUPS_MAX} in its portable form
sysconf(_SC_NGROUPS_MAX), except you will also need malloc().  <stdlib.h>
for using malloc() is another include that doesn't belong in the
synopsis.

If you want better wording for {NGROUPS_MAX} in this man page, see
POSIX.  POSIX.1-2001-draft7 actually doesn't do much more than say
{NGROUPS_MAX}+1 where FreeBSD says NGROUPS_MAX.  The {FOO} markup is
documented elsewhere.  It is very useful for avoiding repeating the
documentation of the messes required for using limits.  It is barely
used in FreeBSD (FreeBSD tends to document only unportabilities like
hard-coding NAME_MAX and PATH_MAX).  The +1 is because the euid may
be returned in the list.  FreeBSD apparently doesn't do this, and its
man page doesn't say that it might be needed.  POSIX gives an example
of using sysconf(_SC_NGROUPS_MAX) will no error checking for sysconf()
or malloc().  POSIX's rationale for getgroups() notes that {NGROUPS_MAX}
might not be constant.

Bruce
Comment 9 wollman 2008-01-27 17:58:03 UTC
<<On Sun, 27 Jan 2008 16:00:04 GMT, Bruce Evans <brde@optusnet.com.au> said:

>  one (to be unportable by hard-coding NGROUPS_MAX).  The includes are
>  already sufficient for using {NGROUPS_MAX} in its portable form
>  sysconf(_SC_NGROUPS_MAX), except you will also need malloc().  <stdlib.h>
>  for using malloc() is another include that doesn't belong in the
>  synopsis.

What Bruce said.  It would be better for constants such as this to be
left completely undefined (at least when not compiling the kernel) --
although there is the inevitable tension between handling these limits
correctly and handling broken applications that do things like

	#ifndef NGROUPS_MAX
	#define NGROUPS_MAX 8
	#endif

Those applications, at least, are clearly wrong, so my vote would be
on the side of breaking the applications and doing the Right Thing by
not defining NGROUPS_MAX.

-GAWollman
Comment 10 Timothy Moore II 2017-09-01 15:21:51 UTC
It appears the getgroups(2) manual page has been updated while this ticket was dormant. This issue should probably be closed.
Comment 11 Oleksandr Tymoshenko freebsd_committer freebsd_triage 2018-04-13 00:31:05 UTC
Value of NGROUPS_MAX was clarified in r217704