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 /* 11/06/2002 Port to LTP dbarrera@us.ibm.com */
22 /* 12/03/2008 Fix concurrency issue mfertre@irisa.fr */
23
24 /*
25 * NAME
26 * msgctl06
27 *
28 * CALLS
29 * msgget(2) msgctl(2)
30 *
31 * ALGORITHM
32 * Get and manipulate a message queue.
33 *
34 * RESTRICTIONS
35 *
36 */
37
38 #include <sys/types.h> /* needed for test */
39 #include <sys/ipc.h> /* needed for test */
40 #include <sys/msg.h> /* needed for test */
41 #include <stdio.h> /* needed by testhead.h */
42 #include "test.h"
43 #include "ipcmsg.h"
44
45 void setup();
46 void cleanup();
47
48 char *TCID = "msgctl06";
49 int TST_TOTAL = 1;
50
51 /*
52 * msgctl3_t -- union of msgctl(2)'s possible argument # 3 types.
53 */
54 typedef union msgctl3_u {
55 struct msqid_ds *msq_ds; /* pointer to msqid_ds struct */
56 struct ipc_acl *msq_acl; /* pointer ACL buff and size */
57 } msgctl3_t;
58
59 extern int local_flag;
60
61 int msqid, status;
62 struct msqid_ds buf;
63
64 /*--------------------------------------------------------------*/
65
main(void)66 int main(void)
67 {
68 key_t key;
69 setup();
70
71 key = getipckey();
72 TEST(msgget(key, IPC_CREAT | IPC_EXCL));
73 msqid = TEST_RETURN;
74 if (TEST_RETURN == -1) {
75 tst_brkm(TFAIL | TTERRNO, NULL, "msgget() failed");
76 }
77
78 TEST(msgctl(msqid, IPC_STAT, &buf));
79 status = TEST_RETURN;
80 if (TEST_RETURN == -1) {
81 tst_resm(TFAIL | TTERRNO,
82 "msgctl(msqid, IPC_STAT, &buf) failed");
83 (void)msgctl(msqid, IPC_RMID, NULL);
84 tst_exit();
85 }
86
87 /*
88 * Check contents of msqid_ds structure.
89 */
90
91 if (buf.msg_qnum != 0) {
92 tst_brkm(TFAIL, NULL, "error: unexpected nbr of messages %ld",
93 buf.msg_qnum);
94 }
95 if (buf.msg_perm.uid != getuid()) {
96 tst_brkm(TFAIL, NULL, "error: unexpected uid %d",
97 buf.msg_perm.uid);
98 }
99 if (buf.msg_perm.gid != getgid()) {
100 tst_brkm(TFAIL, NULL, "error: unexpected gid %d",
101 buf.msg_perm.gid);
102 }
103 if (buf.msg_perm.cuid != getuid()) {
104 tst_brkm(TFAIL, NULL, "error: unexpected cuid %d",
105 buf.msg_perm.cuid);
106 }
107 if (buf.msg_perm.cgid != getgid()) {
108 tst_brkm(TFAIL, NULL, "error: unexpected cgid %d",
109 buf.msg_perm.cgid);
110 }
111
112 tst_resm(TPASS, "msgctl06 ran successfully!");
113 /***************************************************************
114 * cleanup and exit
115 ***************************************************************/
116 cleanup();
117
118 tst_exit();
119 }
120
121 /***************************************************************
122 * * setup() - performs all ONE TIME setup for this test.
123 * ****************************************************************/
setup(void)124 void setup(void)
125 {
126 tst_require_root();
127
128 /* You will want to enable some signal handling so you can capture
129 * unexpected signals like SIGSEGV.
130 */
131 tst_sig(NOFORK, DEF_HANDLER, cleanup);
132
133 /* One cavet that hasn't been fixed yet. TEST_PAUSE contains the code to
134 * fork the test with the -c option. You want to make sure you do this
135 * before you create your temporary directory.
136 */
137 TEST_PAUSE;
138
139 /*
140 * Create a temporary directory and cd into it.
141 * This helps to ensure that a unique msgkey is created.
142 * See ../lib/libipc.c for more information.
143 */
144 tst_tmpdir();
145 }
146
147 /***************************************************************
148 * * * cleanup() - performs all ONE TIME cleanup for this test at
149 * * * completion or premature exit.
150 * * ***************************************************************/
cleanup(void)151 void cleanup(void)
152 {
153 int status;
154
155 /*
156 * Remove the message queue from the system
157 */
158 #ifdef DEBUG
159 tst_resm(TINFO, "Remove the message queue");
160 #endif
161 fflush(stdout);
162 (void)msgctl(msqid, IPC_RMID, NULL);
163 if ((status = msgctl(msqid, IPC_STAT, &buf)) != -1) {
164 (void)msgctl(msqid, IPC_RMID, NULL);
165 tst_resm(TFAIL, "msgctl(msqid, IPC_RMID) failed");
166
167 }
168
169 fflush(stdout);
170
171 tst_rmdir();
172
173 }
174