1 /******************************************************************************/
2 /* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */
3 /* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
4 /* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */
5 /* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */
6 /* */
7 /* This program is free software; you can redistribute it and/or modify */
8 /* it under the terms of the GNU General Public License as published by */
9 /* the Free Software Foundation; either version 2 of the License, or */
10 /* (at your option) any later version. */
11 /* */
12 /* This program is distributed in the hope that it will be useful, */
13 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
14 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
15 /* the GNU General Public License for more details. */
16 /* */
17 /* You should have received a copy of the GNU General Public License */
18 /* along with this program; if not, write to the Free Software */
19 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
20 /* */
21 /******************************************************************************/
22 /******************************************************************************/
23 /* */
24 /* File: mq_ulink01.c */
25 /* */
26 /* Description: This tests the mq_ulink() syscall */
27 /* */
28 /* */
29 /* */
30 /* */
31 /* */
32 /* */
33 /* Usage: <for command-line> */
34 /* mq_ulink01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
35 /* where, -c n : Run n copies concurrently. */
36 /* -e : Turn on errno logging. */
37 /* -i n : Execute test n times. */
38 /* -I x : Execute test for x seconds. */
39 /* -P x : Pause for x seconds between iterations. */
40 /* -t : Turn on syscall timing. */
41 /* */
42 /* Total Tests: 1 */
43 /* */
44 /* Test Name: mq_ulink01 */
45 /* History: Porting from Crackerjack to LTP is done by */
46 /* Manas Kumar Nayak maknayak@in.ibm.com> */
47 /******************************************************************************/
48
49 #include <sys/syscall.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <sys/uio.h>
53 #include <getopt.h>
54 #include <stdlib.h>
55 #include <errno.h>
56 #include <stdio.h>
57 #include <unistd.h>
58 #include <string.h>
59 #include <mqueue.h>
60 #include <limits.h>
61
62 #include "../utils/include_j_h.h"
63 #include "../utils/common_j_h.c"
64
65 #include "test.h"
66 #include "linux_syscall_numbers.h"
67
68 char *TCID = "mq_ulink01";
69 int testno;
70 int TST_TOTAL = 1;
71
72 /* Extern Global Functions */
73 /******************************************************************************/
74 /* */
75 /* Function: cleanup */
76 /* */
77 /* Description: Performs all one time clean up for this test on successful */
78 /* completion, premature exit or failure. Closes all temporary */
79 /* files, removes all temporary directories exits the test with */
80 /* appropriate return code by calling tst_exit() function. */
81 /* */
82 /* Input: None. */
83 /* */
84 /* Output: None. */
85 /* */
86 /* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
87 /* On success - Exits calling tst_exit(). With '0' return code. */
88 /* */
89 /******************************************************************************/
cleanup(void)90 void cleanup(void)
91 {
92
93 tst_rmdir();
94 }
95
96 /* Local Functions */
97 /******************************************************************************/
98 /* */
99 /* Function: setup */
100 /* */
101 /* Description: Performs all one time setup for this test. This function is */
102 /* typically used to capture signals, create temporary dirs */
103 /* and temporary files that may be used in the course of this */
104 /* test. */
105 /* */
106 /* Input: None. */
107 /* */
108 /* Output: None. */
109 /* */
110 /* Return: On failure - Exits by calling cleanup(). */
111 /* On success - returns 0. */
112 /* */
113 /******************************************************************************/
setup(void)114 void setup(void)
115 {
116 tst_require_root();
117 /* Capture signals if any */
118 /* Create temporary directories */
119 TEST_PAUSE;
120 tst_tmpdir();
121 }
122
123 /*
124 * Macros
125 */
126 #define SYSCALL_NAME "mq_ulink"
127
128 enum test_type {
129 NORMAL,
130 };
131
132 /*
133 * Data Structure
134 */
135 struct test_case {
136 char *user;
137 char *qname;
138 int ttype;
139 int ret;
140 int err;
141 };
142
143 /* Test cases
144 *
145 * test status of errors on man page
146 *
147 * EACCES v (permission is denied)
148 * ENAMETOOLONG v (too long name length)
149 * ENOENT v (named message queue does not exist)
150 */
151
152 static struct test_case tcase[] = {
153 { // case00
154 .ttype = NORMAL,
155 .qname = QUEUE_NAME,
156 .ret = 0,
157 .err = 0,
158 },
159 { // case01
160 .ttype = NORMAL,
161 .user = "nobody",
162 .qname = QUEUE_NAME,
163 .ret = -1,
164 .err = EACCES,
165 },
166 { // case02
167 .ttype = NORMAL,
168 // 0 1 2 3
169 // 0123456789012345678901234567890123456789
170 .qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
171 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
172 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
173 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
175 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaa",
176 .ret = -1,
177 .err = ENOENT,
178 },
179 { // case03
180 .ttype = NORMAL,
181 // 0 1 2 3
182 // 0123456789012345678901234567890123456789
183 .qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
184 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
185 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
186 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
187 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
188 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa",
189 .ret = -1,
190 .err = ENAMETOOLONG,
191 },
192 };
193
194 /*
195 * do_test()
196 *
197 * Input : TestCase Data
198 * Return : RESULT_OK(0), RESULT_NG(1)
199 *
200 */
201
do_test(struct test_case * tc)202 static int do_test(struct test_case *tc)
203 {
204 int sys_ret;
205 int sys_errno;
206 int result = RESULT_OK;
207 int rc, fd1 = -1, fd2 = -1;
208 uid_t old_uid = -1;
209
210 /*
211 * When test ended with SIGTERM etc, mq discriptor is left remains.
212 * So we delete it first.
213 */
214 TEST(mq_unlink(QUEUE_NAME));
215
216 /*
217 * Open message queue
218 */
219 rc = mq_open(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL);
220 if (rc == -1) {
221 tst_resm(TFAIL | TTERRNO, "mq_open failed");
222 result = 1;
223 goto EXIT;
224 }
225 fd1 = rc;
226
227 /*
228 * Change effective user id
229 */
230 if (tc->user != NULL) {
231 TEST(rc = setup_euid(tc->user, &old_uid));
232 if (TEST_RETURN < 0) {
233 result = 1;
234 goto EXIT;
235 }
236 }
237
238 /*
239 * Execute system call
240 */
241 errno = 0;
242 TEST(sys_ret = mq_unlink(tc->qname));
243 sys_errno = errno;
244 if (sys_ret >= 0)
245 fd2 = sys_ret;
246
247 /*
248 * Check results
249 */
250 result |= (sys_errno != tc->err);
251 PRINT_RESULT(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno);
252
253 EXIT:
254 if (tc->user != NULL && old_uid != -1)
255 cleanup_euid(old_uid);
256
257 if (fd1 >= 0)
258 close(fd1);
259 if (fd2 >= 0)
260 close(fd2);
261 mq_unlink(QUEUE_NAME);
262 return 0;
263 }
264
main(int ac,char ** av)265 int main(int ac, char **av)
266 {
267 int i;
268 int lc;
269
270 tst_parse_opts(ac, av, NULL, NULL);
271
272 setup();
273
274 for (lc = 0; TEST_LOOPING(lc); ++lc) {
275 tst_count = 0;
276 for (testno = 0; testno < TST_TOTAL; ++testno) {
277
278 int ret;
279
280 ret = 0;
281
282 for (i = 0; ret == 0 &&
283 i < (int)ARRAY_SIZE(tcase); i++) {
284 ret = do_test(&tcase[i]);
285 }
286
287 }
288 }
289 cleanup();
290 tst_exit();
291 }
292