blob: 2f443db89690ef0a7e350a7fd0f36ef779691c0c [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
DAN LIbffa8862013-05-13 10:21:43 +08002 * Copyright (c) International Business Machines Corp., 2001
plars865695b2001-08-27 22:15:12 +00003 *
DAN LIbffa8862013-05-13 10:21:43 +08004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
plars865695b2001-08-27 22:15:12 +00008 *
DAN LIbffa8862013-05-13 10:21:43 +08009 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
plars865695b2001-08-27 22:15:12 +000013 *
DAN LIbffa8862013-05-13 10:21:43 +080014 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000017 */
18
19/*
20 * NAME
21 * semctl01.c
22 *
23 * DESCRIPTION
DAN LIbffa8862013-05-13 10:21:43 +080024 * semctl01 - test the 13 possible semctl() commands
plars865695b2001-08-27 22:15:12 +000025 *
26 * ALGORITHM
27 * create a semaphore set with read and alter permissions
28 * loop if that option was specified
29 * loop through the test cases
30 * do any setup required for the test case
31 * make the semctl() call using the TEST() macro
32 * check the return code
33 * if failure, issue a FAIL message.
34 * otherwise,
35 * if doing functionality testing
36 * call the appropriate test function
DAN LIbffa8862013-05-13 10:21:43 +080037 * if correct,
plars865695b2001-08-27 22:15:12 +000038 * issue a PASS message
39 * otherwise
40 * issue a FAIL message
41 * call cleanup
plars865695b2001-08-27 22:15:12 +000042 */
43
DAN LIa63f9332013-05-13 10:24:33 +080044
45#ifndef _GNU_SOURCE
46#define _GNU_SOURCE
47#endif
Jan Stancek7018c132015-11-13 14:05:28 +010048#include <sys/wait.h>
robbiew23499f02002-11-18 19:54:58 +000049#include "ipcsem.h"
Cyril Hrubis49da8ad2017-10-03 13:45:04 +020050#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000051
52char *TCID = "semctl01";
plars865695b2001-08-27 22:15:12 +000053
DAN LIbffa8862013-05-13 10:21:43 +080054static int sem_id_1 = -1;
DAN LIf74f0a92013-05-22 09:52:09 +080055static int sem_index;
plars865695b2001-08-27 22:15:12 +000056
57/*
58 * These are the various setup and check functions for the 10 different
59 * commands that are available for the semctl() call.
60 */
DAN LIbffa8862013-05-13 10:21:43 +080061static void func_stat(void);
62static void set_setup(void), func_set(void);
63static void func_gall(void);
64static void cnt_setup(int), func_cnt(int);
65static void pid_setup(void), func_pid(int);
66static void func_gval(int);
67static void sall_setup(void), func_sall(void);
68static void func_sval(void);
69static void func_rmid(void);
70static void child_cnt(void);
71static void child_pid(void);
DAN LIa63f9332013-05-13 10:24:33 +080072static void func_iinfo(int);
73static void func_sinfo(void);
74static void func_sstat(int);
plars865695b2001-08-27 22:15:12 +000075
DAN LIbffa8862013-05-13 10:21:43 +080076static struct semid_ds buf;
DAN LIa63f9332013-05-13 10:24:33 +080077static struct seminfo ipc_buf;
DAN LIbffa8862013-05-13 10:21:43 +080078static unsigned short array[PSEMS];
79static struct sembuf sops;
plars865695b2001-08-27 22:15:12 +000080
DAN LIbffa8862013-05-13 10:21:43 +080081#define INCVAL 2
plars865695b2001-08-27 22:15:12 +000082#define NEWMODE 066
83#define NCHILD 5
DAN LIbffa8862013-05-13 10:21:43 +080084#define SEM2 2
85#define SEM4 4
plars865695b2001-08-27 22:15:12 +000086#define ONE 1
mridgef7298c72005-12-05 19:14:37 +000087#ifdef _XLC_COMPILER
subrata_modak4bb656a2009-02-26 12:02:09 +000088#define SEMUN_CAST
mridgef7298c72005-12-05 19:14:37 +000089#else
90#define SEMUN_CAST (union semun)
91#endif
92
DAN LIbffa8862013-05-13 10:21:43 +080093static int pid_arr[NCHILD];
plars865695b2001-08-27 22:15:12 +000094
robbiewd34d5812005-07-11 22:28:09 +000095#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +000096#define PIPE_NAME "semctl01"
robbiewd34d5812005-07-11 22:28:09 +000097static char *argv0;
DAN LIbffa8862013-05-13 10:21:43 +080098static int sem_op;
robbiewd34d5812005-07-11 22:28:09 +000099#endif
100
DAN LIbffa8862013-05-13 10:21:43 +0800101static struct test_case_t {
DAN LIf74f0a92013-05-22 09:52:09 +0800102 int *semid;
DAN LIbffa8862013-05-13 10:21:43 +0800103 int semnum;
104 int cmd;
105 void (*func_test) ();
plars865695b2001-08-27 22:15:12 +0000106 union semun arg;
DAN LIbffa8862013-05-13 10:21:43 +0800107 void (*func_setup) ();
plars865695b2001-08-27 22:15:12 +0000108} TC[] = {
DAN LIf74f0a92013-05-22 09:52:09 +0800109 {&sem_id_1, 0, IPC_STAT, func_stat, SEMUN_CAST & buf, NULL},
110 {&sem_id_1, 0, IPC_SET, func_set, SEMUN_CAST & buf, set_setup},
111 {&sem_id_1, 0, GETALL, func_gall, SEMUN_CAST array, NULL},
112 {&sem_id_1, SEM4, GETNCNT, func_cnt, SEMUN_CAST & buf, cnt_setup},
113 {&sem_id_1, SEM2, GETPID, func_pid, SEMUN_CAST & buf, pid_setup},
114 {&sem_id_1, SEM2, GETVAL, func_gval, SEMUN_CAST & buf, NULL},
115 {&sem_id_1, SEM4, GETZCNT, func_cnt, SEMUN_CAST & buf, cnt_setup},
116 {&sem_id_1, 0, SETALL, func_sall, SEMUN_CAST array, sall_setup},
117 {&sem_id_1, SEM4, SETVAL, func_sval, SEMUN_CAST INCVAL, NULL},
118 {&sem_id_1, 0, IPC_INFO, func_iinfo, SEMUN_CAST & ipc_buf, NULL},
119 {&sem_id_1, 0, SEM_INFO, func_sinfo, SEMUN_CAST & ipc_buf, NULL},
120 {&sem_index, 0, SEM_STAT, func_sstat, SEMUN_CAST & buf, NULL},
121 {&sem_id_1, 0, IPC_RMID, func_rmid, SEMUN_CAST & buf, NULL},
plars865695b2001-08-27 22:15:12 +0000122};
123
Jan Stancek7018c132015-11-13 14:05:28 +0100124int TST_TOTAL = ARRAY_SIZE(TC);
125
126static void kill_all_children(void)
127{
128 int j, status;
129
130 for (j = 0; j < NCHILD; j++) {
Cyril Hrubisd84a7ec2017-10-03 13:48:07 +0200131 SAFE_KILL(cleanup, pid_arr[j], SIGKILL);
Jan Stancek7018c132015-11-13 14:05:28 +0100132 }
133
134 /*
135 * make sure children finished before we proceed with next testcase
136 */
137 for (j = 0; j < NCHILD; j++) {
Cyril Hrubis49da8ad2017-10-03 13:45:04 +0200138 SAFE_WAIT(cleanup, &status);
Jan Stancek7018c132015-11-13 14:05:28 +0100139 }
140}
141
DAN LIbffa8862013-05-13 10:21:43 +0800142int main(int argc, char *argv[])
plars865695b2001-08-27 22:15:12 +0000143{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200144 int lc;
Jan Stancek7018c132015-11-13 14:05:28 +0100145 int i;
plars865695b2001-08-27 22:15:12 +0000146
Cyril Hrubisd6d11d02015-03-09 17:35:43 +0100147 tst_parse_opts(argc, argv, NULL, NULL);
DAN LIbffa8862013-05-13 10:21:43 +0800148
robbiewd34d5812005-07-11 22:28:09 +0000149#ifdef UCLINUX
DAN LIbffa8862013-05-13 10:21:43 +0800150 argv0 = argv[0];
robbiewd34d5812005-07-11 22:28:09 +0000151 maybe_run_child(&child_pid, "nd", 1, &sem_id_1);
subrata_modak4b13c892009-01-22 09:51:33 +0000152 maybe_run_child(&child_cnt, "ndd", 2, &sem_id_1, &sem_op);
robbiewd34d5812005-07-11 22:28:09 +0000153#endif
154
DAN LIbffa8862013-05-13 10:21:43 +0800155 setup();
plars865695b2001-08-27 22:15:12 +0000156
157 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800158 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000159
subrata_modak56207ce2009-03-23 13:35:39 +0000160 for (i = 0; i < TST_TOTAL; i++) {
plars865695b2001-08-27 22:15:12 +0000161
162 /*
163 * Set up any conditions if needed
164 */
plars865695b2001-08-27 22:15:12 +0000165 if (TC[i].func_setup != NULL) {
166 /* call the setup function */
167 switch (TC[i].cmd) {
168 case GETNCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000169 (*TC[i].func_setup) (-ONE);
plars865695b2001-08-27 22:15:12 +0000170 break;
171 case GETZCNT:
subrata_modak56207ce2009-03-23 13:35:39 +0000172 (*TC[i].func_setup) (0);
plars865695b2001-08-27 22:15:12 +0000173 break;
174 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000175 (*TC[i].func_setup) ();
plars865695b2001-08-27 22:15:12 +0000176 break;
177 }
178 }
179
DAN LIf74f0a92013-05-22 09:52:09 +0800180 TEST(semctl(*(TC[i].semid), TC[i].semnum, TC[i].cmd,
plars865695b2001-08-27 22:15:12 +0000181 TC[i].arg));
subrata_modakbdbaec52009-02-26 12:14:51 +0000182
plars865695b2001-08-27 22:15:12 +0000183 if (TEST_RETURN == -1) {
184 tst_resm(TFAIL, "%s call failed - errno = %d "
185 ": %s", TCID, TEST_ERRNO,
186 strerror(TEST_ERRNO));
187 } else {
Cyril Hrubise38b9612014-06-02 17:20:57 +0200188 /*
189 * call the appropriate test function
190 * and pass the return value where it
191 * is needed to perform certain tests.
192 */
193 switch (TC[i].cmd) {
194 case GETNCNT:
195 case GETZCNT:
196 case GETPID:
197 case GETVAL:
198 case IPC_INFO:
199 case SEM_STAT:
200 (*TC[i].func_test) (TEST_RETURN);
201 break;
202 default:
203 (*TC[i].func_test) ();
204 break;
plars865695b2001-08-27 22:15:12 +0000205 }
206 }
207
208 /*
209 * If testing GETNCNT or GETZCNT, clean up the children.
210 */
211 switch (TC[i].cmd) {
212 case GETNCNT:
DAN LIbffa8862013-05-13 10:21:43 +0800213 case GETZCNT:
Jan Stancek7018c132015-11-13 14:05:28 +0100214 kill_all_children();
plars865695b2001-08-27 22:15:12 +0000215 break;
216 }
217 }
218 /*
219 * recreate the semaphore resource if looping
220 */
221 if (TEST_LOOPING(lc)) {
DAN LIbffa8862013-05-13 10:21:43 +0800222 sem_id_1 = semget(semkey, PSEMS,
223 IPC_CREAT | IPC_EXCL | SEM_RA);
224 if (sem_id_1 == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000225 tst_brkm(TBROK, cleanup,
226 "couldn't recreate " "semaphore");
plars865695b2001-08-27 22:15:12 +0000227 }
228 }
229
230 cleanup();
231
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800232 tst_exit();
plars865695b2001-08-27 22:15:12 +0000233}
234
235/*
236 * func_stat() - check the functionality of the IPC_STAT command with semctl()
237 */
DAN LIbffa8862013-05-13 10:21:43 +0800238static void func_stat(void)
plars865695b2001-08-27 22:15:12 +0000239{
240 /* check the number of semaphores and the ipc_perm.mode value */
DAN LIbffa8862013-05-13 10:21:43 +0800241 if (buf.sem_nsems == PSEMS && buf.sem_perm.mode == (SEM_RA))
plars865695b2001-08-27 22:15:12 +0000242 tst_resm(TPASS, "buf.sem_nsems and buf.sem_perm.mode"
subrata_modak56207ce2009-03-23 13:35:39 +0000243 " are correct");
DAN LIbffa8862013-05-13 10:21:43 +0800244 else
plars865695b2001-08-27 22:15:12 +0000245 tst_resm(TFAIL, "semaphore STAT info is incorrect");
plars865695b2001-08-27 22:15:12 +0000246}
247
248/*
249 * set_setup() - set up for the IPC_SET command with semctl()
250 */
DAN LIbffa8862013-05-13 10:21:43 +0800251static void set_setup(void)
plars865695b2001-08-27 22:15:12 +0000252{
253 /* set up a new mode for the semaphore set */
254 buf.sem_perm.mode = SEM_RA | NEWMODE;
255}
256
257/*
258 * func_set() - check the functionality of the IPC_SET command with semctl()
259 */
DAN LIbffa8862013-05-13 10:21:43 +0800260static void func_set(void)
plars865695b2001-08-27 22:15:12 +0000261{
262 /* first stat the semaphore to get the new data */
263 if (semctl(sem_id_1, 0, IPC_STAT, (union semun)&buf) == -1) {
264 tst_resm(TBROK, "stat failed in func_set()");
265 return;
266 }
267
268 /* check that the new mode is what we set */
DAN LIbffa8862013-05-13 10:21:43 +0800269 if (buf.sem_perm.mode == (SEM_RA | NEWMODE))
plars865695b2001-08-27 22:15:12 +0000270 tst_resm(TPASS, "buf.sem_perm.mode is correct");
DAN LIbffa8862013-05-13 10:21:43 +0800271 else
plars865695b2001-08-27 22:15:12 +0000272 tst_resm(TFAIL, "semaphore mode info is incorrect");
plars865695b2001-08-27 22:15:12 +0000273}
274
275/*
276 * func_gall() - check the functionality of the GETALL command with semctl()
277 */
DAN LIbffa8862013-05-13 10:21:43 +0800278static void func_gall(void)
plars865695b2001-08-27 22:15:12 +0000279{
280 int i;
281
282 /* the initial value of the primitive semaphores should be zero */
subrata_modak56207ce2009-03-23 13:35:39 +0000283 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000284 if (array[i] != 0) {
285 tst_resm(TFAIL, "semaphore %d has unexpected value", i);
286 return;
287 }
288 }
289 tst_resm(TPASS, "semaphores have expected values");
290}
291
292/*
293 * cnt_setup() - set up for the GETNCNT and GETZCNT commands with semctl()
294 */
DAN LIbffa8862013-05-13 10:21:43 +0800295static void cnt_setup(int opval)
plars865695b2001-08-27 22:15:12 +0000296{
297 int pid, i;
298
299 sops.sem_num = SEM4;
300 sops.sem_flg = 0;
301
302 /*
303 * if seting up for GETZCNT, the semaphore value needs to be positive
304 */
305 if (opval == 0) {
306 /* initialize the semaphore value to ONE */
307 sops.sem_op = ONE;
DAN LIbffa8862013-05-13 10:21:43 +0800308 if (semop(sem_id_1, &sops, 1) == -1)
plars865695b2001-08-27 22:15:12 +0000309 tst_brkm(TBROK, cleanup, "semop #1 failed - cnt_setup");
plars865695b2001-08-27 22:15:12 +0000310 }
311
DAN LIbffa8862013-05-13 10:21:43 +0800312 /* set the correct operation */
313 sops.sem_op = opval;
subrata_modak56207ce2009-03-23 13:35:39 +0000314 for (i = 0; i < NCHILD; i++) {
plars865695b2001-08-27 22:15:12 +0000315 /* fork five children to wait */
DAN LIbffa8862013-05-13 10:21:43 +0800316 pid = FORK_OR_VFORK();
317 if (pid == -1)
plars865695b2001-08-27 22:15:12 +0000318 tst_brkm(TBROK, cleanup, "fork failed in cnt_setup");
subrata_modakbdbaec52009-02-26 12:14:51 +0000319
DAN LIbffa8862013-05-13 10:21:43 +0800320 if (pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +0000321#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +0000322 sem_op = sops.sem_op;
DAN LIbffa8862013-05-13 10:21:43 +0800323 if (self_exec(argv0, "ndd", 2, sem_id_1, sem_op) < 0)
robbiewd34d5812005-07-11 22:28:09 +0000324 tst_brkm(TBROK, cleanup, "self_exec failed "
325 "in cnt_setup");
robbiewd34d5812005-07-11 22:28:09 +0000326#else
327 child_cnt();
328#endif
DAN LIbffa8862013-05-13 10:21:43 +0800329 } else {
Cyril Hrubisf9791ef2015-03-05 16:09:16 +0100330 TST_PROCESS_STATE_WAIT(cleanup, pid, 'S');
plars865695b2001-08-27 22:15:12 +0000331 /* save the pid so we can kill it later */
332 pid_arr[i] = pid;
333 }
334 }
335}
336
DAN LIbffa8862013-05-13 10:21:43 +0800337static void child_cnt(void)
robbiewd34d5812005-07-11 22:28:09 +0000338{
subrata_modak4b13c892009-01-22 09:51:33 +0000339#ifdef UCLINUX
340 sops.sem_op = (short int)sem_op;
subrata_modak4b13c892009-01-22 09:51:33 +0000341#endif
342
robbiewd34d5812005-07-11 22:28:09 +0000343 sops.sem_num = SEM4;
344 sops.sem_flg = 0;
345
346 /*
347 * Do a semop that will cause the child to sleep.
348 * The child process will be killed in the func_ncnt
349 * routine which should cause an error to be return
350 * by the semop() call.
351 */
DAN LIbffa8862013-05-13 10:21:43 +0800352 if (semop(sem_id_1, &sops, 1) != -1)
robbiewd34d5812005-07-11 22:28:09 +0000353 tst_resm(TBROK, "semop succeeded - cnt_setup");
DAN LIbffa8862013-05-13 10:21:43 +0800354
robbiewd34d5812005-07-11 22:28:09 +0000355 exit(0);
356}
357
plars865695b2001-08-27 22:15:12 +0000358/*
359 * func_cnt() - check the functionality of the GETNCNT and GETZCNT commands
360 * with semctl()
361 */
DAN LIbffa8862013-05-13 10:21:43 +0800362static void func_cnt(int rval)
plars865695b2001-08-27 22:15:12 +0000363{
plars865695b2001-08-27 22:15:12 +0000364
DAN LIbffa8862013-05-13 10:21:43 +0800365 if (rval == NCHILD)
plars865695b2001-08-27 22:15:12 +0000366 tst_resm(TPASS, "number of sleeping processes is correct");
DAN LIbffa8862013-05-13 10:21:43 +0800367 else
plars865695b2001-08-27 22:15:12 +0000368 tst_resm(TFAIL, "number of sleeping processes is not correct");
plars865695b2001-08-27 22:15:12 +0000369}
370
371/*
372 * pid_setup() - set up for the GETPID command with semctl()
373 */
DAN LIbffa8862013-05-13 10:21:43 +0800374static void pid_setup(void)
plars865695b2001-08-27 22:15:12 +0000375{
376 int pid;
subrata_modak41399ed2008-03-14 19:16:23 +0000377
plars865695b2001-08-27 22:15:12 +0000378 /*
subrata_modak4bb656a2009-02-26 12:02:09 +0000379 * Fork a child to do a semop that will pass.
plars865695b2001-08-27 22:15:12 +0000380 */
DAN LIbffa8862013-05-13 10:21:43 +0800381 pid = FORK_OR_VFORK();
382 if (pid == -1)
plars865695b2001-08-27 22:15:12 +0000383 tst_brkm(TBROK, cleanup, "fork failed in pid_setup()");
robbiewd34d5812005-07-11 22:28:09 +0000384
plars865695b2001-08-27 22:15:12 +0000385 if (pid == 0) { /* child */
robbiewd34d5812005-07-11 22:28:09 +0000386#ifdef UCLINUX
DAN LIbffa8862013-05-13 10:21:43 +0800387 if (self_exec(argv0, "nd", 1, sem_id_1) < 0)
robbiewd34d5812005-07-11 22:28:09 +0000388 tst_brkm(TBROK, cleanup, "self_exec failed "
389 "in pid_setup()");
robbiewd34d5812005-07-11 22:28:09 +0000390#else
391 child_pid();
392#endif
Cyril Hrubisf9791ef2015-03-05 16:09:16 +0100393 } else {
plars865695b2001-08-27 22:15:12 +0000394 pid_arr[SEM2] = pid;
Cyril Hrubisf9791ef2015-03-05 16:09:16 +0100395 TST_PROCESS_STATE_WAIT(cleanup, pid, 'Z');
plars865695b2001-08-27 22:15:12 +0000396 }
397}
398
DAN LIbffa8862013-05-13 10:21:43 +0800399static void child_pid(void)
robbiewd34d5812005-07-11 22:28:09 +0000400{
DAN LIbffa8862013-05-13 10:21:43 +0800401 sops.sem_num = SEM2;
402 sops.sem_op = ONE;
robbiewd34d5812005-07-11 22:28:09 +0000403 sops.sem_flg = 0;
robbiewd34d5812005-07-11 22:28:09 +0000404 /*
405 * Do a semop that will increment the semaphore.
406 */
DAN LIbffa8862013-05-13 10:21:43 +0800407 if (semop(sem_id_1, &sops, 1) == -1)
robbiewd34d5812005-07-11 22:28:09 +0000408 tst_resm(TBROK, "semop failed - pid_setup");
robbiewd34d5812005-07-11 22:28:09 +0000409 exit(0);
410}
411
plars865695b2001-08-27 22:15:12 +0000412/*
413 * func_pid() - check the functionality of the GETPID command with semctl()
414 */
DAN LIbffa8862013-05-13 10:21:43 +0800415static void func_pid(int rval)
plars865695b2001-08-27 22:15:12 +0000416{
417 /* compare the rval (pid) to the saved pid from the setup */
DAN LIbffa8862013-05-13 10:21:43 +0800418 if (rval == pid_arr[SEM2])
plars865695b2001-08-27 22:15:12 +0000419 tst_resm(TPASS, "last pid value is correct");
DAN LIbffa8862013-05-13 10:21:43 +0800420 else
plars865695b2001-08-27 22:15:12 +0000421 tst_resm(TFAIL, "last pid value is not correct");
plars865695b2001-08-27 22:15:12 +0000422}
423
424/*
425 * func_gval() - check the functionality of the GETVAL command with semctl()
426 */
DAN LIbffa8862013-05-13 10:21:43 +0800427static void func_gval(int rval)
plars865695b2001-08-27 22:15:12 +0000428{
429 /*
430 * This is a simple test. The semaphore value should be equal
431 * to ONE as it was set in the last test (GETPID).
432 */
DAN LIbffa8862013-05-13 10:21:43 +0800433 if (rval == 1)
plars865695b2001-08-27 22:15:12 +0000434 tst_resm(TPASS, "semaphore value is correct");
DAN LIbffa8862013-05-13 10:21:43 +0800435 else
plars865695b2001-08-27 22:15:12 +0000436 tst_resm(TFAIL, "semaphore value is not correct");
plars865695b2001-08-27 22:15:12 +0000437}
438
439/*
440 * all_setup() - set up for the SETALL command with semctl()
441 */
DAN LIbffa8862013-05-13 10:21:43 +0800442static void sall_setup(void)
plars865695b2001-08-27 22:15:12 +0000443{
444 int i;
445
subrata_modak56207ce2009-03-23 13:35:39 +0000446 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000447 /* initialize the array values to 3 */
448 array[i] = 3;
449 }
450}
451
452/*
453 * func_sall() - check the functionality of the SETALL command with semctl()
454 */
DAN LIbffa8862013-05-13 10:21:43 +0800455static void func_sall(void)
plars865695b2001-08-27 22:15:12 +0000456{
457 int i;
458 unsigned short rarray[PSEMS];
459
460 /*
461 * do a GETALL and compare the values to those set above
462 */
463
DAN LIbffa8862013-05-13 10:21:43 +0800464 if (semctl(sem_id_1, 0, GETALL, (union semun)rarray) == -1)
plars865695b2001-08-27 22:15:12 +0000465 tst_brkm(TBROK, cleanup, "semctl failed in func_sall");
plars865695b2001-08-27 22:15:12 +0000466
subrata_modak56207ce2009-03-23 13:35:39 +0000467 for (i = 0; i < PSEMS; i++) {
plars865695b2001-08-27 22:15:12 +0000468 if (array[i] != rarray[i]) {
469 tst_resm(TFAIL, "semaphore values are not correct");
470 return;
471 }
472 }
473
474 tst_resm(TPASS, "semaphore values are correct");
475}
476
477/*
478 * func_sval() - check the functionality of the SETVAL command with semctl()
479 */
DAN LIbffa8862013-05-13 10:21:43 +0800480static void func_sval(void)
plars865695b2001-08-27 22:15:12 +0000481{
482 int semv;
iyermanoje2cb9cd2002-01-21 18:48:13 +0000483 union semun arr;
plars865695b2001-08-27 22:15:12 +0000484
485 /*
486 * do a GETVAL and compare it to the value set above
487 */
488
DAN LIbffa8862013-05-13 10:21:43 +0800489 semv = semctl(sem_id_1, SEM4, GETVAL, arr);
490 if (semv == -1)
plars865695b2001-08-27 22:15:12 +0000491 tst_brkm(TBROK, cleanup, "semctl failed in func_sval");
plars865695b2001-08-27 22:15:12 +0000492
DAN LIbffa8862013-05-13 10:21:43 +0800493 if (semv != INCVAL)
plars865695b2001-08-27 22:15:12 +0000494 tst_resm(TFAIL, "semaphore value is not what was set");
DAN LIbffa8862013-05-13 10:21:43 +0800495 else
plars865695b2001-08-27 22:15:12 +0000496 tst_resm(TPASS, "semaphore value is correct");
plars865695b2001-08-27 22:15:12 +0000497}
498
499/*
500 * func_rmid() - check the functionality of the IPC_RMID command with semctl()
501 */
DAN LIbffa8862013-05-13 10:21:43 +0800502static void func_rmid(void)
plars865695b2001-08-27 22:15:12 +0000503{
504
505 /*
506 * do a semop() - we should get EINVAL
507 */
DAN LIbffa8862013-05-13 10:21:43 +0800508 if (semop(sem_id_1, &sops, 1) != -1)
plars865695b2001-08-27 22:15:12 +0000509 tst_resm(TFAIL, "semop succeeded on expected fail");
plars865695b2001-08-27 22:15:12 +0000510
DAN LIbffa8862013-05-13 10:21:43 +0800511 if (errno != EINVAL)
plars865695b2001-08-27 22:15:12 +0000512 tst_resm(TFAIL, "returned errno - %d - is not expected", errno);
DAN LIbffa8862013-05-13 10:21:43 +0800513 else
plars865695b2001-08-27 22:15:12 +0000514 tst_resm(TPASS, "semaphore appears to be removed");
plars865695b2001-08-27 22:15:12 +0000515
516 sem_id_1 = -1;
517}
518
DAN LIa63f9332013-05-13 10:24:33 +0800519static void func_iinfo(int hidx)
520{
DAN LIf74f0a92013-05-22 09:52:09 +0800521 if (hidx >= 0) {
522 sem_index = hidx;
DAN LIa63f9332013-05-13 10:24:33 +0800523 tst_resm(TPASS, "the highest index is correct");
DAN LIf74f0a92013-05-22 09:52:09 +0800524 } else {
525 sem_index = 0;
DAN LIa63f9332013-05-13 10:24:33 +0800526 tst_resm(TFAIL, "the highest index is incorrect");
DAN LIf74f0a92013-05-22 09:52:09 +0800527 }
DAN LIa63f9332013-05-13 10:24:33 +0800528}
529
530static void func_sinfo(void)
531{
532 if (ipc_buf.semusz < 1)
533 tst_resm(TFAIL, "number of semaphore sets is incorrect");
534 else
535 tst_resm(TPASS, "number of semaphore sets is correct");
536}
537
538static void func_sstat(int semidx)
539{
540 if (semidx >= 0)
541 tst_resm(TPASS, "id of the semaphore set is correct");
542 else
543 tst_resm(TFAIL, "id of the semaphore set is incorrect");
544}
545
subrata_modak56207ce2009-03-23 13:35:39 +0000546void setup(void)
plars865695b2001-08-27 22:15:12 +0000547{
Garrett Cooper2c282152010-12-16 00:55:50 -0800548
plars865695b2001-08-27 22:15:12 +0000549 tst_sig(FORK, DEF_HANDLER, cleanup);
550
plars865695b2001-08-27 22:15:12 +0000551 TEST_PAUSE;
552
plars865695b2001-08-27 22:15:12 +0000553 tst_tmpdir();
554
Cyril Hrubisf9791ef2015-03-05 16:09:16 +0100555 TST_CHECKPOINT_INIT(tst_rmdir);
556
plars865695b2001-08-27 22:15:12 +0000557 /* get an IPC resource key */
558 semkey = getipckey();
559
560 /* create a semaphore set with read and alter permissions */
DAN LIbffa8862013-05-13 10:21:43 +0800561 sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
562 if (sem_id_1 == -1)
plars865695b2001-08-27 22:15:12 +0000563 tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
plars865695b2001-08-27 22:15:12 +0000564}
565
subrata_modak56207ce2009-03-23 13:35:39 +0000566void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000567{
568 /* if it exists, remove the semaphore resource */
569 rm_sema(sem_id_1);
570
plars865695b2001-08-27 22:15:12 +0000571 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700572}