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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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>
42 #include <sys/ipc.h>
43 #include <sys/sem.h>
44 #include <signal.h>
45 #include <errno.h>
46 #include <stdio.h>
47 #include <sys/wait.h>
48 #include "ipcsem.h"
49 #include "test.h"
50 
51 void setup(void);
52 void cleanup(void);
53 
54 char *TCID = "semctl07";
55 int TST_TOTAL = 1;
56 
57 key_t key;
58 int semid = -1, nsems;
59 
main(int argc,char * argv[])60 int main(int argc, char *argv[])
61 {
62 	int status;
63 	struct semid_ds buf_ds;
64 	union semun arg;
65 
66 	tst_parse_opts(argc, argv, NULL, NULL);
67 
68 	setup();
69 
70 	arg.buf = &buf_ds;
71 	if ((status = semctl(semid, 0, IPC_STAT, arg)) == -1) {
72 		tst_resm(TFAIL, "semctl() failed errno = %d", errno);
73 		semctl(semid, 1, IPC_RMID, arg);
74 
75 	}
76 
77 	/*
78 	 * Check contents of semid_ds structure.
79 	 */
80 
81 	if (arg.buf->sem_nsems != nsems) {
82 		tst_resm(TFAIL, "error: unexpected number of sems %lu",
83 			 arg.buf->sem_nsems);
84 
85 	}
86 	if (arg.buf->sem_perm.uid != getuid()) {
87 		tst_resm(TFAIL, "error: unexpected uid %d",
88 			 arg.buf->sem_perm.uid);
89 
90 	}
91 	if (arg.buf->sem_perm.gid != getgid()) {
92 		tst_resm(TFAIL, "error: unexpected gid %d",
93 			 arg.buf->sem_perm.gid);
94 
95 	}
96 	if (arg.buf->sem_perm.cuid != getuid()) {
97 		tst_resm(TFAIL, "error: unexpected cuid %d",
98 			 arg.buf->sem_perm.cuid);
99 
100 	}
101 	if (arg.buf->sem_perm.cgid != getgid()) {
102 		tst_resm(TFAIL, "error: unexpected cgid %d",
103 			 arg.buf->sem_perm.cgid);
104 
105 	}
106 	if ((status = semctl(semid, 0, GETVAL, arg)) == -1) {
107 		tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno);
108 
109 	}
110 	arg.val = 1;
111 	if ((status = semctl(semid, 0, SETVAL, arg)) == -1) {
112 		tst_resm(TFAIL, "SEMCTL(SETVAL) failed errno = %d", errno);
113 
114 	}
115 	if ((status = semctl(semid, 0, GETVAL, arg)) == -1) {
116 		tst_resm(TFAIL, "semctl(GETVAL) failed errno = %d", errno);
117 
118 	}
119 	if (status != arg.val) {
120 		tst_resm(TFAIL, "error: unexpected value %d", status);
121 
122 	}
123 	if ((status = semctl(semid, 0, GETPID, arg)) == -1) {
124 		tst_resm(TFAIL, "semctl(GETPID) failed errno = %d", errno);
125 
126 	}
127 	status = getpid();
128 	if (status == 0) {
129 		tst_resm(TFAIL, "error: unexpected pid %d", status);
130 
131 	}
132 	if ((status = semctl(semid, 0, GETNCNT, arg)) == -1) {
133 		tst_resm(TFAIL, "semctl(GETNCNT) failed errno = %d", errno);
134 
135 	}
136 	if (status != 0) {
137 		tst_resm(TFAIL, "error: unexpected semncnt %d", status);
138 
139 	}
140 	if ((status = semctl(semid, 0, GETZCNT, arg)) == -1) {
141 		tst_resm(TFAIL, "semctl(GETZCNT) failed errno = %d", errno);
142 
143 	}
144 	if (status != 0) {
145 		tst_resm(TFAIL, "error: unexpected semzcnt %d", status);
146 
147 	}
148 
149 	tst_resm(TPASS, "semctl07 ran successfully!");
150 
151 	cleanup();
152 	tst_exit();
153 }
154 
setup(void)155 void setup(void)
156 {
157 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
158 
159 	TEST_PAUSE;
160 
161 	tst_tmpdir();
162 
163 	/* get an IPC resource key */
164 	key = getipckey();
165 	nsems = 1;
166 
167 	if ((semid = semget(key, nsems, SEM_RA | IPC_CREAT)) == -1) {
168 		tst_brkm(TFAIL, NULL, "semget() failed errno = %d", errno);
169 	}
170 }
171 
cleanup(void)172 void cleanup(void)
173 {
174 	rm_sema(semid);
175 	tst_rmdir();
176 }
177