blob: a071800a280bb6543412c3bb97e9b93c291b41b1 [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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
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;
70extern int Tst_count;
71
subrata_modak56207ce2009-03-23 13:35:39 +000072int sem_id_1 = -1; /* a semaphore set with read and alter permissions */
plars865695b2001-08-27 22:15:12 +000073
subrata_modak4b13c892009-01-22 09:51:33 +000074int sync_pipes[2];
75
plars865695b2001-08-27 22:15:12 +000076/*
77 * These are the various setup and check functions for the 10 different
78 * commands that are available for the semctl() call.
79 */
80void func_stat(void);
81void set_setup(void), func_set(void);
82void func_gall(void);
83void cnt_setup(int), func_cnt(int);
84void pid_setup(void), func_pid(int);
85void gval_setup(void), func_gval(int);
86void sall_setup(void), func_sall(void);
87void func_sval(void);
88void func_rmid(void);
robbiewd34d5812005-07-11 22:28:09 +000089void child_cnt(void);
90void child_pid(void);
plars865695b2001-08-27 22:15:12 +000091
92struct semid_ds buf;
93unsigned short array[PSEMS];
94struct sembuf sops;
95
subrata_modak56207ce2009-03-23 13:35:39 +000096#define INCVAL 2 /* a semaphore increment value */
plars865695b2001-08-27 22:15:12 +000097#define NEWMODE 066
98#define NCHILD 5
subrata_modak56207ce2009-03-23 13:35:39 +000099#define SEM2 2 /* semaphore to use for GETPID and GETVAL */
100#define SEM4 4 /* semaphore to use for GETNCNT and GETZCNT */
plars865695b2001-08-27 22:15:12 +0000101#define ONE 1
mridgef7298c72005-12-05 19:14:37 +0000102#ifdef _XLC_COMPILER
subrata_modak4bb656a2009-02-26 12:02:09 +0000103#define SEMUN_CAST
mridgef7298c72005-12-05 19:14:37 +0000104#else
105#define SEMUN_CAST (union semun)
106#endif
107
108#ifdef _XLC_COMPILER
109#define SEMUN_CAST
110#else
111#define SEMUN_CAST (union semun)
112#endif
plars865695b2001-08-27 22:15:12 +0000113
114int pid_arr[NCHILD];
115
robbiewd34d5812005-07-11 22:28:09 +0000116#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +0000117#define PIPE_NAME "semctl01"
robbiewd34d5812005-07-11 22:28:09 +0000118static char *argv0;
subrata_modak4b13c892009-01-22 09:51:33 +0000119int sem_op;
robbiewd34d5812005-07-11 22:28:09 +0000120#endif
121
plars865695b2001-08-27 22:15:12 +0000122struct test_case_t {
123 int semnum; /* the primitive semaphore to use */
124 int cmd; /* the command to test */
subrata_modak56207ce2009-03-23 13:35:39 +0000125 void (*func_test) (); /* the test function */
plars865695b2001-08-27 22:15:12 +0000126 union semun arg;
subrata_modak56207ce2009-03-23 13:35:39 +0000127 void (*func_setup) (); /* the setup function if necessary */
plars865695b2001-08-27 22:15:12 +0000128} TC[] = {
subrata_modak56207ce2009-03-23 13:35:39 +0000129 {
130 0, IPC_STAT, func_stat, SEMUN_CAST & buf, NULL}, {
131 0, IPC_SET, func_set, SEMUN_CAST & buf, set_setup}, {
132 0, GETALL, func_gall, SEMUN_CAST array, NULL}, {
133 SEM4, GETNCNT, func_cnt, SEMUN_CAST & buf, cnt_setup}, {
134 SEM2, GETPID, func_pid, SEMUN_CAST & buf, pid_setup}, {
135 SEM2, GETVAL, func_gval, SEMUN_CAST & buf, NULL}, {
136 SEM4, GETZCNT, func_cnt, SEMUN_CAST & buf, cnt_setup}, {
137 0, SETALL, func_sall, SEMUN_CAST array, sall_setup}, {
138 SEM4, SETVAL, func_sval, SEMUN_CAST INCVAL, NULL}, {
139 0, IPC_RMID, func_rmid, SEMUN_CAST & buf, NULL}
plars865695b2001-08-27 22:15:12 +0000140};
141
robbiew23499f02002-11-18 19:54:58 +0000142int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000143{
subrata_modak56207ce2009-03-23 13:35:39 +0000144 int lc; /* loop counter */
145 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +0000146 int i, j;
147
148 /* parse standard options */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800149 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800150 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000151 }
robbiewd34d5812005-07-11 22:28:09 +0000152#ifdef UCLINUX
153 argv0 = av[0];
154 maybe_run_child(&child_pid, "nd", 1, &sem_id_1);
subrata_modak4b13c892009-01-22 09:51:33 +0000155 maybe_run_child(&child_cnt, "ndd", 2, &sem_id_1, &sem_op);
robbiewd34d5812005-07-11 22:28:09 +0000156#endif
157
subrata_modak56207ce2009-03-23 13:35:39 +0000158 setup(); /* global setup */
plars865695b2001-08-27 22:15:12 +0000159
160 /* The following loop checks looping state if -i option given */
161
162 for (lc = 0; TEST_LOOPING(lc); lc++) {
163 /* reset Tst_count in case we are looping */
164 Tst_count = 0;
165
166 /* loop through the test cases */
subrata_modak56207ce2009-03-23 13:35:39 +0000167 for (i = 0; i < TST_TOTAL; i++) {
plars865695b2001-08-27 22:15:12 +0000168
169 /*
170 * Set up any conditions if needed
171 */
plars865695b2001-08-27 22:15:12 +0000172 if (TC[i].func_setup != NULL) {
173 /* call the setup function */
174 switch (TC[i].cmd) {
175 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000176 (*TC[i].func_setup) (-ONE);
plars865695b2001-08-27 22:15:12 +0000177 break;
178 case GETZCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000179 (*TC[i].func_setup) (0);
plars865695b2001-08-27 22:15:12 +0000180 break;
181 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000182 (*TC[i].func_setup) ();
plars865695b2001-08-27 22:15:12 +0000183 break;
184 }
185 }
186
187 /*
188 * Use TEST macro to make the call
189 */
190
191 TEST(semctl(sem_id_1, TC[i].semnum, TC[i].cmd,
192 TC[i].arg));
subrata_modakbdbaec52009-02-26 12:14:51 +0000193
plars865695b2001-08-27 22:15:12 +0000194 if (TEST_RETURN == -1) {
195 tst_resm(TFAIL, "%s call failed - errno = %d "
196 ": %s", TCID, TEST_ERRNO,
197 strerror(TEST_ERRNO));
198 } else {
199 if (STD_FUNCTIONAL_TEST) {
200 /*
201 * call the appropriate test function
202 * and pass the return value where it
203 * is needed to perform certain tests.
204 */
205 switch (TC[i].cmd) {
206 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000207 /*FALLTHROUGH*/ case GETZCNT:
208 /*FALLTHROUGH*/ case GETPID:
209 /*FALLTHROUGH*/ case GETVAL:
210 (*TC[i].
211 func_test) (TEST_RETURN);
plars865695b2001-08-27 22:15:12 +0000212 break;
213 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000214 (*TC[i].func_test) ();
plars865695b2001-08-27 22:15:12 +0000215 break;
216 }
217 } else {
218 tst_resm(TPASS, "call succeeded");
219 }
220 }
221
222 /*
223 * If testing GETNCNT or GETZCNT, clean up the children.
224 */
225 switch (TC[i].cmd) {
226 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000227 /*FALLTHROUGH*/ case GETZCNT:
228 for (j = 0; j < NCHILD; j++) {
plars865695b2001-08-27 22:15:12 +0000229 if (kill(pid_arr[j], SIGKILL) == -1) {
230 tst_brkm(TBROK, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000231 "child kill failed");
plars865695b2001-08-27 22:15:12 +0000232 }
233 }
234 break;
235 }
236 }
237 /*
238 * recreate the semaphore resource if looping
239 */
240 if (TEST_LOOPING(lc)) {
241 if ((sem_id_1 = semget(semkey, PSEMS,
subrata_modak56207ce2009-03-23 13:35:39 +0000242 IPC_CREAT | IPC_EXCL | SEM_RA))
243 == -1) {
244 tst_brkm(TBROK, cleanup,
245 "couldn't recreate " "semaphore");
plars865695b2001-08-27 22:15:12 +0000246 }
247 }
248 }
249
250 cleanup();
251
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800252 tst_exit();
robbiew23499f02002-11-18 19:54:58 +0000253
plars865695b2001-08-27 22:15:12 +0000254}
255
256/*
257 * func_stat() - check the functionality of the IPC_STAT command with semctl()
258 */
subrata_modak56207ce2009-03-23 13:35:39 +0000259void func_stat()
plars865695b2001-08-27 22:15:12 +0000260{
261 /* check the number of semaphores and the ipc_perm.mode value */
robbiew23499f02002-11-18 19:54:58 +0000262 if (buf.sem_nsems == PSEMS && buf.sem_perm.mode == (SEM_RA)) {
plars865695b2001-08-27 22:15:12 +0000263 tst_resm(TPASS, "buf.sem_nsems and buf.sem_perm.mode"
subrata_modak56207ce2009-03-23 13:35:39 +0000264 " are correct");
plars865695b2001-08-27 22:15:12 +0000265 } else {
266 tst_resm(TFAIL, "semaphore STAT info is incorrect");
267 }
268}
269
270/*
271 * set_setup() - set up for the IPC_SET command with semctl()
272 */
subrata_modak56207ce2009-03-23 13:35:39 +0000273void set_setup()
plars865695b2001-08-27 22:15:12 +0000274{
275 /* set up a new mode for the semaphore set */
276 buf.sem_perm.mode = SEM_RA | NEWMODE;
277}
278
279/*
280 * func_set() - check the functionality of the IPC_SET command with semctl()
281 */
subrata_modak56207ce2009-03-23 13:35:39 +0000282void func_set()
plars865695b2001-08-27 22:15:12 +0000283{
284 /* first stat the semaphore to get the new data */
285 if (semctl(sem_id_1, 0, IPC_STAT, (union semun)&buf) == -1) {
286 tst_resm(TBROK, "stat failed in func_set()");
287 return;
288 }
289
290 /* check that the new mode is what we set */
robbiew23499f02002-11-18 19:54:58 +0000291 if (buf.sem_perm.mode == (SEM_RA | NEWMODE)) {
plars865695b2001-08-27 22:15:12 +0000292 tst_resm(TPASS, "buf.sem_perm.mode is correct");
293 } else {
294 tst_resm(TFAIL, "semaphore mode info is incorrect");
295 }
296}
297
298/*
299 * func_gall() - check the functionality of the GETALL command with semctl()
300 */
subrata_modak56207ce2009-03-23 13:35:39 +0000301void func_gall()
plars865695b2001-08-27 22:15:12 +0000302{
303 int i;
304
305 /* the initial value of the primitive semaphores should be zero */
subrata_modak56207ce2009-03-23 13:35:39 +0000306 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000307 if (array[i] != 0) {
308 tst_resm(TFAIL, "semaphore %d has unexpected value", i);
309 return;
310 }
311 }
312 tst_resm(TPASS, "semaphores have expected values");
313}
314
315/*
316 * cnt_setup() - set up for the GETNCNT and GETZCNT commands with semctl()
317 */
subrata_modak56207ce2009-03-23 13:35:39 +0000318void cnt_setup(int opval)
plars865695b2001-08-27 22:15:12 +0000319{
320 int pid, i;
321
322 sops.sem_num = SEM4;
323 sops.sem_flg = 0;
324
325 /*
326 * if seting up for GETZCNT, the semaphore value needs to be positive
327 */
328 if (opval == 0) {
329 /* initialize the semaphore value to ONE */
330 sops.sem_op = ONE;
331 if (semop(sem_id_1, &sops, 1) == -1) {
332 tst_brkm(TBROK, cleanup, "semop #1 failed - cnt_setup");
333 }
334 }
335
336 sops.sem_op = opval; /* set the correct operation */
subrata_modak56207ce2009-03-23 13:35:39 +0000337 for (i = 0; i < NCHILD; i++) {
subrata_modak4b13c892009-01-22 09:51:33 +0000338 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
subrata_modak8791f672008-05-20 10:11:00 +0000339 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000340
plars865695b2001-08-27 22:15:12 +0000341 /* fork five children to wait */
subrata_modak8791f672008-05-20 10:11:00 +0000342 if ((pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +0000343 tst_brkm(TBROK, cleanup, "fork failed in cnt_setup");
subrata_modakbdbaec52009-02-26 12:14:51 +0000344
subrata_modak56207ce2009-03-23 13:35:39 +0000345 if (pid == 0) { /* child */
robbiewd34d5812005-07-11 22:28:09 +0000346#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +0000347 sem_op = sops.sem_op;
subrata_modak56207ce2009-03-23 13:35:39 +0000348 if (self_exec(argv0, "ndd", 2, sem_id_1, sem_op) < 0) {
robbiewd34d5812005-07-11 22:28:09 +0000349 tst_brkm(TBROK, cleanup, "self_exec failed "
350 "in cnt_setup");
plars865695b2001-08-27 22:15:12 +0000351 }
robbiewd34d5812005-07-11 22:28:09 +0000352#else
353 child_cnt();
354#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000355 } else { /* parent */
subrata_modak8791f672008-05-20 10:11:00 +0000356 if (sync_pipe_wait(sync_pipes) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000357 tst_brkm(TBROK, cleanup,
358 "sync_pipe_wait failed");
subrata_modak8791f672008-05-20 10:11:00 +0000359
subrata_modak4b13c892009-01-22 09:51:33 +0000360 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000361 tst_brkm(TBROK, cleanup,
362 "sync_pipe_close failed");
plars865695b2001-08-27 22:15:12 +0000363
364 /* save the pid so we can kill it later */
365 pid_arr[i] = pid;
366 }
367 }
subrata_modak41399ed2008-03-14 19:16:23 +0000368 /* After last son has been created, give it a chance to execute the
369 * semop command before we continue. Without this sleep, on SMP machine
370 * the father semctl could be executed before the son semop.
371 */
372 sleep(1);
plars865695b2001-08-27 22:15:12 +0000373}
374
subrata_modak56207ce2009-03-23 13:35:39 +0000375void child_cnt()
robbiewd34d5812005-07-11 22:28:09 +0000376{
subrata_modak4b13c892009-01-22 09:51:33 +0000377#ifdef UCLINUX
378 sops.sem_op = (short int)sem_op;
379 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
380 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
381#endif
382
383 if (sync_pipe_notify(sync_pipes) == -1)
384 tst_brkm(TBROK, cleanup, "sync_pipe_notify failed");
385
Subrata Modak9e365e82010-07-03 23:13:41 +0530386#ifdef UCLINUX
387 if (sync_pipe_close(sync_pipes, NULL) == -1)
388#else
subrata_modak4b13c892009-01-22 09:51:33 +0000389 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
Subrata Modak9e365e82010-07-03 23:13:41 +0530390#endif
subrata_modak4b13c892009-01-22 09:51:33 +0000391 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
392
robbiewd34d5812005-07-11 22:28:09 +0000393 sops.sem_num = SEM4;
394 sops.sem_flg = 0;
395
396 /*
397 * Do a semop that will cause the child to sleep.
398 * The child process will be killed in the func_ncnt
399 * routine which should cause an error to be return
400 * by the semop() call.
401 */
402 if (semop(sem_id_1, &sops, 1) != -1) {
403 tst_resm(TBROK, "semop succeeded - cnt_setup");
404 }
405 exit(0);
406}
407
plars865695b2001-08-27 22:15:12 +0000408/*
409 * func_cnt() - check the functionality of the GETNCNT and GETZCNT commands
410 * with semctl()
411 */
subrata_modak56207ce2009-03-23 13:35:39 +0000412void func_cnt(int rval)
plars865695b2001-08-27 22:15:12 +0000413{
plars865695b2001-08-27 22:15:12 +0000414
415 if (rval == NCHILD) {
416 tst_resm(TPASS, "number of sleeping processes is correct");
417 } else {
418 tst_resm(TFAIL, "number of sleeping processes is not correct");
419 }
420}
421
422/*
423 * pid_setup() - set up for the GETPID command with semctl()
424 */
subrata_modak56207ce2009-03-23 13:35:39 +0000425void pid_setup()
plars865695b2001-08-27 22:15:12 +0000426{
427 int pid;
subrata_modak41399ed2008-03-14 19:16:23 +0000428
subrata_modak4b13c892009-01-22 09:51:33 +0000429 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) {
subrata_modak8791f672008-05-20 10:11:00 +0000430 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000431 }
plars865695b2001-08-27 22:15:12 +0000432
plars865695b2001-08-27 22:15:12 +0000433 /*
subrata_modak4bb656a2009-02-26 12:02:09 +0000434 * Fork a child to do a semop that will pass.
plars865695b2001-08-27 22:15:12 +0000435 */
robbiewd34d5812005-07-11 22:28:09 +0000436 if ((pid = FORK_OR_VFORK()) == -1) {
plars865695b2001-08-27 22:15:12 +0000437 tst_brkm(TBROK, cleanup, "fork failed in pid_setup()");
438 }
robbiewd34d5812005-07-11 22:28:09 +0000439
plars865695b2001-08-27 22:15:12 +0000440 if (pid == 0) { /* child */
robbiewd34d5812005-07-11 22:28:09 +0000441#ifdef UCLINUX
442 if (self_exec(argv0, "nd", 1, sem_id_1) < 0) {
443 tst_brkm(TBROK, cleanup, "self_exec failed "
444 "in pid_setup()");
plars865695b2001-08-27 22:15:12 +0000445 }
robbiewd34d5812005-07-11 22:28:09 +0000446#else
447 child_pid();
448#endif
plars865695b2001-08-27 22:15:12 +0000449 } else { /* parent */
subrata_modak8791f672008-05-20 10:11:00 +0000450 if (sync_pipe_wait(sync_pipes) == -1)
451 tst_brkm(TBROK, cleanup, "sync_pipe_wait failed");
452
subrata_modak4b13c892009-01-22 09:51:33 +0000453 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
subrata_modak8791f672008-05-20 10:11:00 +0000454 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
subrata_modak41399ed2008-03-14 19:16:23 +0000455 sleep(1);
plars865695b2001-08-27 22:15:12 +0000456 pid_arr[SEM2] = pid;
457 }
458}
459
subrata_modak56207ce2009-03-23 13:35:39 +0000460void child_pid()
robbiewd34d5812005-07-11 22:28:09 +0000461{
subrata_modak4b13c892009-01-22 09:51:33 +0000462#ifdef UCLINUX
463 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
464 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
465#endif
466
467 if (sync_pipe_notify(sync_pipes) == -1)
468 tst_brkm(TBROK, cleanup, "sync_pipe_notify failed");
469
470 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
471 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
472
robbiewd34d5812005-07-11 22:28:09 +0000473 sops.sem_num = SEM2; /* semaphore to change */
474 sops.sem_op = ONE; /* operation is to increment semaphore */
475 sops.sem_flg = 0;
476
477 /*
478 * Do a semop that will increment the semaphore.
479 */
480 if (semop(sem_id_1, &sops, 1) == -1) {
481 tst_resm(TBROK, "semop failed - pid_setup");
482 }
483 exit(0);
484}
485
plars865695b2001-08-27 22:15:12 +0000486/*
487 * func_pid() - check the functionality of the GETPID command with semctl()
488 */
subrata_modak56207ce2009-03-23 13:35:39 +0000489void func_pid(int rval)
plars865695b2001-08-27 22:15:12 +0000490{
491 /* compare the rval (pid) to the saved pid from the setup */
492 if (rval == pid_arr[SEM2]) {
493 tst_resm(TPASS, "last pid value is correct");
494 } else {
495 tst_resm(TFAIL, "last pid value is not correct");
496 }
497}
498
499/*
500 * func_gval() - check the functionality of the GETVAL command with semctl()
501 */
subrata_modak56207ce2009-03-23 13:35:39 +0000502void func_gval(int rval)
plars865695b2001-08-27 22:15:12 +0000503{
504 /*
505 * This is a simple test. The semaphore value should be equal
506 * to ONE as it was set in the last test (GETPID).
507 */
508 if (rval == 1) {
509 tst_resm(TPASS, "semaphore value is correct");
510 } else {
511 tst_resm(TFAIL, "semaphore value is not correct");
512 }
513
514}
515
516/*
517 * all_setup() - set up for the SETALL command with semctl()
518 */
subrata_modak56207ce2009-03-23 13:35:39 +0000519void sall_setup()
plars865695b2001-08-27 22:15:12 +0000520{
521 int i;
522
subrata_modak56207ce2009-03-23 13:35:39 +0000523 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000524 /* initialize the array values to 3 */
525 array[i] = 3;
526 }
527}
528
529/*
530 * func_sall() - check the functionality of the SETALL command with semctl()
531 */
subrata_modak56207ce2009-03-23 13:35:39 +0000532void func_sall()
plars865695b2001-08-27 22:15:12 +0000533{
534 int i;
535 unsigned short rarray[PSEMS];
536
537 /*
538 * do a GETALL and compare the values to those set above
539 */
540
541 if (semctl(sem_id_1, 0, GETALL, (union semun)rarray) == -1) {
542 tst_brkm(TBROK, cleanup, "semctl failed in func_sall");
543 }
544
subrata_modak56207ce2009-03-23 13:35:39 +0000545 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000546 if (array[i] != rarray[i]) {
547 tst_resm(TFAIL, "semaphore values are not correct");
548 return;
549 }
550 }
551
552 tst_resm(TPASS, "semaphore values are correct");
553}
554
555/*
556 * func_sval() - check the functionality of the SETVAL command with semctl()
557 */
subrata_modak56207ce2009-03-23 13:35:39 +0000558void func_sval()
plars865695b2001-08-27 22:15:12 +0000559{
560 int semv;
iyermanoje2cb9cd2002-01-21 18:48:13 +0000561 union semun arr;
plars865695b2001-08-27 22:15:12 +0000562
563 /*
564 * do a GETVAL and compare it to the value set above
565 */
566
iyermanoje2cb9cd2002-01-21 18:48:13 +0000567 if ((semv = semctl(sem_id_1, SEM4, GETVAL, arr)) == -1) {
plars865695b2001-08-27 22:15:12 +0000568 tst_brkm(TBROK, cleanup, "semctl failed in func_sval");
569 }
570
571 if (semv != INCVAL) {
572 tst_resm(TFAIL, "semaphore value is not what was set");
573 } else {
574 tst_resm(TPASS, "semaphore value is correct");
575 }
576}
577
578/*
579 * func_rmid() - check the functionality of the IPC_RMID command with semctl()
580 */
subrata_modak56207ce2009-03-23 13:35:39 +0000581void func_rmid()
plars865695b2001-08-27 22:15:12 +0000582{
583
584 /*
585 * do a semop() - we should get EINVAL
586 */
587 if (semop(sem_id_1, &sops, 1) != -1) {
588 tst_resm(TFAIL, "semop succeeded on expected fail");
589 }
590
591 if (errno != EINVAL) {
592 tst_resm(TFAIL, "returned errno - %d - is not expected", errno);
593 } else {
594 tst_resm(TPASS, "semaphore appears to be removed");
595 }
596
597 sem_id_1 = -1;
598}
599
600/*
601 * setup() - performs all the ONE TIME setup for this test.
602 */
subrata_modak56207ce2009-03-23 13:35:39 +0000603void setup(void)
plars865695b2001-08-27 22:15:12 +0000604{
Garrett Cooper2c282152010-12-16 00:55:50 -0800605
plars865695b2001-08-27 22:15:12 +0000606 tst_sig(FORK, DEF_HANDLER, cleanup);
607
plars865695b2001-08-27 22:15:12 +0000608 TEST_PAUSE;
609
610 /*
611 * Create a temporary directory and cd into it.
612 * This helps to ensure that a unique msgkey is created.
613 * See ../lib/libipc.c for more information.
614 */
615 tst_tmpdir();
616
617 /* get an IPC resource key */
618 semkey = getipckey();
619
620 /* create a semaphore set with read and alter permissions */
621 if ((sem_id_1 =
subrata_modak56207ce2009-03-23 13:35:39 +0000622 semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA)) == -1) {
plars865695b2001-08-27 22:15:12 +0000623 tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
624 }
625}
626
627/*
628 * cleanup() - performs all the ONE TIME cleanup for this test at completion
629 * or premature exit.
630 */
subrata_modak56207ce2009-03-23 13:35:39 +0000631void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000632{
633 /* if it exists, remove the semaphore resource */
634 rm_sema(sem_id_1);
635
plars865695b2001-08-27 22:15:12 +0000636 tst_rmdir();
637
638 /*
639 * print timing stats if that option was specified.
640 * print errno log if that option was specified.
641 */
642 TEST_CLEANUP;
643
Garrett Cooper2c282152010-12-16 00:55:50 -0800644}