newlib/winsup/testsuite/winsup.api/ltp/getgroups01.c

315 lines
8.5 KiB
C

/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
*
*/
/* $Id$ */
/***********************************************************************
TEST IDENTIFIER: getgroups01 : Getgroups system call critical test
PARENT DOCUMENT: ggrtds01: Getgroups system call test design spec
AUTHOR: Barrie Kletscher
Rewrote : 11-92 by Richard Logan
CO-PILOT: Dave Baumgartner
TEST ITEMS:
1. Check to see if getgroups(-1, gidset) fails and sets errno to EINVAL
2. Check to see if getgroups(0, gidset) does not return -1 and gidset is
not modified.
3. Check to see if getgroups(x, gigset) fails and sets errno to EINVAL,
where x is one less then what is returned by getgroups(0, gidset).
4. Check to see if getgroups() succeeds and gidset contains
group id returned from getgid().
INPUT SPECIFICATIONS:
NONE
OUTPUT SPECIFICATIONS:
Standard tst_res output format
ENVIRONMENTAL NEEDS:
NONE.
SPECIAL PROCEDURAL REQUIREMENTS:
None
INTERCASE DEPENDENCIES:
Test case #3 depends on test case #2.
DETAILED DESCRIPTION:
Set up the signal handling capabilities.
execute tests
exit
BUGS:
None known.
************************************************************/
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include "test.h"
#include "usctest.h"
void setup();
void cleanup(void) __attribute__((noreturn));
const char *TCID="getgroups01"; /* Test program identifier. */
int TST_TOTAL=4; /* Total number of test cases. */
extern int Tst_count; /* Test Case counter for tst_* routines */
/***********************************************************************
* MAIN
***********************************************************************/
int
main(int ac, char **av)
{
int lc; /* loop counter */
const char *ptr; /* message returned from parse_opts */
int i, /* counter */
group, /* return value from Getgid() call */
entries; /* number of group entries */
gid_t gidset[NGROUPS]; /* storage for all group ids */
gid_t cmpset[NGROUPS];
int ret;
int ret2;
int errors = 0;
char msg[500];
/***************************************************************
* parse standard options, and exit if there is an error
***************************************************************/
if ( (ptr=parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL ) {
tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", ptr);
tst_exit();
}
/***************************************************************
* perform global setup for test
***************************************************************/
setup();
/***************************************************************
* check looping state if -c option given
***************************************************************/
for (lc=0; TEST_LOOPING(lc); lc++) {
/* reset Tst_count in case we are looping. */
Tst_count=0;
/*
* Check to see if getgroups() fails on erraneous condition.
*/
TEST( getgroups(-1,gidset) );
if((ret=TEST_RETURN) != -1) {
sprintf(msg,
"getgroups(-1,gidset) returned %d, expected -1 and errno = EINVAL",
ret);
tst_resm(TFAIL,msg);
errors++;
}
else if ( STD_FUNCTIONAL_TEST ) {
if(errno != EINVAL) {
sprintf(msg,
"getgroups(-1,gidset) returned %d, errno = %d, expected errno %d (EINVAL)",
ret, errno, EINVAL);
tst_resm(TFAIL,msg);
errors++;
}
else {
sprintf(msg,
"getgroups(-1,gidset) returned %d and error = %d (EINVAL) as expected",
ret, errno);
tst_resm(TPASS, msg);
}
}
/*
* Check that if ngrps is zero that the number of groups is return and
* the the gidset array is not modified.
* This is a POSIX special case.
*/
memset(gidset, 052, NGROUPS);
memset(cmpset, 052, NGROUPS);
TEST( getgroups(0,gidset) );
if((ret=TEST_RETURN) < 0) {
sprintf(msg,
"getgroups(0,gidset) returned %d with errno = %d, expected num gids with no change to gidset",
ret, errno);
tst_resm(TFAIL,msg);
errors++;
}
else if ( STD_FUNCTIONAL_TEST ) {
/*
* check that gidset was unchanged
*/
if ( memcmp(cmpset, gidset, NGROUPS) != 0 ) {
sprintf(msg,
"getgroups(0,gidset) returned %d, the gidset array was modified",
ret);
tst_resm(TFAIL,msg);
errors++;
}
else {
sprintf(msg,
"getgroups(0,gidset) returned %d, the gidset array not was modified",
ret);
tst_resm(TPASS, msg);
}
}
/*
* Check to see that is -1 is returned and errno is set to EINVAL when
* ngroups is not big enough to hold all groups.
*/
if ( ret <= 1 ) {
sprintf(msg, "getgroups(0,gidset) returned %d, Unable to test that\nusing ngrps >=1 but less than number of grps", ret);
tst_resm(TCONF, msg);
errors++;
}
else {
TEST( getgroups(ret-1, gidset) );
if ((ret2 = TEST_RETURN) == -1 ) {
if ( STD_FUNCTIONAL_TEST ) {
if ( errno != EINVAL ) {
sprintf(msg,
"getgroups(%d, gidset) returned -1, but not errno %d (EINVAL) but %d",
ret-1, EINVAL, errno);
tst_resm(TFAIL, msg);
errors++;
}
else {
sprintf(msg,
"getgroups(%d, gidset) returned -1, and errno %d (EINVAL) when %d grps",
ret-1, errno, ret);
tst_resm(TPASS, msg);
}
}
}
else {
sprintf(msg,
"getgroups(%d, gidset) returned %d, expected -1 and errno EINVAL.",
ret-1, ret2);
tst_resm(TFAIL, msg);
errors++;
}
}
/*
* Check to see if getgroups() succeeds and contains getgid's gid.
*/
TEST( getgroups(NGROUPS,gidset) );
if((entries = TEST_RETURN) == -1) {
sprintf(msg, "getgroups(NGROUPS,gidset) returned -1 and errno = %d", errno);
tst_resm(TFAIL, msg);
errors++;
}
else if ( STD_FUNCTIONAL_TEST ) {
/*
* Check to see if getgroups() contains getgid().
*/
group = getgid();
for(i = 0; i < entries; i++)
{
if(gidset[i] == group)
{
sprintf(msg,
"getgroups(NGROUPS,gidset) ret %d contains gid %d (from getgid)",
entries, group);
tst_resm(TPASS, msg);
break;
}
}
if( i == entries ) {
sprintf(msg,
"getgroups(NGROUPS,gidset) ret %d, does not contain gid %d (from getgid)",
entries, group);
tst_resm(TFAIL,msg);
errors++;
}
}
}
cleanup();
return 0;
} /* end main() */
/***************************************************************
* setup() - performs all ONE TIME setup for this test.
***************************************************************/
void
setup()
{
/* capture signals */
tst_sig(FORK, DEF_HANDLER, cleanup);
/* Pause if that option was specified */
TEST_PAUSE;
} /* End setup() */
/***************************************************************
* cleanup() - performs all ONE TIME cleanup for this test at
* completion or premature exit.
***************************************************************/
void
cleanup()
{
/*
* print timing stats if that option was specified.
* print errno log if that option was specified.
*/
TEST_CLEANUP;
/* exit with return code appropriate for results */
tst_exit();
} /* End cleanup() */