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
51void setup(void);
52void cleanup(void);
53
54char *TCID = "semctl07";
55int TST_TOTAL = 1;
56
57key_t key;
58int semid = -1, nsems;
59
60int 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
155void 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
172void cleanup(void)
173{
174	rm_sema(semid);
175	tst_rmdir();
176}
177