Home | History | Annotate | Download | only in semget
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2001
      4  *
      5  *   This program is free software;  you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     13  *   the GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program;  if not, write to the Free Software
     17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * NAME
     22  *	semget05.c
     23  *
     24  * DESCRIPTION
     25  *	semget05 - test for ENOSPC error
     26  *
     27  * ALGORITHM
     28  *	create semaphore sets in a loop until the system limit is reached
     29  *	loop if that option was specified
     30  *	attempt to create yet another semaphore set
     31  *	check the errno value
     32  *	  issue a PASS message if we get ENOSPC
     33  *	otherwise, the tests fails
     34  *	  issue a FAIL message
     35  *	call cleanup
     36  *
     37  * USAGE:  <for command-line>
     38  * HISTORY
     39  *	03/2001 - Written by Wayne Boyer
     40  *      07/2006 - Changes By Michael Reed
     41  *                - Changed the value of MAXIDS for the specific machine by reading
     42  *                  the system limit for SEMMNI - The maximum number of sempahore sets
     43  *      03/2008 - Matthieu Fertr  (mfertre (at) irisa.fr)
     44  *                - Fix concurrency issue. Create private semaphores to
     45  *                  avoid conflict with concurrent processes.
     46  *
     47  * RESTRICTIONS
     48  *	none
     49  */
     50 
     51 #include "../lib/ipcsem.h"
     52 
     53 char *TCID = "semget05";
     54 int TST_TOTAL = 1;
     55 
     56 /*
     57  * The MAXIDS value is somewhat arbitrary and may need to be increased
     58  * depending on the system being tested.
     59  */
     60 
     61 int MAXIDS = 2048;
     62 
     63 int *sem_id_arr = NULL;
     64 int num_sems = 0;		/* count the semaphores created */
     65 
     66 int main(int ac, char **av)
     67 {
     68 	int lc;
     69 	FILE *fp;
     70 
     71 	tst_parse_opts(ac, av, NULL, NULL);
     72 
     73 	/* Set the MAXIDS for the specific machine by reading the system limit
     74 	 * for SEMMNI - The maximum number of sempahore sets
     75 	 */
     76 	fp = fopen("/proc/sys/kernel/sem", "r");
     77 	if (fp != NULL) {
     78 		int getmaxid;
     79 		if (fscanf(fp, "%*d %*d %*d %d", &getmaxid) == 1)
     80 			MAXIDS = getmaxid + 1;
     81 		fclose(fp);
     82 	}
     83 
     84 	sem_id_arr = malloc(sizeof(int) * MAXIDS);
     85 	if (sem_id_arr == NULL)
     86 		tst_brkm(TBROK, cleanup, "malloc failed");
     87 
     88 	setup();
     89 
     90 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     91 		tst_count = 0;
     92 
     93 
     94 		TEST(semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
     95 		if (TEST_RETURN != -1) {
     96 			tst_resm(TFAIL, "call succeeded when error expected");
     97 			continue;
     98 		}
     99 
    100 		switch (TEST_ERRNO) {
    101 		case ENOSPC:
    102 			tst_resm(TPASS, "expected failure - errno "
    103 				 "= %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
    104 			break;
    105 		default:
    106 			tst_resm(TFAIL, "unexpected error - %d : %s",
    107 				 TEST_ERRNO, strerror(TEST_ERRNO));
    108 			break;
    109 		}
    110 	}
    111 
    112 	cleanup();
    113 
    114 	tst_exit();
    115 }
    116 
    117 void setup(void)
    118 {
    119 	int sem_q;
    120 
    121 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    122 
    123 	TEST_PAUSE;
    124 
    125 	tst_tmpdir();
    126 
    127 	while ((sem_q = semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL)) != -1) {
    128 		sem_id_arr[num_sems++] = sem_q;
    129 		if (num_sems == MAXIDS) {
    130 			tst_brkm(TBROK, cleanup, "The maximum number of "
    131 				 "semaphore ID's has been\n\t reached.  Please "
    132 				 "increase the MAXIDS value in the test.");
    133 		}
    134 	}
    135 
    136 	if (errno != ENOSPC) {
    137 		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup"
    138 			 " - errno = %d : %s", errno, strerror(errno));
    139 	}
    140 }
    141 
    142 void cleanup(void)
    143 {
    144 	int i;
    145 
    146 	for (i = 0; i < num_sems; i++) {
    147 		rm_sema(sem_id_arr[i]);
    148 	}
    149 
    150 	free(sem_id_arr);
    151 	tst_rmdir();
    152 }
    153