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@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 "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
main(int ac,char ** av)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
setup(void)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
cleanup(void)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