• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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