blob: fb616507fdee160b808213f7cf47679c742f1d41 [file] [log] [blame]
subrata_modak812b8502009-05-29 10:38:21 +00001/******************************************************************************/
Cyril Hrubisbe8b8782014-03-18 17:55:52 +01002/* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */
Garrett Cooper2384bd42010-11-22 14:53:11 -08003/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
Cyril Hrubisbe8b8782014-03-18 17:55:52 +01004/* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */
subrata_modak812b8502009-05-29 10:38:21 +00005/* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */
Cyril Hrubisbe8b8782014-03-18 17:55:52 +01006/* Porting from Crackerjack to LTP is done by */
7/* Manas Kumar Nayak maknayak@in.ibm.com> */
8/* */
subrata_modak812b8502009-05-29 10:38:21 +00009/* This program is free software; you can redistribute it and/or modify */
10/* it under the terms of the GNU General Public License as published by */
Cyril Hrubisbe8b8782014-03-18 17:55:52 +010011/* the Free Software Foundation; either version 2 of the License, or */
12/* (at your option) any later version. */
13/* */
14/* This program is distributed in the hope that it will be useful, */
15/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
16/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
17/* the GNU General Public License for more details. */
18/* */
19/* You should have received a copy of the GNU General Public License */
20/* along with this program; if not, write to the Free Software Foundation, */
21/* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
22/* */
subrata_modak812b8502009-05-29 10:38:21 +000023/******************************************************************************/
24/******************************************************************************/
Cyril Hrubisbe8b8782014-03-18 17:55:52 +010025/* */
26/* Description: This tests the mq_notify() syscall */
27/* */
subrata_modak812b8502009-05-29 10:38:21 +000028/******************************************************************************/
Garrett Cooper09cbd9c2010-02-18 21:24:03 -080029#define _XOPEN_SOURCE 600
subrata_modak812b8502009-05-29 10:38:21 +000030#include <sys/syscall.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/uio.h>
34#include <getopt.h>
Garrett Cooper2384bd42010-11-22 14:53:11 -080035#include <libgen.h>
36#include <limits.h>
subrata_modak812b8502009-05-29 10:38:21 +000037#include <errno.h>
38#include <stdio.h>
39#include <unistd.h>
40#include <string.h>
41#include <mqueue.h>
42#include <signal.h>
Garrett Cooper2384bd42010-11-22 14:53:11 -080043#include <stdlib.h>
subrata_modak812b8502009-05-29 10:38:21 +000044
45#include "../utils/include_j_h.h"
46
subrata_modak812b8502009-05-29 10:38:21 +000047#include "test.h"
subrata_modak812b8502009-05-29 10:38:21 +000048#include "linux_syscall_numbers.h"
49
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020050char *TCID = "mq_notify01";
Wanlong Gao354ebb42012-12-07 10:10:04 +080051int testno;
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020052int TST_TOTAL = 1;
subrata_modak812b8502009-05-29 10:38:21 +000053
Cyril Hrubisbe8b8782014-03-18 17:55:52 +010054static void cleanup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +080055{
Garrett Cooper2384bd42010-11-22 14:53:11 -080056 tst_rmdir();
subrata_modak812b8502009-05-29 10:38:21 +000057}
58
Cyril Hrubisbe8b8782014-03-18 17:55:52 +010059static void setup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +080060{
Garrett Cooper2384bd42010-11-22 14:53:11 -080061 TEST_PAUSE;
62 tst_tmpdir();
subrata_modak812b8502009-05-29 10:38:21 +000063}
64
subrata_modak812b8502009-05-29 10:38:21 +000065#define SYSCALL_NAME "mq_notify"
66
subrata_modak812b8502009-05-29 10:38:21 +000067static int opt_debug;
68static char *progname;
69static int notified;
70static int cmp_ok;
71
subrata_modak812b8502009-05-29 10:38:21 +000072enum test_type {
Garrett Cooper2384bd42010-11-22 14:53:11 -080073 NORMAL,
74 FD_NONE,
75 FD_NOT_EXIST,
76 FD_FILE,
77 ALREADY_REGISTERED,
subrata_modak812b8502009-05-29 10:38:21 +000078};
79
subrata_modak812b8502009-05-29 10:38:21 +000080struct test_case {
Garrett Cooper2384bd42010-11-22 14:53:11 -080081 int notify;
subrata_modak812b8502009-05-29 10:38:21 +000082 int ttype;
Garrett Cooper2384bd42010-11-22 14:53:11 -080083 int ret;
84 int err;
subrata_modak812b8502009-05-29 10:38:21 +000085};
86
87#define MAX_MSGSIZE 8192
Garrett Cooper2384bd42010-11-22 14:53:11 -080088#define MSG_SIZE 16
subrata_modak812b8502009-05-29 10:38:21 +000089#define USER_DATA 0x12345678
90
subrata_modak812b8502009-05-29 10:38:21 +000091static struct test_case tcase[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +080092 { // case00
93 .ttype = NORMAL,
94 .notify = SIGEV_NONE,
95 .ret = 0,
96 .err = 0,
97 },
98 { // case01
99 .ttype = NORMAL,
100 .notify = SIGEV_SIGNAL,
101 .ret = 0,
102 .err = 0,
103 },
104 { // case02
105 .ttype = NORMAL,
106 .notify = SIGEV_THREAD,
107 .ret = 0,
108 .err = 0,
109 },
110 { // case03
111 .ttype = FD_NONE,
112 .notify = SIGEV_NONE,
113 .ret = -1,
114 .err = EBADF,
115 },
116 { // case04
117 .ttype = FD_NOT_EXIST,
118 .notify = SIGEV_NONE,
119 .ret = -1,
120 .err = EBADF,
121 },
122 { // case05
123 .ttype = FD_FILE,
124 .notify = SIGEV_NONE,
125 .ret = -1,
126 .err = EBADF,
127 },
128 { // case06
129 .ttype = ALREADY_REGISTERED,
130 .notify = SIGEV_NONE,
131 .ret = -1,
132 .err = EBUSY,
133 },
subrata_modak812b8502009-05-29 10:38:21 +0000134};
135
Wanlong Gao354ebb42012-12-07 10:10:04 +0800136static void sigfunc(int signo, siginfo_t * info, void *data)
subrata_modak812b8502009-05-29 10:38:21 +0000137{
Garrett Cooper2384bd42010-11-22 14:53:11 -0800138 if (opt_debug) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 tst_resm(TINFO, "si_code E:%d,\tR:%d", info->si_code,
140 SI_MESGQ);
141 tst_resm(TINFO, "si_signo E:%d,\tR:%d", info->si_signo,
142 SIGUSR1);
143 tst_resm(TINFO, "si_value E:0x%x,\tR:0x%x",
144 info->si_value.sival_int, USER_DATA);
145 tst_resm(TINFO, "si_pid E:%d,\tR:%d", info->si_pid, getpid());
146 tst_resm(TINFO, "si_uid E:%d,\tR:%d", info->si_uid, getuid());
Garrett Cooper2384bd42010-11-22 14:53:11 -0800147 }
148 cmp_ok = info->si_code == SI_MESGQ &&
Wanlong Gao354ebb42012-12-07 10:10:04 +0800149 info->si_signo == SIGUSR1 &&
150 info->si_value.sival_int == USER_DATA &&
151 info->si_pid == getpid() && info->si_uid == getuid();
Garrett Cooper2384bd42010-11-22 14:53:11 -0800152 notified = 1;
subrata_modak812b8502009-05-29 10:38:21 +0000153}
154
155static void tfunc(union sigval sv)
156{
Garrett Cooper2384bd42010-11-22 14:53:11 -0800157 cmp_ok = sv.sival_int == USER_DATA;
158 notified = 1;
subrata_modak812b8502009-05-29 10:38:21 +0000159}
160
subrata_modak812b8502009-05-29 10:38:21 +0000161static int do_test(struct test_case *tc)
162{
Garrett Cooper2384bd42010-11-22 14:53:11 -0800163 int sys_ret;
164 int sys_errno;
165 int result = RESULT_OK;
166 int rc, i, fd = -1;
167 struct sigevent ev;
168 struct sigaction sigact;
Garrett Cooper09cbd9c2010-02-18 21:24:03 -0800169 struct timespec abs_timeout;
Garrett Cooper2384bd42010-11-22 14:53:11 -0800170 char smsg[MAX_MSGSIZE];
subrata_modak812b8502009-05-29 10:38:21 +0000171
Garrett Cooper2384bd42010-11-22 14:53:11 -0800172 notified = cmp_ok = 1;
subrata_modak812b8502009-05-29 10:38:21 +0000173
Garrett Cooper09cbd9c2010-02-18 21:24:03 -0800174 /* Don't timeout. */
175 abs_timeout.tv_sec = 0;
176 abs_timeout.tv_nsec = 0;
177
Garrett Cooper2384bd42010-11-22 14:53:11 -0800178 /*
179 * When test ended with SIGTERM etc, mq discriptor is left remains.
180 * So we delete it first.
181 */
182 mq_unlink(QUEUE_NAME);
subrata_modak812b8502009-05-29 10:38:21 +0000183
Garrett Cooper2384bd42010-11-22 14:53:11 -0800184 switch (tc->ttype) {
185 case FD_NOT_EXIST:
186 fd = INT_MAX - 1;
187 /* fallthrough */
subrata_modak812b8502009-05-29 10:38:21 +0000188 case FD_NONE:
Garrett Cooper2384bd42010-11-22 14:53:11 -0800189 break;
190 case FD_FILE:
191 TEST(fd = open("/", O_RDONLY));
192 if (TEST_RETURN < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800193 tst_resm(TFAIL, "can't open \"/\".");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800194 result = 1;
195 goto EXIT;
196 }
197 break;
198 default:
199 /*
200 * Open message queue
201 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800202 TEST(fd =
203 mq_open(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU,
204 NULL));
Garrett Cooper2384bd42010-11-22 14:53:11 -0800205 if (TEST_RETURN < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800206 tst_resm(TFAIL | TTERRNO, "mq_open failed");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800207 result = 1;
208 goto EXIT;
209 }
210 }
subrata_modak812b8502009-05-29 10:38:21 +0000211
212 /*
Garrett Cooper2384bd42010-11-22 14:53:11 -0800213 * Set up struct sigevent
214 */
215 ev.sigev_notify = tc->notify;
subrata_modak812b8502009-05-29 10:38:21 +0000216
Garrett Cooper2384bd42010-11-22 14:53:11 -0800217 switch (tc->notify) {
218 case SIGEV_SIGNAL:
219 notified = cmp_ok = 0;
220 ev.sigev_signo = SIGUSR1;
221 ev.sigev_value.sival_int = USER_DATA;
222
223 memset(&sigact, 0, sizeof(sigact));
224 sigact.sa_sigaction = sigfunc;
225 sigact.sa_flags = SA_SIGINFO;
226 TEST(rc = sigaction(SIGUSR1, &sigact, NULL));
227 break;
228 case SIGEV_THREAD:
229 notified = cmp_ok = 0;
230 ev.sigev_notify_function = tfunc;
231 ev.sigev_notify_attributes = NULL;
232 ev.sigev_value.sival_int = USER_DATA;
233 break;
234 }
subrata_modak812b8502009-05-29 10:38:21 +0000235
236 if (tc->ttype == ALREADY_REGISTERED) {
Garrett Cooper2384bd42010-11-22 14:53:11 -0800237 TEST(rc = mq_notify(fd, &ev));
238 if (TEST_RETURN < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800239 tst_resm(TFAIL | TTERRNO, "mq_notify failed");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800240 result = 1;
241 goto EXIT;
242 }
243 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800244
subrata_modak812b8502009-05-29 10:38:21 +0000245 /*
Garrett Cooper2384bd42010-11-22 14:53:11 -0800246 * Execute system call
247 */
248 errno = 0;
249 sys_ret = mq_notify(fd, &ev);
Garrett Cooper3fceccb2010-02-18 21:43:51 -0800250 sys_errno = errno;
Garrett Cooper2384bd42010-11-22 14:53:11 -0800251 if (sys_ret < 0)
252 goto TEST_END;
subrata_modak812b8502009-05-29 10:38:21 +0000253
Garrett Cooper2384bd42010-11-22 14:53:11 -0800254 /*
255 * Prepare send message
256 */
257 for (i = 0; i < MSG_SIZE; i++)
258 smsg[i] = i;
259 TEST(rc = mq_timedsend(fd, smsg, MSG_SIZE, 0, &abs_timeout));
260 if (rc < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800261 tst_resm(TFAIL | TTERRNO, "mq_timedsend failed");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800262 result = 1;
263 goto EXIT;
264 }
subrata_modak812b8502009-05-29 10:38:21 +0000265
Garrett Cooper2384bd42010-11-22 14:53:11 -0800266 while (!notified)
267 usleep(10000);
subrata_modak812b8502009-05-29 10:38:21 +0000268
269TEST_END:
Garrett Cooper2384bd42010-11-22 14:53:11 -0800270 /*
271 * Check results
272 */
273 result |= (sys_ret != 0 && sys_errno != tc->err) || !cmp_ok;
274 PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno,
275 cmp_ok);
subrata_modak812b8502009-05-29 10:38:21 +0000276
277EXIT:
Garrett Cooper2384bd42010-11-22 14:53:11 -0800278 if (fd >= 0) {
279 close(fd);
280 mq_unlink(QUEUE_NAME);
281 }
subrata_modak812b8502009-05-29 10:38:21 +0000282
Garrett Cooper2384bd42010-11-22 14:53:11 -0800283 return result;
subrata_modak812b8502009-05-29 10:38:21 +0000284}
subrata_modak812b8502009-05-29 10:38:21 +0000285
subrata_modak812b8502009-05-29 10:38:21 +0000286static void usage(const char *progname)
287{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800288 tst_resm(TINFO, "usage: %s [options]", progname);
289 tst_resm(TINFO, "This is a regression test program of %s system call.",
290 SYSCALL_NAME);
291 tst_resm(TINFO, "options:");
292 tst_resm(TINFO, " -d --debug Show debug messages");
293 tst_resm(TINFO, " -h --help Show this message");
subrata_modak812b8502009-05-29 10:38:21 +0000294}
295
Wanlong Gao354ebb42012-12-07 10:10:04 +0800296int main(int ac, char **av)
297{
subrata_modak812b8502009-05-29 10:38:21 +0000298 int result = RESULT_OK;
Garrett Cooper2384bd42010-11-22 14:53:11 -0800299 int c;
300 int i;
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200301 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200302 const char *msg;
subrata_modak812b8502009-05-29 10:38:21 +0000303
304 struct option long_options[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800305 {"debug", no_argument, 0, 'd'},
306 {"help", no_argument, 0, 'h'},
307 {NULL, 0, NULL, 0}
Garrett Cooper2384bd42010-11-22 14:53:11 -0800308 };
subrata_modak812b8502009-05-29 10:38:21 +0000309
Garrett Cooper2384bd42010-11-22 14:53:11 -0800310 progname = basename(av[0]);
Garrett Cooper2c282152010-12-16 00:55:50 -0800311
Garrett Cooper2384bd42010-11-22 14:53:11 -0800312 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800313 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak812b8502009-05-29 10:38:21 +0000314
Garrett Cooper2384bd42010-11-22 14:53:11 -0800315 setup();
subrata_modak812b8502009-05-29 10:38:21 +0000316
Garrett Cooper2384bd42010-11-22 14:53:11 -0800317 for (lc = 0; TEST_LOOPING(lc); ++lc) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800318 tst_count = 0;
Garrett Cooper2384bd42010-11-22 14:53:11 -0800319 for (testno = 0; testno < TST_TOTAL; ++testno) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800320 TEST(c = getopt_long(ac, av, "dh", long_options, NULL));
321 while (TEST_RETURN != -1) {
Garrett Cooper2384bd42010-11-22 14:53:11 -0800322 switch (c) {
323 case 'd':
324 opt_debug = 1;
325 break;
326 default:
327 usage(progname);
328 }
329 }
subrata_modak812b8502009-05-29 10:38:21 +0000330
Garrett Cooper2384bd42010-11-22 14:53:11 -0800331 if (ac != optind) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800332 tst_resm(TINFO, "Options are not match.");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800333 usage(progname);
334 }
subrata_modak812b8502009-05-29 10:38:21 +0000335
Wanlong Gao354ebb42012-12-07 10:10:04 +0800336 for (i = 0; i < (int)(sizeof(tcase) / sizeof(tcase[0]));
337 i++) {
Garrett Cooper2384bd42010-11-22 14:53:11 -0800338 int ret;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800339 tst_resm(TINFO, "(case%02d) START", i);
Garrett Cooper2384bd42010-11-22 14:53:11 -0800340 ret = do_test(&tcase[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800341 tst_resm(TINFO, "(case%02d) END => %s",
342 i, (ret == 0) ? "OK" : "NG");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800343 result |= ret;
344 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800345
Wanlong Gao354ebb42012-12-07 10:10:04 +0800346 switch (result) {
Garrett Cooper2384bd42010-11-22 14:53:11 -0800347 case RESULT_OK:
348 tst_resm(TPASS, "mq_notify call succeeded");
349 break;
subrata_modak812b8502009-05-29 10:38:21 +0000350
Garrett Cooper2384bd42010-11-22 14:53:11 -0800351 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800352 tst_brkm(TFAIL, cleanup, "mq_notify failed");
Garrett Cooper2384bd42010-11-22 14:53:11 -0800353 break;
354 }
subrata_modak812b8502009-05-29 10:38:21 +0000355
Garrett Cooper2384bd42010-11-22 14:53:11 -0800356 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800357 }
Garrett Cooper2384bd42010-11-22 14:53:11 -0800358 cleanup();
subrata_modak812b8502009-05-29 10:38:21 +0000359 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700360}