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  *	semop01.c
23  *
24  * DESCRIPTION
25  *	semop01 - test that semop() basic functionality is correct
26  *
27  * ALGORITHM
28  *	create a semaphore set and initialize some values
29  *	loop if that option was specified
30  *	call semop() to set values for the primitive semaphores
31  *	check the return code
32  *	  if failure, issue a FAIL message.
33  *	otherwise,
34  *	  if doing functionality testing
35  *		get the semaphore values and compare with expected values
36  *		if correct,
37  *			issue a PASS message
38  *		otherwise
39  *			issue a FAIL message
40  *	  else issue a PASS message
41  *	call cleanup
42  *
43  * HISTORY
44  *	03/2001  - Written by Wayne Boyer
45  *	17/01/02 - Modified. Manoj Iyer, IBM Austin. TX. manjo@austin.ibm.com
46  *	           4th argument to semctl() system call was modified according
47  *	           to man pages.
48  *	           In my opinion The test should not even have compiled but
49  *	           it was working due to some mysterious reason.
50  *
51  * RESTRICTIONS
52  *	none
53  */
54 
55 #include "ipcsem.h"
56 
57 #define NSEMS	4		/* the number of primitive semaphores to test */
58 
59 char *TCID = "semop01";
60 int TST_TOTAL = 1;
61 
62 int sem_id_1 = -1;		/* a semaphore set with read & alter permissions */
63 
64 union semun get_arr;
65 struct sembuf sops[PSEMS];
66 
main(int ac,char ** av)67 int main(int ac, char **av)
68 {
69 	int lc;
70 	int i;
71 	int fail = 0;
72 
73 	tst_parse_opts(ac, av, NULL, NULL);
74 
75 	setup();
76 
77 	for (lc = 0; TEST_LOOPING(lc); lc++) {
78 		tst_count = 0;
79 
80 		TEST(semop(sem_id_1, sops, NSEMS));
81 
82 		if (TEST_RETURN == -1) {
83 			tst_resm(TFAIL, "%s call failed - errno = %d : %s",
84 				 TCID, TEST_ERRNO, strerror(TEST_ERRNO));
85 		} else {
86 			/* get the values and make sure they */
87 			/* are the same as what was set      */
88 			if (semctl(sem_id_1, 0, GETALL, get_arr) == -1) {
89 				tst_brkm(TBROK, cleanup,
90 					 "semctl() failed in functional test");
91 			}
92 
93 			for (i = 0; i < NSEMS; i++) {
94 				if (get_arr.array[i] != i * i) {
95 					fail = 1;
96 				}
97 			}
98 			if (fail)
99 				tst_resm(TFAIL,
100 					 "semaphore values are wrong");
101 			else
102 				tst_resm(TPASS,
103 					 "semaphore values are correct");
104 		}
105 
106 		/*
107 		 * clean up things in case we are looping
108 		 */
109 		union semun set_arr;
110 		set_arr.val = 0;
111 		for (i = 0; i < NSEMS; i++) {
112 			if (semctl(sem_id_1, i, SETVAL, set_arr) == -1) {
113 				tst_brkm(TBROK, cleanup, "semctl failed");
114 			}
115 		}
116 	}
117 
118 	cleanup();
119 	tst_exit();
120 }
121 
setup(void)122 void setup(void)
123 {
124 	int i;
125 
126 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
127 
128 	TEST_PAUSE;
129 
130 	tst_tmpdir();
131 
132 	get_arr.array = malloc(sizeof(unsigned short int) * PSEMS);
133 	if (get_arr.array == NULL)
134 		tst_brkm(TBROK, cleanup, "malloc failed");
135 
136 	semkey = getipckey();
137 
138 	sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
139 	if (sem_id_1 == -1)
140 		tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
141 
142 	for (i = 0; i < NSEMS; i++) {
143 		sops[i].sem_num = i;
144 		sops[i].sem_op = i * i;
145 		sops[i].sem_flg = SEM_UNDO;
146 	}
147 }
148 
cleanup(void)149 void cleanup(void)
150 {
151 	rm_sema(sem_id_1);
152 
153 	free(get_arr.array);
154 
155 	tst_rmdir();
156 }
157