blob: ec6109d30e86eff4c6f0289873b8629576ca4026 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * semctl01.c
23 *
24 * DESCRIPTION
25 * semctl01 - test the 10 possible semctl() commands
26 *
27 * ALGORITHM
28 * create a semaphore set with read and alter permissions
29 * loop if that option was specified
30 * loop through the test cases
31 * do any setup required for the test case
32 * make the semctl() call using the TEST() macro
33 * check the return code
34 * if failure, issue a FAIL message.
35 * otherwise,
36 * if doing functionality testing
37 * call the appropriate test function
38 * if correct,
39 * issue a PASS message
40 * otherwise
41 * issue a FAIL message
42 * call cleanup
43 *
44 * USAGE: <for command-line>
45 * semctl01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
46 * where, -c n : Run n copies concurrently.
47 * -f : Turn off functionality Testing.
48 * -i n : Execute test n times.
49 * -I x : Execute test for x seconds.
50 * -P x : Pause for x seconds between iterations.
51 * -t : Turn on syscall timing.
52 *
53 * HISTORY
54 * 03/2001 - Written by Wayne Boyer
55 *
subrata_modak41399ed2008-03-14 19:16:23 +000056 * 11/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
57 * - Fix concurrency issue. Due to the use of usleep function to
58 * synchronize processes, synchronization issues can occur on a loaded
59 * system. Fix this by using pipes to synchronize processes.
60 *
plars865695b2001-08-27 22:15:12 +000061 * RESTRICTIONS
62 * none
63 */
64
robbiew23499f02002-11-18 19:54:58 +000065#include "ipcsem.h"
subrata_modak41399ed2008-03-14 19:16:23 +000066#include "libtestsuite.h"
plars865695b2001-08-27 22:15:12 +000067
68char *TCID = "semctl01";
69int TST_TOTAL = 10;
plars865695b2001-08-27 22:15:12 +000070
subrata_modak56207ce2009-03-23 13:35:39 +000071int sem_id_1 = -1; /* a semaphore set with read and alter permissions */
plars865695b2001-08-27 22:15:12 +000072
subrata_modak4b13c892009-01-22 09:51:33 +000073int sync_pipes[2];
74
plars865695b2001-08-27 22:15:12 +000075/*
76 * These are the various setup and check functions for the 10 different
77 * commands that are available for the semctl() call.
78 */
79void func_stat(void);
80void set_setup(void), func_set(void);
81void func_gall(void);
82void cnt_setup(int), func_cnt(int);
83void pid_setup(void), func_pid(int);
84void gval_setup(void), func_gval(int);
85void sall_setup(void), func_sall(void);
86void func_sval(void);
87void func_rmid(void);
robbiewd34d5812005-07-11 22:28:09 +000088void child_cnt(void);
89void child_pid(void);
plars865695b2001-08-27 22:15:12 +000090
91struct semid_ds buf;
92unsigned short array[PSEMS];
93struct sembuf sops;
94
subrata_modak56207ce2009-03-23 13:35:39 +000095#define INCVAL 2 /* a semaphore increment value */
plars865695b2001-08-27 22:15:12 +000096#define NEWMODE 066
97#define NCHILD 5
subrata_modak56207ce2009-03-23 13:35:39 +000098#define SEM2 2 /* semaphore to use for GETPID and GETVAL */
99#define SEM4 4 /* semaphore to use for GETNCNT and GETZCNT */
plars865695b2001-08-27 22:15:12 +0000100#define ONE 1
mridgef7298c72005-12-05 19:14:37 +0000101#ifdef _XLC_COMPILER
subrata_modak4bb656a2009-02-26 12:02:09 +0000102#define SEMUN_CAST
mridgef7298c72005-12-05 19:14:37 +0000103#else
104#define SEMUN_CAST (union semun)
105#endif
106
107#ifdef _XLC_COMPILER
108#define SEMUN_CAST
109#else
110#define SEMUN_CAST (union semun)
111#endif
plars865695b2001-08-27 22:15:12 +0000112
113int pid_arr[NCHILD];
114
robbiewd34d5812005-07-11 22:28:09 +0000115#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +0000116#define PIPE_NAME "semctl01"
robbiewd34d5812005-07-11 22:28:09 +0000117static char *argv0;
subrata_modak4b13c892009-01-22 09:51:33 +0000118int sem_op;
robbiewd34d5812005-07-11 22:28:09 +0000119#endif
120
plars865695b2001-08-27 22:15:12 +0000121struct test_case_t {
122 int semnum; /* the primitive semaphore to use */
123 int cmd; /* the command to test */
subrata_modak56207ce2009-03-23 13:35:39 +0000124 void (*func_test) (); /* the test function */
plars865695b2001-08-27 22:15:12 +0000125 union semun arg;
subrata_modak56207ce2009-03-23 13:35:39 +0000126 void (*func_setup) (); /* the setup function if necessary */
plars865695b2001-08-27 22:15:12 +0000127} TC[] = {
subrata_modak56207ce2009-03-23 13:35:39 +0000128 {
129 0, IPC_STAT, func_stat, SEMUN_CAST & buf, NULL}, {
130 0, IPC_SET, func_set, SEMUN_CAST & buf, set_setup}, {
131 0, GETALL, func_gall, SEMUN_CAST array, NULL}, {
132 SEM4, GETNCNT, func_cnt, SEMUN_CAST & buf, cnt_setup}, {
133 SEM2, GETPID, func_pid, SEMUN_CAST & buf, pid_setup}, {
134 SEM2, GETVAL, func_gval, SEMUN_CAST & buf, NULL}, {
135 SEM4, GETZCNT, func_cnt, SEMUN_CAST & buf, cnt_setup}, {
136 0, SETALL, func_sall, SEMUN_CAST array, sall_setup}, {
137 SEM4, SETVAL, func_sval, SEMUN_CAST INCVAL, NULL}, {
138 0, IPC_RMID, func_rmid, SEMUN_CAST & buf, NULL}
plars865695b2001-08-27 22:15:12 +0000139};
140
robbiew23499f02002-11-18 19:54:58 +0000141int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000142{
subrata_modak56207ce2009-03-23 13:35:39 +0000143 int lc; /* loop counter */
144 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +0000145 int i, j;
146
147 /* parse standard options */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800148 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800149 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000150 }
robbiewd34d5812005-07-11 22:28:09 +0000151#ifdef UCLINUX
152 argv0 = av[0];
153 maybe_run_child(&child_pid, "nd", 1, &sem_id_1);
subrata_modak4b13c892009-01-22 09:51:33 +0000154 maybe_run_child(&child_cnt, "ndd", 2, &sem_id_1, &sem_op);
robbiewd34d5812005-07-11 22:28:09 +0000155#endif
156
subrata_modak56207ce2009-03-23 13:35:39 +0000157 setup(); /* global setup */
plars865695b2001-08-27 22:15:12 +0000158
159 /* The following loop checks looping state if -i option given */
160
161 for (lc = 0; TEST_LOOPING(lc); lc++) {
162 /* reset Tst_count in case we are looping */
163 Tst_count = 0;
164
165 /* loop through the test cases */
subrata_modak56207ce2009-03-23 13:35:39 +0000166 for (i = 0; i < TST_TOTAL; i++) {
plars865695b2001-08-27 22:15:12 +0000167
168 /*
169 * Set up any conditions if needed
170 */
plars865695b2001-08-27 22:15:12 +0000171 if (TC[i].func_setup != NULL) {
172 /* call the setup function */
173 switch (TC[i].cmd) {
174 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000175 (*TC[i].func_setup) (-ONE);
plars865695b2001-08-27 22:15:12 +0000176 break;
177 case GETZCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000178 (*TC[i].func_setup) (0);
plars865695b2001-08-27 22:15:12 +0000179 break;
180 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000181 (*TC[i].func_setup) ();
plars865695b2001-08-27 22:15:12 +0000182 break;
183 }
184 }
185
186 /*
187 * Use TEST macro to make the call
188 */
189
190 TEST(semctl(sem_id_1, TC[i].semnum, TC[i].cmd,
191 TC[i].arg));
subrata_modakbdbaec52009-02-26 12:14:51 +0000192
plars865695b2001-08-27 22:15:12 +0000193 if (TEST_RETURN == -1) {
194 tst_resm(TFAIL, "%s call failed - errno = %d "
195 ": %s", TCID, TEST_ERRNO,
196 strerror(TEST_ERRNO));
197 } else {
198 if (STD_FUNCTIONAL_TEST) {
199 /*
200 * call the appropriate test function
201 * and pass the return value where it
202 * is needed to perform certain tests.
203 */
204 switch (TC[i].cmd) {
205 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000206 /*FALLTHROUGH*/ case GETZCNT:
207 /*FALLTHROUGH*/ case GETPID:
208 /*FALLTHROUGH*/ case GETVAL:
209 (*TC[i].
210 func_test) (TEST_RETURN);
plars865695b2001-08-27 22:15:12 +0000211 break;
212 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000213 (*TC[i].func_test) ();
plars865695b2001-08-27 22:15:12 +0000214 break;
215 }
216 } else {
217 tst_resm(TPASS, "call succeeded");
218 }
219 }
220
221 /*
222 * If testing GETNCNT or GETZCNT, clean up the children.
223 */
224 switch (TC[i].cmd) {
225 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000226 /*FALLTHROUGH*/ case GETZCNT:
227 for (j = 0; j < NCHILD; j++) {
plars865695b2001-08-27 22:15:12 +0000228 if (kill(pid_arr[j], SIGKILL) == -1) {
229 tst_brkm(TBROK, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000230 "child kill failed");
plars865695b2001-08-27 22:15:12 +0000231 }
232 }
233 break;
234 }
235 }
236 /*
237 * recreate the semaphore resource if looping
238 */
239 if (TEST_LOOPING(lc)) {
240 if ((sem_id_1 = semget(semkey, PSEMS,
subrata_modak56207ce2009-03-23 13:35:39 +0000241 IPC_CREAT | IPC_EXCL | SEM_RA))
242 == -1) {
243 tst_brkm(TBROK, cleanup,
244 "couldn't recreate " "semaphore");
plars865695b2001-08-27 22:15:12 +0000245 }
246 }
247 }
248
249 cleanup();
250
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800251 tst_exit();
robbiew23499f02002-11-18 19:54:58 +0000252
plars865695b2001-08-27 22:15:12 +0000253}
254
255/*
256 * func_stat() - check the functionality of the IPC_STAT command with semctl()
257 */
subrata_modak56207ce2009-03-23 13:35:39 +0000258void func_stat()
plars865695b2001-08-27 22:15:12 +0000259{
260 /* check the number of semaphores and the ipc_perm.mode value */
robbiew23499f02002-11-18 19:54:58 +0000261 if (buf.sem_nsems == PSEMS && buf.sem_perm.mode == (SEM_RA)) {
plars865695b2001-08-27 22:15:12 +0000262 tst_resm(TPASS, "buf.sem_nsems and buf.sem_perm.mode"
subrata_modak56207ce2009-03-23 13:35:39 +0000263 " are correct");
plars865695b2001-08-27 22:15:12 +0000264 } else {
265 tst_resm(TFAIL, "semaphore STAT info is incorrect");
266 }
267}
268
269/*
270 * set_setup() - set up for the IPC_SET command with semctl()
271 */
subrata_modak56207ce2009-03-23 13:35:39 +0000272void set_setup()
plars865695b2001-08-27 22:15:12 +0000273{
274 /* set up a new mode for the semaphore set */
275 buf.sem_perm.mode = SEM_RA | NEWMODE;
276}
277
278/*
279 * func_set() - check the functionality of the IPC_SET command with semctl()
280 */
subrata_modak56207ce2009-03-23 13:35:39 +0000281void func_set()
plars865695b2001-08-27 22:15:12 +0000282{
283 /* first stat the semaphore to get the new data */
284 if (semctl(sem_id_1, 0, IPC_STAT, (union semun)&buf) == -1) {
285 tst_resm(TBROK, "stat failed in func_set()");
286 return;
287 }
288
289 /* check that the new mode is what we set */
robbiew23499f02002-11-18 19:54:58 +0000290 if (buf.sem_perm.mode == (SEM_RA | NEWMODE)) {
plars865695b2001-08-27 22:15:12 +0000291 tst_resm(TPASS, "buf.sem_perm.mode is correct");
292 } else {
293 tst_resm(TFAIL, "semaphore mode info is incorrect");
294 }
295}
296
297/*
298 * func_gall() - check the functionality of the GETALL command with semctl()
299 */
subrata_modak56207ce2009-03-23 13:35:39 +0000300void func_gall()
plars865695b2001-08-27 22:15:12 +0000301{
302 int i;
303
304 /* the initial value of the primitive semaphores should be zero */
subrata_modak56207ce2009-03-23 13:35:39 +0000305 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000306 if (array[i] != 0) {
307 tst_resm(TFAIL, "semaphore %d has unexpected value", i);
308 return;
309 }
310 }
311 tst_resm(TPASS, "semaphores have expected values");
312}
313
314/*
315 * cnt_setup() - set up for the GETNCNT and GETZCNT commands with semctl()
316 */
subrata_modak56207ce2009-03-23 13:35:39 +0000317void cnt_setup(int opval)
plars865695b2001-08-27 22:15:12 +0000318{
319 int pid, i;
320
321 sops.sem_num = SEM4;
322 sops.sem_flg = 0;
323
324 /*
325 * if seting up for GETZCNT, the semaphore value needs to be positive
326 */
327 if (opval == 0) {
328 /* initialize the semaphore value to ONE */
329 sops.sem_op = ONE;
330 if (semop(sem_id_1, &sops, 1) == -1) {
331 tst_brkm(TBROK, cleanup, "semop #1 failed - cnt_setup");
332 }
333 }
334
335 sops.sem_op = opval; /* set the correct operation */
subrata_modak56207ce2009-03-23 13:35:39 +0000336 for (i = 0; i < NCHILD; i++) {
subrata_modak4b13c892009-01-22 09:51:33 +0000337 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
subrata_modak8791f672008-05-20 10:11:00 +0000338 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000339
plars865695b2001-08-27 22:15:12 +0000340 /* fork five children to wait */
subrata_modak8791f672008-05-20 10:11:00 +0000341 if ((pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +0000342 tst_brkm(TBROK, cleanup, "fork failed in cnt_setup");
subrata_modakbdbaec52009-02-26 12:14:51 +0000343
subrata_modak56207ce2009-03-23 13:35:39 +0000344 if (pid == 0) { /* child */
robbiewd34d5812005-07-11 22:28:09 +0000345#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +0000346 sem_op = sops.sem_op;
subrata_modak56207ce2009-03-23 13:35:39 +0000347 if (self_exec(argv0, "ndd", 2, sem_id_1, sem_op) < 0) {
robbiewd34d5812005-07-11 22:28:09 +0000348 tst_brkm(TBROK, cleanup, "self_exec failed "
349 "in cnt_setup");
plars865695b2001-08-27 22:15:12 +0000350 }
robbiewd34d5812005-07-11 22:28:09 +0000351#else
352 child_cnt();
353#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000354 } else { /* parent */
subrata_modak8791f672008-05-20 10:11:00 +0000355 if (sync_pipe_wait(sync_pipes) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000356 tst_brkm(TBROK, cleanup,
357 "sync_pipe_wait failed");
subrata_modak8791f672008-05-20 10:11:00 +0000358
subrata_modak4b13c892009-01-22 09:51:33 +0000359 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000360 tst_brkm(TBROK, cleanup,
361 "sync_pipe_close failed");
plars865695b2001-08-27 22:15:12 +0000362
363 /* save the pid so we can kill it later */
364 pid_arr[i] = pid;
365 }
366 }
subrata_modak41399ed2008-03-14 19:16:23 +0000367 /* After last son has been created, give it a chance to execute the
368 * semop command before we continue. Without this sleep, on SMP machine
369 * the father semctl could be executed before the son semop.
370 */
371 sleep(1);
plars865695b2001-08-27 22:15:12 +0000372}
373
subrata_modak56207ce2009-03-23 13:35:39 +0000374void child_cnt()
robbiewd34d5812005-07-11 22:28:09 +0000375{
subrata_modak4b13c892009-01-22 09:51:33 +0000376#ifdef UCLINUX
377 sops.sem_op = (short int)sem_op;
378 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
379 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
380#endif
381
382 if (sync_pipe_notify(sync_pipes) == -1)
383 tst_brkm(TBROK, cleanup, "sync_pipe_notify failed");
384
Subrata Modak9e365e82010-07-03 23:13:41 +0530385#ifdef UCLINUX
386 if (sync_pipe_close(sync_pipes, NULL) == -1)
387#else
subrata_modak4b13c892009-01-22 09:51:33 +0000388 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
Subrata Modak9e365e82010-07-03 23:13:41 +0530389#endif
subrata_modak4b13c892009-01-22 09:51:33 +0000390 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
391
robbiewd34d5812005-07-11 22:28:09 +0000392 sops.sem_num = SEM4;
393 sops.sem_flg = 0;
394
395 /*
396 * Do a semop that will cause the child to sleep.
397 * The child process will be killed in the func_ncnt
398 * routine which should cause an error to be return
399 * by the semop() call.
400 */
401 if (semop(sem_id_1, &sops, 1) != -1) {
402 tst_resm(TBROK, "semop succeeded - cnt_setup");
403 }
404 exit(0);
405}
406
plars865695b2001-08-27 22:15:12 +0000407/*
408 * func_cnt() - check the functionality of the GETNCNT and GETZCNT commands
409 * with semctl()
410 */
subrata_modak56207ce2009-03-23 13:35:39 +0000411void func_cnt(int rval)
plars865695b2001-08-27 22:15:12 +0000412{
plars865695b2001-08-27 22:15:12 +0000413
414 if (rval == NCHILD) {
415 tst_resm(TPASS, "number of sleeping processes is correct");
416 } else {
417 tst_resm(TFAIL, "number of sleeping processes is not correct");
418 }
419}
420
421/*
422 * pid_setup() - set up for the GETPID command with semctl()
423 */
subrata_modak56207ce2009-03-23 13:35:39 +0000424void pid_setup()
plars865695b2001-08-27 22:15:12 +0000425{
426 int pid;
subrata_modak41399ed2008-03-14 19:16:23 +0000427
subrata_modak4b13c892009-01-22 09:51:33 +0000428 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) {
subrata_modak8791f672008-05-20 10:11:00 +0000429 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000430 }
plars865695b2001-08-27 22:15:12 +0000431
plars865695b2001-08-27 22:15:12 +0000432 /*
subrata_modak4bb656a2009-02-26 12:02:09 +0000433 * Fork a child to do a semop that will pass.
plars865695b2001-08-27 22:15:12 +0000434 */
robbiewd34d5812005-07-11 22:28:09 +0000435 if ((pid = FORK_OR_VFORK()) == -1) {
plars865695b2001-08-27 22:15:12 +0000436 tst_brkm(TBROK, cleanup, "fork failed in pid_setup()");
437 }
robbiewd34d5812005-07-11 22:28:09 +0000438
plars865695b2001-08-27 22:15:12 +0000439 if (pid == 0) { /* child */
robbiewd34d5812005-07-11 22:28:09 +0000440#ifdef UCLINUX
441 if (self_exec(argv0, "nd", 1, sem_id_1) < 0) {
442 tst_brkm(TBROK, cleanup, "self_exec failed "
443 "in pid_setup()");
plars865695b2001-08-27 22:15:12 +0000444 }
robbiewd34d5812005-07-11 22:28:09 +0000445#else
446 child_pid();
447#endif
plars865695b2001-08-27 22:15:12 +0000448 } else { /* parent */
subrata_modak8791f672008-05-20 10:11:00 +0000449 if (sync_pipe_wait(sync_pipes) == -1)
450 tst_brkm(TBROK, cleanup, "sync_pipe_wait failed");
451
subrata_modak4b13c892009-01-22 09:51:33 +0000452 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
subrata_modak8791f672008-05-20 10:11:00 +0000453 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000454 sleep(1);
plars865695b2001-08-27 22:15:12 +0000455 pid_arr[SEM2] = pid;
456 }
457}
458
subrata_modak56207ce2009-03-23 13:35:39 +0000459void child_pid()
robbiewd34d5812005-07-11 22:28:09 +0000460{
subrata_modak4b13c892009-01-22 09:51:33 +0000461#ifdef UCLINUX
462 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
463 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
464#endif
465
466 if (sync_pipe_notify(sync_pipes) == -1)
467 tst_brkm(TBROK, cleanup, "sync_pipe_notify failed");
468
469 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
470 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
471
robbiewd34d5812005-07-11 22:28:09 +0000472 sops.sem_num = SEM2; /* semaphore to change */
473 sops.sem_op = ONE; /* operation is to increment semaphore */
474 sops.sem_flg = 0;
475
476 /*
477 * Do a semop that will increment the semaphore.
478 */
479 if (semop(sem_id_1, &sops, 1) == -1) {
480 tst_resm(TBROK, "semop failed - pid_setup");
481 }
482 exit(0);
483}
484
plars865695b2001-08-27 22:15:12 +0000485/*
486 * func_pid() - check the functionality of the GETPID command with semctl()
487 */
subrata_modak56207ce2009-03-23 13:35:39 +0000488void func_pid(int rval)
plars865695b2001-08-27 22:15:12 +0000489{
490 /* compare the rval (pid) to the saved pid from the setup */
491 if (rval == pid_arr[SEM2]) {
492 tst_resm(TPASS, "last pid value is correct");
493 } else {
494 tst_resm(TFAIL, "last pid value is not correct");
495 }
496}
497
498/*
499 * func_gval() - check the functionality of the GETVAL command with semctl()
500 */
subrata_modak56207ce2009-03-23 13:35:39 +0000501void func_gval(int rval)
plars865695b2001-08-27 22:15:12 +0000502{
503 /*
504 * This is a simple test. The semaphore value should be equal
505 * to ONE as it was set in the last test (GETPID).
506 */
507 if (rval == 1) {
508 tst_resm(TPASS, "semaphore value is correct");
509 } else {
510 tst_resm(TFAIL, "semaphore value is not correct");
511 }
512
513}
514
515/*
516 * all_setup() - set up for the SETALL command with semctl()
517 */
subrata_modak56207ce2009-03-23 13:35:39 +0000518void sall_setup()
plars865695b2001-08-27 22:15:12 +0000519{
520 int i;
521
subrata_modak56207ce2009-03-23 13:35:39 +0000522 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000523 /* initialize the array values to 3 */
524 array[i] = 3;
525 }
526}
527
528/*
529 * func_sall() - check the functionality of the SETALL command with semctl()
530 */
subrata_modak56207ce2009-03-23 13:35:39 +0000531void func_sall()
plars865695b2001-08-27 22:15:12 +0000532{
533 int i;
534 unsigned short rarray[PSEMS];
535
536 /*
537 * do a GETALL and compare the values to those set above
538 */
539
540 if (semctl(sem_id_1, 0, GETALL, (union semun)rarray) == -1) {
541 tst_brkm(TBROK, cleanup, "semctl failed in func_sall");
542 }
543
subrata_modak56207ce2009-03-23 13:35:39 +0000544 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000545 if (array[i] != rarray[i]) {
546 tst_resm(TFAIL, "semaphore values are not correct");
547 return;
548 }
549 }
550
551 tst_resm(TPASS, "semaphore values are correct");
552}
553
554/*
555 * func_sval() - check the functionality of the SETVAL command with semctl()
556 */
subrata_modak56207ce2009-03-23 13:35:39 +0000557void func_sval()
plars865695b2001-08-27 22:15:12 +0000558{
559 int semv;
iyermanoje2cb9cd2002-01-21 18:48:13 +0000560 union semun arr;
plars865695b2001-08-27 22:15:12 +0000561
562 /*
563 * do a GETVAL and compare it to the value set above
564 */
565
iyermanoje2cb9cd2002-01-21 18:48:13 +0000566 if ((semv = semctl(sem_id_1, SEM4, GETVAL, arr)) == -1) {
plars865695b2001-08-27 22:15:12 +0000567 tst_brkm(TBROK, cleanup, "semctl failed in func_sval");
568 }
569
570 if (semv != INCVAL) {
571 tst_resm(TFAIL, "semaphore value is not what was set");
572 } else {
573 tst_resm(TPASS, "semaphore value is correct");
574 }
575}
576
577/*
578 * func_rmid() - check the functionality of the IPC_RMID command with semctl()
579 */
subrata_modak56207ce2009-03-23 13:35:39 +0000580void func_rmid()
plars865695b2001-08-27 22:15:12 +0000581{
582
583 /*
584 * do a semop() - we should get EINVAL
585 */
586 if (semop(sem_id_1, &sops, 1) != -1) {
587 tst_resm(TFAIL, "semop succeeded on expected fail");
588 }
589
590 if (errno != EINVAL) {
591 tst_resm(TFAIL, "returned errno - %d - is not expected", errno);
592 } else {
593 tst_resm(TPASS, "semaphore appears to be removed");
594 }
595
596 sem_id_1 = -1;
597}
598
599/*
600 * setup() - performs all the ONE TIME setup for this test.
601 */
subrata_modak56207ce2009-03-23 13:35:39 +0000602void setup(void)
plars865695b2001-08-27 22:15:12 +0000603{
Garrett Cooper2c282152010-12-16 00:55:50 -0800604
plars865695b2001-08-27 22:15:12 +0000605 tst_sig(FORK, DEF_HANDLER, cleanup);
606
plars865695b2001-08-27 22:15:12 +0000607 TEST_PAUSE;
608
609 /*
610 * Create a temporary directory and cd into it.
611 * This helps to ensure that a unique msgkey is created.
612 * See ../lib/libipc.c for more information.
613 */
614 tst_tmpdir();
615
616 /* get an IPC resource key */
617 semkey = getipckey();
618
619 /* create a semaphore set with read and alter permissions */
620 if ((sem_id_1 =
subrata_modak56207ce2009-03-23 13:35:39 +0000621 semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA)) == -1) {
plars865695b2001-08-27 22:15:12 +0000622 tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
623 }
624}
625
626/*
627 * cleanup() - performs all the ONE TIME cleanup for this test at completion
628 * or premature exit.
629 */
subrata_modak56207ce2009-03-23 13:35:39 +0000630void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000631{
632 /* if it exists, remove the semaphore resource */
633 rm_sema(sem_id_1);
634
plars865695b2001-08-27 22:15:12 +0000635 tst_rmdir();
636
637 /*
638 * print timing stats if that option was specified.
639 * print errno log if that option was specified.
640 */
641 TEST_CLEANUP;
642
Chris Dearmanec6edca2012-10-17 19:54:01 -0700643}