semctl07.c revision ec6edca7aa42b6affd989ef91b5897f96795e40f
1/*
2 *
3 *   Copyright (c) International Business Machines  Corp., 2002
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/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
21/* 10/30/2002	Port to LTP	dbarrera@us.ibm.com */
22
23/*
24 * NAME
25 *	semctl07
26 *
27 * CALLS
28 *	semctl(2) semget(2)
29 *
30 * ALGORITHM
31 *	Get and manipulate a set of semaphores.
32 *
33 * RESTRICTIONS
34 *
35 * HISTORY
36 *      10/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
37 *      - Fix concurrency issue. A statically defined key was used. Leading
38 *        to conflict with other instances of the same test.
39 */
40
41#include <sys/types.h>		/* needed for test              */
42#include <sys/ipc.h>		/* needed for test              */
43#include <sys/sem.h>		/* needed for test              */
44#include <signal.h>		/* needed for test              */
45#include <errno.h>		/* needed for test              */
46#include <stdio.h>		/* needed by testhead.h         */
47#include <wait.h>		/* needed by testhead.h         */
48#include "ipcsem.h"
49#include "test.h"
50#include "usctest.h"
51
52void setup();
53void cleanup();
54
55/*
56 *These globals must be defined in the test.
57 */
58
59char *TCID = "semctl07";	/* Test program identifier.    */
60int TST_TOTAL = 1;		/* Total number of test cases. */
61
62int exp_enos[] = { 0 };		/* List must end with 0 */
63
64key_t key;
65int semid = -1, nsems;
66
67/*--------------------------------------------------------------*/
68
69int main(argc, argv)
70int argc;
71char *argv[];
72{
73	int status;
74	struct semid_ds buf_ds;
75
76	union semun {
77		int val;
78		struct semid_ds *buf;
79		short *array;
80	};
81
82	union semun arg;
83
84	setup();		/* temp file is now open        */
85/*--------------------------------------------------------------*/
86
87	arg.buf = &buf_ds;
88	if ((status = semctl(semid, 0, IPC_STAT, arg)) == -1) {
89		tst_resm(TFAIL, "semctl() failed errno = %d", errno);
90		semctl(semid, 1, IPC_RMID, arg);
91
92	}
93
94	/*
95	 * Check contents of semid_ds structure.
96	 */
97
98	if (arg.buf->sem_nsems != nsems) {
99		tst_resm(TFAIL, "error: unexpected number of sems %lu",
100			 arg.buf->sem_nsems);
101
102	}
103	if (arg.buf->sem_perm.uid != getuid()) {
104		tst_resm(TFAIL, "error: unexpected uid %d",
105			 arg.buf->sem_perm.uid);
106
107	}
108	if (arg.buf->sem_perm.gid != getgid()) {
109		tst_resm(TFAIL, "error: unexpected gid %d",
110			 arg.buf->sem_perm.gid);
111
112	}
113	if (arg.buf->sem_perm.cuid != getuid()) {
114		tst_resm(TFAIL, "error: unexpected cuid %d",
115			 arg.buf->sem_perm.cuid);
116
117	}
118	if (arg.buf->sem_perm.cgid != getgid()) {
119		tst_resm(TFAIL, "error: unexpected cgid %d",
120			 arg.buf->sem_perm.cgid);
121
122	}
123	if ((status = semctl(semid, 0, GETVAL, arg)) == -1) {
124		tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno);
125
126	}
127	arg.val = 1;
128	if ((status = semctl(semid, 0, SETVAL, arg)) == -1) {
129		tst_resm(TFAIL, "SEMCTL(SETVAL) failed errno = %d", errno);
130
131	}
132	if ((status = semctl(semid, 0, GETVAL, arg)) == -1) {
133		tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno);
134
135	}
136	if (status != arg.val) {
137		tst_resm(TFAIL, "error: unexpected value %d", status);
138
139	}
140	if ((status = semctl(semid, 0, GETPID, arg)) == -1) {
141		tst_resm(TFAIL, "semctl(GETPID) failed errno = %d", errno);
142
143	}
144	status = getpid();
145	if (status == 0) {
146		tst_resm(TFAIL, "error: unexpected pid %d", status);
147
148	}
149	if ((status = semctl(semid, 0, GETNCNT, arg)) == -1) {
150		tst_resm(TFAIL, "semctl(GETNCNT) failed errno = %d", errno);
151
152	}
153	if (status != 0) {
154		tst_resm(TFAIL, "error: unexpected semncnt %d", status);
155
156	}
157	if ((status = semctl(semid, 0, GETZCNT, arg)) == -1) {
158		tst_resm(TFAIL, "semctl(GETZCNT) failed errno = %d", errno);
159
160	}
161	if (status != 0) {
162		tst_resm(TFAIL, "error: unexpected semzcnt %d", status);
163
164	}
165
166	tst_resm(TPASS, "semctl07 ran successfully!");
167/*--------------------------------------------------------------*/
168/* Clean up any files created by test before exit.		*/
169/*--------------------------------------------------------------*/
170
171	cleanup();
172	return (0);
173}
174
175/*--------------------------------------------------------------*/
176
177/***************************************************************
178 * setup() - performs all ONE TIME setup for this test.
179 *****************************************************************/
180void setup()
181{
182	/* You will want to enable some signal handling so you can capture
183	 * unexpected signals like SIGSEGV.
184	 *                   */
185	tst_sig(NOFORK, DEF_HANDLER, cleanup);
186
187	/* One cavet that hasn't been fixed yet.  TEST_PAUSE contains the code to
188	 * fork the test with the -c option.  You want to make sure you do this
189	 * before you create your temporary directory.
190	 */
191	TEST_PAUSE;
192
193	/*
194	 * Create a temporary directory and cd into it.
195	 * This helps to ensure that a unique msgkey is created.
196	 * See ../lib/libipc.c for more information.
197	 */
198	tst_tmpdir();
199
200	/* get an IPC resource key */
201	key = getipckey();
202	nsems = 1;
203
204	if ((semid = semget(key, nsems, SEM_RA | IPC_CREAT)) == -1) {
205		tst_resm(TFAIL, "semget() failed errno = %d", errno);
206		tst_exit();
207	}
208}
209
210/***************************************************************
211 * cleanup() - performs all ONE TIME cleanup for this test at
212 * completion or premature exit.
213 ****************************************************************/
214void cleanup()
215{
216	/* if it exists, remove the semaphore resouce */
217	rm_sema(semid);
218
219	tst_rmdir();
220
221	/*
222	 * print timing stats if that option was specified.
223	 * print errno log if that option was specified.
224	 */
225	TEST_CLEANUP;
226
227}
228