* [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive
@ 2017-06-05 20:05 Petr Vorel
2017-06-05 20:05 ` [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup Petr Vorel
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Petr Vorel @ 2017-06-05 20:05 UTC (permalink / raw)
To: ltp
This is a regression from
commit 5c266719126b0e770102b787a904cf90ece922ec
Author: Petr Vorel <pvorel@suse.cz>
Date: Wed Mar 8 15:21:52 2017 +0100
syscalls/mq_timedreceive: convert to new API
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
.../syscalls/mq_timedreceive/mq_timedreceive01.c | 32 ++++++++++++++--------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c
index f6ff4a5a4..6ed670464 100644
--- a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c
+++ b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c
@@ -28,6 +28,10 @@
#include "tst_sig_proc.h"
#include "tst_safe_posix_ipc.h"
+#define MAX_MSGSIZE 8192
+#define QUEUE_NAME "/test_mqueue"
+
+static char smsg[MAX_MSGSIZE];
static struct sigaction act;
static pid_t pid;
static int fd, fd_root;
@@ -35,7 +39,7 @@ static struct timespec timeout_ts;
static struct timespec eintr_ts;
struct test_case {
- int len;
+ unsigned int len;
unsigned prio;
struct timespec *rq;
int fd;
@@ -47,10 +51,6 @@ struct test_case {
void (*cleanup)(void);
};
-#define MAX_MSGSIZE 8192
-
-#define QUEUE_NAME "/test_mqueue"
-
static void create_queue(void);
static void create_queue_nonblock(void);
static void create_queue_sig(void);
@@ -175,10 +175,15 @@ static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
static void setup(void)
{
+ unsigned int i;
+
act.sa_handler = sighandler;
sigaction(SIGINT, &act, NULL);
fd_root = SAFE_OPEN("/", O_RDONLY);
+
+ for (i = 0; i < MAX_MSGSIZE; i++)
+ smsg[i] = i;
}
static void cleanup(void)
@@ -227,12 +232,6 @@ static void open_fd(void)
static void send_msg(int fd, int len, int prio)
{
- char smsg[MAX_MSGSIZE];
- int i;
-
- for (i = 0; i < len; i++)
- smsg[i] = i;
-
if (mq_timedsend(fd, smsg, len, prio,
&((struct timespec){0})) < 0)
tst_brk(TBROK | TERRNO, "mq_timedsend failed");
@@ -256,9 +255,10 @@ static void unlink_queue_sig(void)
static void do_test(unsigned int i)
{
+ unsigned int j;
const struct test_case *tc = &tcase[i];
char rmsg[MAX_MSGSIZE];
- unsigned prio;
+ unsigned int prio;
size_t msg_len = MAX_MSGSIZE;
/*
@@ -308,6 +308,14 @@ static void do_test(unsigned int i)
return;
}
+ for (j = 0; j < tc->len; j++) {
+ if (rmsg[j] != smsg[j]) {
+ tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong data in loop %d returned %d, expected %d",
+ i, rmsg[j], smsg[j]);
+ return;
+ }
+ }
+
tst_res(TPASS, "mq_timedreceive returned %ld prio %u", TEST_RETURN, prio);
}
--
2.12.2
^ permalink raw reply related [flat|nested] 5+ messages in thread* [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup 2017-06-05 20:05 [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Petr Vorel @ 2017-06-05 20:05 ` Petr Vorel 2017-06-06 14:26 ` Cyril Hrubis 2017-06-05 20:05 ` [LTP] [PATCH 3/3] syscalls/mq_notify: Cleanup + use mq.h Petr Vorel 2017-06-06 13:58 ` [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Cyril Hrubis 2 siblings, 1 reply; 5+ messages in thread From: Petr Vorel @ 2017-06-05 20:05 UTC (permalink / raw) To: ltp and other changes: * Header mq.h to reuse common code. + Cleanup syscalls/mq_timedreceive. Signed-off-by: Petr Vorel <pvorel@suse.cz> --- testcases/kernel/syscalls/mq_timedreceive/Makefile | 2 + .../syscalls/mq_timedreceive/mq_timedreceive01.c | 158 ++--- testcases/kernel/syscalls/mq_timedsend/Makefile | 2 + .../kernel/syscalls/mq_timedsend/mq_timedsend01.c | 673 ++++++++------------- testcases/kernel/syscalls/utils/mq.h | 100 +++ 5 files changed, 381 insertions(+), 554 deletions(-) create mode 100644 testcases/kernel/syscalls/utils/mq.h diff --git a/testcases/kernel/syscalls/mq_timedreceive/Makefile b/testcases/kernel/syscalls/mq_timedreceive/Makefile index 2e1628e9f..0f2e05dfa 100644 --- a/testcases/kernel/syscalls/mq_timedreceive/Makefile +++ b/testcases/kernel/syscalls/mq_timedreceive/Makefile @@ -21,6 +21,8 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk CPPFLAGS ?= -D_POSIX_C_SOURCE=$(shell getconf _POSIX_MESSAGE_PASSING)L +CPPFLAGS += -I$(abs_srcdir)/../utils + LDLIBS += -lpthread -lrt include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c index 6ed670464..73b433da4 100644 --- a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c +++ b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c @@ -1,9 +1,11 @@ /* - * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd - * Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, - * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, - * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> - * Copyright (c) 2016-2017 Linux Test Project + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> + * + * Author(s): + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,49 +18,29 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <errno.h> #include <limits.h> -#include <mqueue.h> - -#include "tst_test.h" -#include "tst_sig_proc.h" -#include "tst_safe_posix_ipc.h" -#define MAX_MSGSIZE 8192 -#define QUEUE_NAME "/test_mqueue" +#include "mq.h" -static char smsg[MAX_MSGSIZE]; static struct sigaction act; -static pid_t pid; -static int fd, fd_root; -static struct timespec timeout_ts; -static struct timespec eintr_ts; struct test_case { + void (*setup)(void); + void (*cleanup)(void); + int fd; unsigned int len; - unsigned prio; + unsigned int prio; struct timespec *rq; - int fd; int invalid_msg; int send; int ret; int err; - void (*setup)(void); - void (*cleanup)(void); }; -static void create_queue(void); -static void create_queue_nonblock(void); -static void create_queue_sig(void); -static void create_queue_timeout(void); -static void open_fd(void); -static void unlink_queue(void); -static void unlink_queue_sig(void); - static const struct test_case tcase[] = { { .setup = create_queue, @@ -89,7 +71,7 @@ static const struct test_case tcase[] = { .cleanup = unlink_queue, .send = 1, .len = 1, - .prio = 32767, /* max priority */ + .prio = MQ_PRIO_MAX - 1, .ret = 0, .err = 0, }, @@ -115,57 +97,57 @@ static const struct test_case tcase[] = { .err = EBADF, }, { + .setup = open_fd, .len = 0, .ret = -1, .err = EBADF, - .setup = open_fd, }, { + .setup = create_queue_nonblock, + .cleanup = unlink_queue, .len = 16, .ret = -1, .err = EAGAIN, - .setup = create_queue_nonblock, - .cleanup = unlink_queue, }, { + .setup = create_queue, + .cleanup = unlink_queue, .len = 16, .rq = &(struct timespec) {.tv_sec = -1, .tv_nsec = 0}, .ret = -1, .err = EINVAL, - .setup = create_queue, - .cleanup = unlink_queue, }, { + .setup = create_queue, + .cleanup = unlink_queue, .len = 16, .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = -1}, .ret = -1, .err = EINVAL, - .setup = create_queue, - .cleanup = unlink_queue, }, { + .setup = create_queue, + .cleanup = unlink_queue, .len = 16, .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000}, .ret = -1, .err = EINVAL, - .setup = create_queue, - .cleanup = unlink_queue, }, { + .setup = create_queue_timeout, + .cleanup = unlink_queue, .len = 16, .ret = -1, .rq = &timeout_ts, .err = ETIMEDOUT, - .setup = create_queue_timeout, - .cleanup = unlink_queue, }, { + .setup = create_queue_sig, + .cleanup = unlink_queue_sig, .len = 16, .rq = &eintr_ts, .ret = -1, .err = EINTR, - .setup = create_queue_sig, - .cleanup = unlink_queue_sig, }, }; @@ -175,7 +157,7 @@ static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) static void setup(void) { - unsigned int i; + int i; act.sa_handler = sighandler; sigaction(SIGINT, &act, NULL); @@ -195,71 +177,13 @@ static void cleanup(void) SAFE_CLOSE(fd_root); } -static void create_queue(void) -{ - fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL); -} - -static void create_queue_nonblock(void) -{ - fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR | O_NONBLOCK, - S_IRWXU, NULL); -} - -static void create_queue_sig(void) -{ - clock_gettime(CLOCK_REALTIME, &eintr_ts); - eintr_ts.tv_sec += 3; - - create_queue(); - pid = create_sig_proc(SIGINT, 40, 200000); -} - -static void create_queue_timeout(void) -{ - clock_gettime(CLOCK_REALTIME, &timeout_ts); - timeout_ts.tv_nsec += 50000000; - timeout_ts.tv_sec += timeout_ts.tv_nsec / 1000000000; - timeout_ts.tv_nsec %= 1000000000; - - create_queue(); -} - -static void open_fd(void) -{ - fd = fd_root; -} - -static void send_msg(int fd, int len, int prio) -{ - if (mq_timedsend(fd, smsg, len, prio, - &((struct timespec){0})) < 0) - tst_brk(TBROK | TERRNO, "mq_timedsend failed"); -} - -static void unlink_queue(void) -{ - if (fd > 0) - SAFE_CLOSE(fd); - - mq_unlink(QUEUE_NAME); -} - -static void unlink_queue_sig(void) -{ - SAFE_KILL(pid, SIGTERM); - SAFE_WAIT(NULL); - - unlink_queue(); -} - static void do_test(unsigned int i) { - unsigned int j; const struct test_case *tc = &tcase[i]; - char rmsg[MAX_MSGSIZE]; + unsigned int j; unsigned int prio; - size_t msg_len = MAX_MSGSIZE; + size_t len = MAX_MSGSIZE; + char rmsg[len]; /* * When test ended with SIGTERM etc, mq descriptor is left remains. @@ -277,27 +201,25 @@ static void do_test(unsigned int i) send_msg(fd, tc->len, tc->prio); if (tc->invalid_msg) - msg_len -= 1; + len -= 1; - TEST(mq_timedreceive(fd, rmsg, msg_len, &prio, tc->rq)); + TEST(mq_timedreceive(fd, rmsg, len, &prio, tc->rq)); if (tc->cleanup) tc->cleanup(); if (TEST_RETURN < 0) { - if (TEST_ERRNO != tc->err) { + if (tc->err != TEST_ERRNO) tst_res(TFAIL | TTERRNO, "mq_timedreceive failed unexpectedly, expected %s", tst_strerrno(tc->err)); - } else { + else tst_res(TPASS | TTERRNO, "mq_timedreceive failed expectedly"); - } return; } - - if (TEST_RETURN != tc->len) { - tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong msg_len returned %ld, expected %d", + if (tc->len != TEST_RETURN) { + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong len returned %ld, expected %d", TEST_RETURN, tc->len); return; } @@ -310,13 +232,15 @@ static void do_test(unsigned int i) for (j = 0; j < tc->len; j++) { if (rmsg[j] != smsg[j]) { - tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong data in loop %d returned %d, expected %d", + tst_res(TFAIL | TTERRNO, + "mq_timedreceive wrong data in loop %d returned %d, expected %d", i, rmsg[j], smsg[j]); return; } } - tst_res(TPASS, "mq_timedreceive returned %ld prio %u", TEST_RETURN, prio); + tst_res(TPASS, "mq_timedreceive returned %ld, priority %u, length: %lu", + TEST_RETURN, prio, len); } static struct tst_test test = { diff --git a/testcases/kernel/syscalls/mq_timedsend/Makefile b/testcases/kernel/syscalls/mq_timedsend/Makefile index 71ebae98b..4e1b61282 100644 --- a/testcases/kernel/syscalls/mq_timedsend/Makefile +++ b/testcases/kernel/syscalls/mq_timedsend/Makefile @@ -20,6 +20,8 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk +CPPFLAGS += -I$(abs_srcdir)/../utils + LDLIBS += -lpthread -lrt include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c b/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c index 77198cea8..745008097 100644 --- a/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c +++ b/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c @@ -1,480 +1,279 @@ -/********************************************************************************/ -/* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */ -/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */ -/* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */ -/* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ -/* the GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* USA */ -/********************************************************************************/ -/************************************************************************/ -/* */ -/* File: mq_timedsend01.c */ -/* */ -/* Description: This tests the mq_timedsend() syscall */ -/* */ -/* */ -/* */ -/* */ -/* */ -/* */ -/* Usage: <for command-line> */ -/* mq_timedsend01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */ -/* where, -c n : Run n copies concurrently. */ -/* -e : Turn on errno logging. */ -/* -i n : Execute test n times. */ -/* -I x : Execute test for x seconds. */ -/* -P x : Pause for x seconds between iterations. */ -/* -t : Turn on syscall timing. */ -/* */ -/* Total Tests: 1 */ -/* */ -/* Test Name: mq_timedsend01 */ -/* History: Porting from Crackerjack to LTP is done by */ -/* Manas Kumar Nayak maknayak@in.ibm.com> */ -/************************************************************************/ -#include <sys/syscall.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <getopt.h> -#include <stdlib.h> +/* + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> + * + * Author(s): + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <mqueue.h> -#include <time.h> -#include <signal.h> #include <limits.h> -#include "../utils/include_j_h.h" -#include "../utils/common_j_h.c" +#include "mq.h" -#include "test.h" -#include "linux_syscall_numbers.h" +static struct sigaction act; -char *TCID = "mq_timedsend01"; -int testno; -int TST_TOTAL = 1; -struct sigaction act; +struct test_case { + void (*setup)(void); + void (*cleanup)(void); + int fd; + unsigned int len; + unsigned int prio; + struct timespec *rq; + int send; + int ret; + int err; +}; -/* - * sighandler() - */ -void sighandler(int sig) -{ - if (sig == SIGINT) - return; - return; -} +static struct test_case tcase[] = { + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 0, + .ret = 0, + .err = 0, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 1, + .ret = 0, + .err = 0, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = MAX_MSGSIZE, + .ret = 0, + .err = 0, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 1, + .prio = MQ_PRIO_MAX - 1, + .ret = 0, + .err = 0, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = MAX_MSGSIZE + 1, + .ret = -1, + .err = EMSGSIZE, + }, + { + .len = 0, + .fd = -1, + .ret = -1, + .err = EBADF, + }, + { + .len = 0, + .fd = INT_MAX - 1, + .ret = -1, + .err = EBADF, + }, + { + .setup = open_fd, + .len = 0, + .ret = -1, + .err = EBADF, + }, + { + .setup = create_queue_nonblock, + .cleanup = unlink_queue, + .len = 16, + .send = 1, + .ret = -1, + .err = EAGAIN, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 1, + .prio = MQ_PRIO_MAX, + .ret = -1, + .err = EINVAL, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 16, + .rq = &(struct timespec) {.tv_sec = -1, .tv_nsec = 0}, + .send = 1, + .ret = -1, + .err = EINVAL, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 16, + .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = -1}, + .send = 1, + .ret = -1, + .err = EINVAL, + }, + { + .setup = create_queue, + .cleanup = unlink_queue, + .len = 16, + .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000}, + .send = 1, + .ret = -1, + .err = EINVAL, + }, + { + .setup = create_queue_timeout, + .cleanup = unlink_queue, + .len = 16, + .rq = &timeout_ts, + .send = 1, + .ret = -1, + .err = ETIMEDOUT, + }, + { + .setup = create_queue_sig, + .cleanup = unlink_queue_sig, + .len = 16, + .ret = -1, + .send = 1, + .rq = &eintr_ts, + .err = EINTR, + }, +}; -/* Extern Global Functions */ -/******************************************************************************/ -/* */ -/* Function: cleanup */ -/* */ -/* Description: Performs all one time clean up for this test on successful */ -/* completion, premature exit or failure. Closes all temporary */ -/* files, removes all temporary directories exits the test with */ -/* appropriate return code by calling tst_exit() function. */ -/* */ -/* Input: None. */ -/* */ -/* Output: None. */ -/* */ -/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ -/* On success - Exits calling tst_exit(). With '0' return code. */ -/* */ -/******************************************************************************/ -void cleanup(void) +static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) { - - tst_rmdir(); } -/* Local Functions */ -/******************************************************************************/ -/* */ -/* Function: setup */ -/* */ -/* Description: Performs all one time setup for this test. This function is */ -/* typically used to capture signals, create temporary dirs */ -/* and temporary files that may be used in the course of this */ -/* test. */ -/* */ -/* Input: None. */ -/* */ -/* Output: None. */ -/* */ -/* Return: On failure - Exits by calling cleanup(). */ -/* On success - returns 0. */ -/* */ -/******************************************************************************/ -void setup(void) +static void setup(void) { + int i; - /* Capture signals if any */ act.sa_handler = sighandler; - sigfillset(&act.sa_mask); - sigaction(SIGINT, &act, NULL); - /* Create temporary directories */ - TEST_PAUSE; - tst_tmpdir(); -} - -/* - * Macros - */ -#define SYSCALL_NAME "mq_timedsend" - -enum test_type { - NORMAL, - FD_NONE, - FD_NOT_EXIST, - FD_FILE, - FULL_QUEUE, - SEND_SIGINT, -}; - -/* - * Data Structure - */ -struct test_case { - int ttype; - int non_block; - int len; - unsigned prio; - time_t sec; - long nsec; - int ret; - int err; -}; -#define MAX_MSG 10 -#define MAX_MSGSIZE 8192 + fd_root = SAFE_OPEN("/", O_RDONLY); -/* Test cases -* -* test status of errors on man page -* -* EAGAIN v (would block) -* EBADF v (not a valid descriptor) -* EINTR v (interrupted by a signal) -* EINVAL v (1. invalid 'msg_prio' or -* 2. would block but timeout exists) -* EMSGSIZE v ('msg_len' exceeds the message size of the queue) -* ETIMEDOUT v (not block and timeout occured) -*/ + for (i = 0; i < MAX_MSGSIZE; i++) + smsg[i] = i; +} -static struct test_case tcase[] = { - { // case00 - .ttype = NORMAL, - .len = 0, // also success when size equals zero - .ret = 0, - .err = 0, - }, - { // case01 - .ttype = NORMAL, - .len = 1, - .ret = 0, - .err = 0, - }, - { // case02 - .ttype = NORMAL, - .len = MAX_MSGSIZE, - .ret = 0, - .err = 0, - }, - { // case03 - .ttype = NORMAL, - .len = 1, - .prio = 32767, // max priority - .ret = 0, - .err = 0, - }, - { // case04 - .ttype = NORMAL, - .len = MAX_MSGSIZE + 1, - .ret = -1, - .err = EMSGSIZE, - }, - { // case05 - .ttype = FD_NONE, - .len = 0, - .ret = -1, - .err = EBADF, - }, - { // case06 - .ttype = FD_NOT_EXIST, - .len = 0, - .ret = -1, - .err = EBADF, - }, - { // case07 - .ttype = FD_FILE, - .len = 0, - .ret = -1, - .err = EBADF, - }, - { // case08 - .ttype = FULL_QUEUE, - .non_block = 1, - .len = 16, - .ret = -1, - .err = EAGAIN, - }, - { // case09 - .ttype = NORMAL, - .len = 1, - .prio = 32768, // max priority + 1 - .ret = -1, - .err = EINVAL, - }, - { // case10 - .ttype = FULL_QUEUE, - .len = 16, - .sec = -1, - .nsec = 0, - .ret = -1, - .err = EINVAL, - }, - { // case11 - .ttype = FULL_QUEUE, - .len = 16, - .sec = 0, - .nsec = -1, - .ret = -1, - .err = EINVAL, - }, - { // case12 - .ttype = FULL_QUEUE, - .len = 16, - .sec = 0, - .nsec = 1000000000, - .ret = -1, - .err = EINVAL, - }, - { // case13 - .ttype = FULL_QUEUE, - .len = 16, - .sec = 0, - .nsec = 999999999, - .ret = -1, - .err = ETIMEDOUT, - }, - { // case14 - .ttype = SEND_SIGINT, - .len = 16, - .ret = -1, - .sec = 3, - .nsec = 0, - .err = EINTR, - }, -}; +static void cleanup(void) +{ + if (fd > 0) + close(fd); -/* - * do_test() - * - * Input : TestCase Data - * Return : RESULT_OK(0), RESULT_NG(1) - * - */ + if (fd_root > 0) + SAFE_CLOSE(fd_root); +} -static int do_test(struct test_case *tc) +static void do_test(unsigned int i) { - int sys_ret; - int sys_errno; - int result = RESULT_OK; - int oflag; - int i, rc, cmp_ok = 1, fd = -1; - char smsg[MAX_MSGSIZE], rmsg[MAX_MSGSIZE]; - struct timespec ts = { 0, 0 }; - pid_t pid = 0; - unsigned prio; + const struct test_case *tc = &tcase[i]; + unsigned int j; + unsigned int prio; + size_t len = MAX_MSGSIZE; + char rmsg[len]; /* * When test ended with SIGTERM etc, mq descriptor is left remains. * So we delete it first. */ - TEST(mq_unlink(QUEUE_NAME)); + mq_unlink(QUEUE_NAME); - switch (tc->ttype) { - case FD_NOT_EXIST: - fd = INT_MAX - 1; - /* fallthrough */ - case FD_NONE: - break; - case FD_FILE: - TEST(fd = open("/", O_RDONLY)); - if (fd < 0) { - tst_resm(TFAIL, "can't open \"/\".- errno = %d : %s\n", - TEST_ERRNO, strerror(TEST_ERRNO)); - result = 1; - goto EXIT; - } - break; - default: - /* - * Open message queue - */ - oflag = O_CREAT | O_EXCL | O_RDWR; - if (tc->non_block) - oflag |= O_NONBLOCK; + if (tc->fd) + fd = tc->fd; - TEST(fd = mq_open(QUEUE_NAME, oflag, S_IRWXU, NULL)); - if (TEST_RETURN < 0) { - tst_resm(TFAIL, "mq_open failed - errno = %d : %s\n", - TEST_ERRNO, strerror(TEST_ERRNO)); - result = 1; - goto EXIT; - } - if (tc->ttype == FULL_QUEUE || tc->ttype == SEND_SIGINT) { - for (i = 0; i < MAX_MSG; i++) { - TEST(rc = - mq_timedsend(fd, smsg, tc->len, 0, &ts)); - if (rc < 0) { - tst_resm(TFAIL, - "mq_timedsend failed - errno = %d : %s\n", - TEST_ERRNO, - strerror(TEST_ERRNO)); - result = 1; - goto EXIT; - } - } - if (tc->ttype == SEND_SIGINT) { - pid = create_sig_proc(200000, SIGINT, UINT_MAX); - if (pid < 0) { - result = 1; - goto EXIT; - } - } - } - break; - } + if (tc->setup) + tc->setup(); - /* - * Prepare send message - */ - for (i = 0; i < tc->len && i < sizeof(smsg); i++) - smsg[i] = i; + if (tc->send) { + for (j = 0; j < MSG_LENGTH; j++) + send_msg(fd, tc->len, tc->prio); + } - /* - * Set the timeout value - */ - ts.tv_sec = tc->sec; - ts.tv_nsec = tc->nsec; - if (tc->sec >= 0 || tc->nsec != 0) - ts.tv_sec += time(NULL); + TEST(mq_timedsend(fd, smsg, tc->len, tc->prio, tc->rq)); - /* - * Execut test system call - */ - errno = 0; - TEST(sys_ret = mq_timedsend(fd, smsg, tc->len, tc->prio, &ts)); - sys_errno = errno; - if (sys_ret < 0) - goto TEST_END; + if (TEST_RETURN < 0) { + if (tc->err != TEST_ERRNO) + tst_res(TFAIL | TTERRNO, + "mq_timedsend failed unexpectedly, expected %s", + tst_strerrno(tc->err)); + else + tst_res(TPASS | TTERRNO, "mq_timedreceive failed expectedly"); - /* - * Receive echoed message and compare - */ - ts.tv_sec = 0; - ts.tv_nsec = 0; - TEST(rc = mq_timedreceive(fd, rmsg, MAX_MSGSIZE, &prio, &ts)); - if (rc < 0) { - tst_resm(TFAIL, "mq_timedreceive failed - errno = %d : %s\n", - TEST_ERRNO, strerror(TEST_ERRNO)); - result = 1; - goto EXIT; - } - if (rc != tc->len || tc->prio != prio) - cmp_ok = 0; - else { - for (i = 0; i < tc->len; i++) - if (rmsg[i] != smsg[i]) { - cmp_ok = 0; - break; - } - } -TEST_END: - /* - * Check results - */ - result |= (sys_errno != tc->err) || !cmp_ok; - PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno, - cmp_ok); + if (tc->cleanup) + tc->cleanup(); -EXIT: - if (fd >= 0) { - TEST(close(fd)); - TEST(mq_unlink(QUEUE_NAME)); - } - if (pid > 0) { - int st; - kill(pid, SIGTERM); - wait(&st); + return; } - return result; -} -/* - * main() - */ - -int main(int ac, char **av) -{ - int result = RESULT_OK; - int i; - int lc; + TEST(mq_timedreceive(fd, rmsg, len, &prio, tc->rq)); - tst_parse_opts(ac, av, NULL, NULL); + if (tc->cleanup) + tc->cleanup(); - setup(); + if (TEST_RETURN < 0) { + if (tc->err != TEST_ERRNO) { + tst_res(TFAIL | TTERRNO, + "mq_timedreceive failed unexpectedly, expected %s", + tst_strerrno(tc->err)); + return; + } - for (lc = 0; TEST_LOOPING(lc); ++lc) { - tst_count = 0; - for (testno = 0; testno < TST_TOTAL; ++testno) { + if (tc->ret >= 0) { + tst_res(TFAIL | TTERRNO, "mq_timedreceive returned %ld, expected %d", + TEST_RETURN, tc->ret); + return; + } + } - /* - * Execute test - */ - for (i = 0; i < (int)ARRAY_SIZE(tcase); i++) { - int ret; - tst_resm(TINFO, "(case%02d) START", i); - ret = do_test(&tcase[i]); - tst_resm(TINFO, "(case%02d) END => %s", i, - (ret == 0) ? "OK" : "NG"); - result |= ret; - } - /* - * Check results - */ - switch (result) { - case RESULT_OK: - tst_resm(TPASS, "mq_timedsend call succeeded"); - break; + if (tc->len != TEST_RETURN) { + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong len returned %ld, expected %d", + TEST_RETURN, tc->len); + return; + } - default: - tst_brkm(TFAIL | TTERRNO, cleanup, - "mq_timedsend failed"); - } + if (tc->prio != prio) { + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong prio returned %d, expected %d", + prio, tc->prio); + return; + } + for (j = 0; j < tc->len; j++) { + if (rmsg[j] != smsg[j]) { + tst_res(TFAIL | TTERRNO, + "mq_timedreceive wrong data in loop %d returned %d, expected %d", + i, rmsg[j], smsg[j]); + return; } } - cleanup(); - tst_exit(); + + tst_res(TPASS, "mq_timedreceive returned %ld, priority %u, length: %lu", + TEST_RETURN, prio, len); } + +static struct tst_test test = { + .tcnt = ARRAY_SIZE(tcase), + .test = do_test, + .setup = setup, + .cleanup = cleanup, + .forks_child = 1, +}; diff --git a/testcases/kernel/syscalls/utils/mq.h b/testcases/kernel/syscalls/utils/mq.h new file mode 100644 index 000000000..ff6404fac --- /dev/null +++ b/testcases/kernel/syscalls/utils/mq.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> + * + * Author(s): + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __MQ_H__ +#define __MQ_H__ + +#include "tst_test.h" +#include "tst_sig_proc.h" +#include "tst_safe_posix_ipc.h" + +#define MAX_MSGSIZE 8192 +#define MSG_LENGTH 10 +#define QUEUE_NAME "/test_mqueue" + +static mqd_t fd, fd_root; +static pid_t pid; +static struct timespec timeout_ts; +static struct timespec eintr_ts; +char smsg[MAX_MSGSIZE]; + +static inline void create_queue(void) +{ + fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, 0700, NULL); +} + +static inline void create_queue_nonblock(void) +{ + fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR | O_NONBLOCK, + 0700, NULL); +} + +static inline void create_queue_sig(void) +{ + clock_gettime(CLOCK_REALTIME, &eintr_ts); + eintr_ts.tv_sec += 3; + + create_queue(); + pid = create_sig_proc(SIGINT, 40, 200000); +} + +static inline void create_queue_timeout(void) +{ + clock_gettime(CLOCK_REALTIME, &timeout_ts); + timeout_ts.tv_nsec += 50000000; + timeout_ts.tv_sec += timeout_ts.tv_nsec / 1000000000; + timeout_ts.tv_nsec %= 1000000000; + + create_queue(); +} + +static inline void open_fd(void) +{ + fd = fd_root; +} + +static inline void unlink_queue(void) +{ + if (fd > 0) + SAFE_CLOSE(fd); + + mq_unlink(QUEUE_NAME); +} + +static inline void unlink_queue_sig(void) +{ + SAFE_KILL(pid, SIGTERM); + SAFE_WAIT(NULL); + + unlink_queue(); +} + +static inline void send_msg(int fd, int len, int prio) +{ + if (mq_timedsend(fd, smsg, len, prio, + &((struct timespec){0})) < 0) + tst_brk(TBROK | TERRNO, "mq_timedsend failed"); +} + +#endif /* __MQ_H__ */ -- 2.12.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup 2017-06-05 20:05 ` [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup Petr Vorel @ 2017-06-06 14:26 ` Cyril Hrubis 0 siblings, 0 replies; 5+ messages in thread From: Cyril Hrubis @ 2017-06-06 14:26 UTC (permalink / raw) To: ltp Hi! > and other changes: > * Header mq.h to reuse common code. > + Cleanup syscalls/mq_timedreceive. > > Signed-off-by: Petr Vorel <pvorel@suse.cz> > --- > testcases/kernel/syscalls/mq_timedreceive/Makefile | 2 + > .../syscalls/mq_timedreceive/mq_timedreceive01.c | 158 ++--- > testcases/kernel/syscalls/mq_timedsend/Makefile | 2 + > .../kernel/syscalls/mq_timedsend/mq_timedsend01.c | 673 ++++++++------------- > testcases/kernel/syscalls/utils/mq.h | 100 +++ > 5 files changed, 381 insertions(+), 554 deletions(-) > create mode 100644 testcases/kernel/syscalls/utils/mq.h > > diff --git a/testcases/kernel/syscalls/mq_timedreceive/Makefile b/testcases/kernel/syscalls/mq_timedreceive/Makefile > index 2e1628e9f..0f2e05dfa 100644 > --- a/testcases/kernel/syscalls/mq_timedreceive/Makefile > +++ b/testcases/kernel/syscalls/mq_timedreceive/Makefile > @@ -21,6 +21,8 @@ top_srcdir ?= ../../../.. > include $(top_srcdir)/include/mk/testcases.mk > > CPPFLAGS ?= -D_POSIX_C_SOURCE=$(shell getconf _POSIX_MESSAGE_PASSING)L > +CPPFLAGS += -I$(abs_srcdir)/../utils > + > LDLIBS += -lpthread -lrt > > include $(top_srcdir)/include/mk/generic_leaf_target.mk > diff --git a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c > index 6ed670464..73b433da4 100644 > --- a/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c > +++ b/testcases/kernel/syscalls/mq_timedreceive/mq_timedreceive01.c > @@ -1,9 +1,11 @@ > /* > - * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd > - * Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, > - * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, > - * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> > - * Copyright (c) 2016-2017 Linux Test Project > + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd > + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> > + * > + * Author(s): > + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, > + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, > + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License as > @@ -16,49 +18,29 @@ > * GNU General Public License for more details. > * > * You should have received a copy of the GNU General Public License > - * along with this program; if not, write the Free Software Foundation, > - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > */ > > #include <errno.h> > #include <limits.h> > -#include <mqueue.h> > - > -#include "tst_test.h" > -#include "tst_sig_proc.h" > -#include "tst_safe_posix_ipc.h" > > -#define MAX_MSGSIZE 8192 > -#define QUEUE_NAME "/test_mqueue" > +#include "mq.h" > > -static char smsg[MAX_MSGSIZE]; > static struct sigaction act; > -static pid_t pid; > -static int fd, fd_root; > -static struct timespec timeout_ts; > -static struct timespec eintr_ts; > > struct test_case { > + void (*setup)(void); > + void (*cleanup)(void); > + int fd; > unsigned int len; > - unsigned prio; > + unsigned int prio; > struct timespec *rq; > - int fd; > int invalid_msg; > int send; > int ret; > int err; > - void (*setup)(void); > - void (*cleanup)(void); > }; > > -static void create_queue(void); > -static void create_queue_nonblock(void); > -static void create_queue_sig(void); > -static void create_queue_timeout(void); > -static void open_fd(void); > -static void unlink_queue(void); > -static void unlink_queue_sig(void); > - > static const struct test_case tcase[] = { > { > .setup = create_queue, > @@ -89,7 +71,7 @@ static const struct test_case tcase[] = { > .cleanup = unlink_queue, > .send = 1, > .len = 1, > - .prio = 32767, /* max priority */ > + .prio = MQ_PRIO_MAX - 1, > .ret = 0, > .err = 0, > }, > @@ -115,57 +97,57 @@ static const struct test_case tcase[] = { > .err = EBADF, > }, > { > + .setup = open_fd, > .len = 0, > .ret = -1, > .err = EBADF, > - .setup = open_fd, > }, > { > + .setup = create_queue_nonblock, > + .cleanup = unlink_queue, > .len = 16, > .ret = -1, > .err = EAGAIN, > - .setup = create_queue_nonblock, > - .cleanup = unlink_queue, > }, > { > + .setup = create_queue, > + .cleanup = unlink_queue, > .len = 16, > .rq = &(struct timespec) {.tv_sec = -1, .tv_nsec = 0}, > .ret = -1, > .err = EINVAL, > - .setup = create_queue, > - .cleanup = unlink_queue, > }, > { > + .setup = create_queue, > + .cleanup = unlink_queue, > .len = 16, > .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = -1}, > .ret = -1, > .err = EINVAL, > - .setup = create_queue, > - .cleanup = unlink_queue, > }, > { > + .setup = create_queue, > + .cleanup = unlink_queue, > .len = 16, > .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000}, > .ret = -1, > .err = EINVAL, > - .setup = create_queue, > - .cleanup = unlink_queue, > }, > { > + .setup = create_queue_timeout, > + .cleanup = unlink_queue, > .len = 16, > .ret = -1, > .rq = &timeout_ts, > .err = ETIMEDOUT, > - .setup = create_queue_timeout, > - .cleanup = unlink_queue, > }, > { > + .setup = create_queue_sig, > + .cleanup = unlink_queue_sig, > .len = 16, > .rq = &eintr_ts, > .ret = -1, > .err = EINTR, > - .setup = create_queue_sig, > - .cleanup = unlink_queue_sig, > }, > }; > > @@ -175,7 +157,7 @@ static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) > > static void setup(void) > { > - unsigned int i; > + int i; > > act.sa_handler = sighandler; > sigaction(SIGINT, &act, NULL); > @@ -195,71 +177,13 @@ static void cleanup(void) > SAFE_CLOSE(fd_root); > } > > -static void create_queue(void) > -{ > - fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL); > -} > - > -static void create_queue_nonblock(void) > -{ > - fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR | O_NONBLOCK, > - S_IRWXU, NULL); > -} > - > -static void create_queue_sig(void) > -{ > - clock_gettime(CLOCK_REALTIME, &eintr_ts); > - eintr_ts.tv_sec += 3; > - > - create_queue(); > - pid = create_sig_proc(SIGINT, 40, 200000); > -} > - > -static void create_queue_timeout(void) > -{ > - clock_gettime(CLOCK_REALTIME, &timeout_ts); > - timeout_ts.tv_nsec += 50000000; > - timeout_ts.tv_sec += timeout_ts.tv_nsec / 1000000000; > - timeout_ts.tv_nsec %= 1000000000; > - > - create_queue(); > -} > - > -static void open_fd(void) > -{ > - fd = fd_root; > -} > - > -static void send_msg(int fd, int len, int prio) > -{ > - if (mq_timedsend(fd, smsg, len, prio, > - &((struct timespec){0})) < 0) > - tst_brk(TBROK | TERRNO, "mq_timedsend failed"); > -} > - > -static void unlink_queue(void) > -{ > - if (fd > 0) > - SAFE_CLOSE(fd); > - > - mq_unlink(QUEUE_NAME); > -} > - > -static void unlink_queue_sig(void) > -{ > - SAFE_KILL(pid, SIGTERM); > - SAFE_WAIT(NULL); > - > - unlink_queue(); > -} > - > static void do_test(unsigned int i) > { > - unsigned int j; > const struct test_case *tc = &tcase[i]; > - char rmsg[MAX_MSGSIZE]; > + unsigned int j; > unsigned int prio; > - size_t msg_len = MAX_MSGSIZE; > + size_t len = MAX_MSGSIZE; > + char rmsg[len]; > > /* > * When test ended with SIGTERM etc, mq descriptor is left remains. > @@ -277,27 +201,25 @@ static void do_test(unsigned int i) > send_msg(fd, tc->len, tc->prio); > > if (tc->invalid_msg) > - msg_len -= 1; > + len -= 1; > > - TEST(mq_timedreceive(fd, rmsg, msg_len, &prio, tc->rq)); > + TEST(mq_timedreceive(fd, rmsg, len, &prio, tc->rq)); > > if (tc->cleanup) > tc->cleanup(); > > if (TEST_RETURN < 0) { > - if (TEST_ERRNO != tc->err) { > + if (tc->err != TEST_ERRNO) > tst_res(TFAIL | TTERRNO, > "mq_timedreceive failed unexpectedly, expected %s", > tst_strerrno(tc->err)); > - } else { > + else > tst_res(TPASS | TTERRNO, "mq_timedreceive failed expectedly"); > - } > return; > } > > - > - if (TEST_RETURN != tc->len) { > - tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong msg_len returned %ld, expected %d", > + if (tc->len != TEST_RETURN) { > + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong len returned %ld, expected %d", > TEST_RETURN, tc->len); > return; > } > @@ -310,13 +232,15 @@ static void do_test(unsigned int i) > > for (j = 0; j < tc->len; j++) { > if (rmsg[j] != smsg[j]) { > - tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong data in loop %d returned %d, expected %d", > + tst_res(TFAIL | TTERRNO, > + "mq_timedreceive wrong data in loop %d returned %d, expected %d", > i, rmsg[j], smsg[j]); > return; > } > } > > - tst_res(TPASS, "mq_timedreceive returned %ld prio %u", TEST_RETURN, prio); > + tst_res(TPASS, "mq_timedreceive returned %ld, priority %u, length: %lu", > + TEST_RETURN, prio, len); > } > > static struct tst_test test = { > diff --git a/testcases/kernel/syscalls/mq_timedsend/Makefile b/testcases/kernel/syscalls/mq_timedsend/Makefile > index 71ebae98b..4e1b61282 100644 > --- a/testcases/kernel/syscalls/mq_timedsend/Makefile > +++ b/testcases/kernel/syscalls/mq_timedsend/Makefile > @@ -20,6 +20,8 @@ top_srcdir ?= ../../../.. > > include $(top_srcdir)/include/mk/testcases.mk > > +CPPFLAGS += -I$(abs_srcdir)/../utils > + > LDLIBS += -lpthread -lrt > > include $(top_srcdir)/include/mk/generic_leaf_target.mk > diff --git a/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c b/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c > index 77198cea8..745008097 100644 > --- a/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c > +++ b/testcases/kernel/syscalls/mq_timedsend/mq_timedsend01.c > @@ -1,480 +1,279 @@ > -/********************************************************************************/ > -/* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */ > -/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */ > -/* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */ > -/* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */ > -/* */ > -/* This program is free software; you can redistribute it and/or modify */ > -/* it under the terms of the GNU General Public License as published by */ > -/* the Free Software Foundation; either version 2 of the License, or */ > -/* (at your option) any later version. */ > -/* */ > -/* This program is distributed in the hope that it will be useful, */ > -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ > -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ > -/* the GNU General Public License for more details. */ > -/* */ > -/* You should have received a copy of the GNU General Public License */ > -/* along with this program; if not, write to the Free Software */ > -/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ > -/* USA */ > -/********************************************************************************/ > -/************************************************************************/ > -/* */ > -/* File: mq_timedsend01.c */ > -/* */ > -/* Description: This tests the mq_timedsend() syscall */ > -/* */ > -/* */ > -/* */ > -/* */ > -/* */ > -/* */ > -/* Usage: <for command-line> */ > -/* mq_timedsend01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */ > -/* where, -c n : Run n copies concurrently. */ > -/* -e : Turn on errno logging. */ > -/* -i n : Execute test n times. */ > -/* -I x : Execute test for x seconds. */ > -/* -P x : Pause for x seconds between iterations. */ > -/* -t : Turn on syscall timing. */ > -/* */ > -/* Total Tests: 1 */ > -/* */ > -/* Test Name: mq_timedsend01 */ > -/* History: Porting from Crackerjack to LTP is done by */ > -/* Manas Kumar Nayak maknayak@in.ibm.com> */ > -/************************************************************************/ > -#include <sys/syscall.h> > -#include <sys/types.h> > -#include <sys/stat.h> > -#include <sys/wait.h> > -#include <getopt.h> > -#include <stdlib.h> > +/* > + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd > + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> > + * > + * Author(s): > + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, > + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, > + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it would be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > #include <errno.h> > -#include <stdio.h> > -#include <unistd.h> > -#include <string.h> > -#include <mqueue.h> > -#include <time.h> > -#include <signal.h> > #include <limits.h> > > -#include "../utils/include_j_h.h" > -#include "../utils/common_j_h.c" > +#include "mq.h" > > -#include "test.h" > -#include "linux_syscall_numbers.h" > +static struct sigaction act; > > -char *TCID = "mq_timedsend01"; > -int testno; > -int TST_TOTAL = 1; > -struct sigaction act; > +struct test_case { > + void (*setup)(void); > + void (*cleanup)(void); > + int fd; > + unsigned int len; > + unsigned int prio; > + struct timespec *rq; > + int send; > + int ret; > + int err; > +}; > > -/* > - * sighandler() > - */ > -void sighandler(int sig) > -{ > - if (sig == SIGINT) > - return; > - return; > -} > +static struct test_case tcase[] = { > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 0, > + .ret = 0, > + .err = 0, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 1, > + .ret = 0, > + .err = 0, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = MAX_MSGSIZE, > + .ret = 0, > + .err = 0, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 1, > + .prio = MQ_PRIO_MAX - 1, > + .ret = 0, > + .err = 0, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = MAX_MSGSIZE + 1, > + .ret = -1, > + .err = EMSGSIZE, > + }, > + { > + .len = 0, > + .fd = -1, > + .ret = -1, > + .err = EBADF, > + }, > + { > + .len = 0, > + .fd = INT_MAX - 1, > + .ret = -1, > + .err = EBADF, > + }, > + { > + .setup = open_fd, > + .len = 0, > + .ret = -1, > + .err = EBADF, > + }, > + { > + .setup = create_queue_nonblock, > + .cleanup = unlink_queue, > + .len = 16, > + .send = 1, > + .ret = -1, > + .err = EAGAIN, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 1, > + .prio = MQ_PRIO_MAX, > + .ret = -1, > + .err = EINVAL, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 16, > + .rq = &(struct timespec) {.tv_sec = -1, .tv_nsec = 0}, > + .send = 1, > + .ret = -1, > + .err = EINVAL, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 16, > + .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = -1}, > + .send = 1, > + .ret = -1, > + .err = EINVAL, > + }, > + { > + .setup = create_queue, > + .cleanup = unlink_queue, > + .len = 16, > + .rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000}, > + .send = 1, > + .ret = -1, > + .err = EINVAL, > + }, > + { > + .setup = create_queue_timeout, > + .cleanup = unlink_queue, > + .len = 16, > + .rq = &timeout_ts, > + .send = 1, > + .ret = -1, > + .err = ETIMEDOUT, > + }, > + { > + .setup = create_queue_sig, > + .cleanup = unlink_queue_sig, > + .len = 16, > + .ret = -1, > + .send = 1, > + .rq = &eintr_ts, > + .err = EINTR, > + }, > +}; > > -/* Extern Global Functions */ > -/******************************************************************************/ > -/* */ > -/* Function: cleanup */ > -/* */ > -/* Description: Performs all one time clean up for this test on successful */ > -/* completion, premature exit or failure. Closes all temporary */ > -/* files, removes all temporary directories exits the test with */ > -/* appropriate return code by calling tst_exit() function. */ > -/* */ > -/* Input: None. */ > -/* */ > -/* Output: None. */ > -/* */ > -/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ > -/* On success - Exits calling tst_exit(). With '0' return code. */ > -/* */ > -/******************************************************************************/ > -void cleanup(void) > +static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) > { > - > - tst_rmdir(); > } > > -/* Local Functions */ > -/******************************************************************************/ > -/* */ > -/* Function: setup */ > -/* */ > -/* Description: Performs all one time setup for this test. This function is */ > -/* typically used to capture signals, create temporary dirs */ > -/* and temporary files that may be used in the course of this */ > -/* test. */ > -/* */ > -/* Input: None. */ > -/* */ > -/* Output: None. */ > -/* */ > -/* Return: On failure - Exits by calling cleanup(). */ > -/* On success - returns 0. */ > -/* */ > -/******************************************************************************/ > -void setup(void) > +static void setup(void) > { > + int i; > > - /* Capture signals if any */ > act.sa_handler = sighandler; > - sigfillset(&act.sa_mask); > - > sigaction(SIGINT, &act, NULL); > - /* Create temporary directories */ > - TEST_PAUSE; > - tst_tmpdir(); > -} > - > -/* > - * Macros > - */ > -#define SYSCALL_NAME "mq_timedsend" > - > -enum test_type { > - NORMAL, > - FD_NONE, > - FD_NOT_EXIST, > - FD_FILE, > - FULL_QUEUE, > - SEND_SIGINT, > -}; > - > -/* > - * Data Structure > - */ > -struct test_case { > - int ttype; > - int non_block; > - int len; > - unsigned prio; > - time_t sec; > - long nsec; > - int ret; > - int err; > -}; > > -#define MAX_MSG 10 > -#define MAX_MSGSIZE 8192 > + fd_root = SAFE_OPEN("/", O_RDONLY); > > -/* Test cases > -* > -* test status of errors on man page > -* > -* EAGAIN v (would block) > -* EBADF v (not a valid descriptor) > -* EINTR v (interrupted by a signal) > -* EINVAL v (1. invalid 'msg_prio' or > -* 2. would block but timeout exists) > -* EMSGSIZE v ('msg_len' exceeds the message size of the queue) > -* ETIMEDOUT v (not block and timeout occured) > -*/ > + for (i = 0; i < MAX_MSGSIZE; i++) > + smsg[i] = i; > +} > > -static struct test_case tcase[] = { > - { // case00 > - .ttype = NORMAL, > - .len = 0, // also success when size equals zero > - .ret = 0, > - .err = 0, > - }, > - { // case01 > - .ttype = NORMAL, > - .len = 1, > - .ret = 0, > - .err = 0, > - }, > - { // case02 > - .ttype = NORMAL, > - .len = MAX_MSGSIZE, > - .ret = 0, > - .err = 0, > - }, > - { // case03 > - .ttype = NORMAL, > - .len = 1, > - .prio = 32767, // max priority > - .ret = 0, > - .err = 0, > - }, > - { // case04 > - .ttype = NORMAL, > - .len = MAX_MSGSIZE + 1, > - .ret = -1, > - .err = EMSGSIZE, > - }, > - { // case05 > - .ttype = FD_NONE, > - .len = 0, > - .ret = -1, > - .err = EBADF, > - }, > - { // case06 > - .ttype = FD_NOT_EXIST, > - .len = 0, > - .ret = -1, > - .err = EBADF, > - }, > - { // case07 > - .ttype = FD_FILE, > - .len = 0, > - .ret = -1, > - .err = EBADF, > - }, > - { // case08 > - .ttype = FULL_QUEUE, > - .non_block = 1, > - .len = 16, > - .ret = -1, > - .err = EAGAIN, > - }, > - { // case09 > - .ttype = NORMAL, > - .len = 1, > - .prio = 32768, // max priority + 1 > - .ret = -1, > - .err = EINVAL, > - }, > - { // case10 > - .ttype = FULL_QUEUE, > - .len = 16, > - .sec = -1, > - .nsec = 0, > - .ret = -1, > - .err = EINVAL, > - }, > - { // case11 > - .ttype = FULL_QUEUE, > - .len = 16, > - .sec = 0, > - .nsec = -1, > - .ret = -1, > - .err = EINVAL, > - }, > - { // case12 > - .ttype = FULL_QUEUE, > - .len = 16, > - .sec = 0, > - .nsec = 1000000000, > - .ret = -1, > - .err = EINVAL, > - }, > - { // case13 > - .ttype = FULL_QUEUE, > - .len = 16, > - .sec = 0, > - .nsec = 999999999, > - .ret = -1, > - .err = ETIMEDOUT, > - }, > - { // case14 > - .ttype = SEND_SIGINT, > - .len = 16, > - .ret = -1, > - .sec = 3, > - .nsec = 0, > - .err = EINTR, > - }, > -}; > +static void cleanup(void) > +{ > + if (fd > 0) > + close(fd); > > -/* > - * do_test() > - * > - * Input : TestCase Data > - * Return : RESULT_OK(0), RESULT_NG(1) > - * > - */ > + if (fd_root > 0) > + SAFE_CLOSE(fd_root); > +} > > -static int do_test(struct test_case *tc) > +static void do_test(unsigned int i) > { > - int sys_ret; > - int sys_errno; > - int result = RESULT_OK; > - int oflag; > - int i, rc, cmp_ok = 1, fd = -1; > - char smsg[MAX_MSGSIZE], rmsg[MAX_MSGSIZE]; > - struct timespec ts = { 0, 0 }; > - pid_t pid = 0; > - unsigned prio; > + const struct test_case *tc = &tcase[i]; > + unsigned int j; > + unsigned int prio; > + size_t len = MAX_MSGSIZE; > + char rmsg[len]; > > /* > * When test ended with SIGTERM etc, mq descriptor is left remains. > * So we delete it first. > */ > - TEST(mq_unlink(QUEUE_NAME)); > + mq_unlink(QUEUE_NAME); > > - switch (tc->ttype) { > - case FD_NOT_EXIST: > - fd = INT_MAX - 1; > - /* fallthrough */ > - case FD_NONE: > - break; > - case FD_FILE: > - TEST(fd = open("/", O_RDONLY)); > - if (fd < 0) { > - tst_resm(TFAIL, "can't open \"/\".- errno = %d : %s\n", > - TEST_ERRNO, strerror(TEST_ERRNO)); > - result = 1; > - goto EXIT; > - } > - break; > - default: > - /* > - * Open message queue > - */ > - oflag = O_CREAT | O_EXCL | O_RDWR; > - if (tc->non_block) > - oflag |= O_NONBLOCK; > + if (tc->fd) > + fd = tc->fd; > > - TEST(fd = mq_open(QUEUE_NAME, oflag, S_IRWXU, NULL)); > - if (TEST_RETURN < 0) { > - tst_resm(TFAIL, "mq_open failed - errno = %d : %s\n", > - TEST_ERRNO, strerror(TEST_ERRNO)); > - result = 1; > - goto EXIT; > - } > - if (tc->ttype == FULL_QUEUE || tc->ttype == SEND_SIGINT) { > - for (i = 0; i < MAX_MSG; i++) { > - TEST(rc = > - mq_timedsend(fd, smsg, tc->len, 0, &ts)); > - if (rc < 0) { > - tst_resm(TFAIL, > - "mq_timedsend failed - errno = %d : %s\n", > - TEST_ERRNO, > - strerror(TEST_ERRNO)); > - result = 1; > - goto EXIT; > - } > - } > - if (tc->ttype == SEND_SIGINT) { > - pid = create_sig_proc(200000, SIGINT, UINT_MAX); > - if (pid < 0) { > - result = 1; > - goto EXIT; > - } > - } > - } > - break; > - } > + if (tc->setup) > + tc->setup(); > > - /* > - * Prepare send message > - */ > - for (i = 0; i < tc->len && i < sizeof(smsg); i++) > - smsg[i] = i; > + if (tc->send) { > + for (j = 0; j < MSG_LENGTH; j++) > + send_msg(fd, tc->len, tc->prio); > + } > > - /* > - * Set the timeout value > - */ > - ts.tv_sec = tc->sec; > - ts.tv_nsec = tc->nsec; > - if (tc->sec >= 0 || tc->nsec != 0) > - ts.tv_sec += time(NULL); > + TEST(mq_timedsend(fd, smsg, tc->len, tc->prio, tc->rq)); > > - /* > - * Execut test system call > - */ > - errno = 0; > - TEST(sys_ret = mq_timedsend(fd, smsg, tc->len, tc->prio, &ts)); > - sys_errno = errno; > - if (sys_ret < 0) > - goto TEST_END; > + if (TEST_RETURN < 0) { > + if (tc->err != TEST_ERRNO) > + tst_res(TFAIL | TTERRNO, > + "mq_timedsend failed unexpectedly, expected %s", > + tst_strerrno(tc->err)); > + else > + tst_res(TPASS | TTERRNO, "mq_timedreceive failed expectedly"); > > - /* > - * Receive echoed message and compare > - */ > - ts.tv_sec = 0; > - ts.tv_nsec = 0; > - TEST(rc = mq_timedreceive(fd, rmsg, MAX_MSGSIZE, &prio, &ts)); > - if (rc < 0) { > - tst_resm(TFAIL, "mq_timedreceive failed - errno = %d : %s\n", > - TEST_ERRNO, strerror(TEST_ERRNO)); > - result = 1; > - goto EXIT; > - } > - if (rc != tc->len || tc->prio != prio) > - cmp_ok = 0; > - else { > - for (i = 0; i < tc->len; i++) > - if (rmsg[i] != smsg[i]) { > - cmp_ok = 0; > - break; > - } > - } > -TEST_END: > - /* > - * Check results > - */ > - result |= (sys_errno != tc->err) || !cmp_ok; > - PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno, > - cmp_ok); > + if (tc->cleanup) > + tc->cleanup(); > > -EXIT: > - if (fd >= 0) { > - TEST(close(fd)); > - TEST(mq_unlink(QUEUE_NAME)); > - } > - if (pid > 0) { > - int st; > - kill(pid, SIGTERM); > - wait(&st); > + return; > } > - return result; > -} > > -/* > - * main() > - */ > - > -int main(int ac, char **av) > -{ > - int result = RESULT_OK; > - int i; > - int lc; > + TEST(mq_timedreceive(fd, rmsg, len, &prio, tc->rq)); > > - tst_parse_opts(ac, av, NULL, NULL); > + if (tc->cleanup) > + tc->cleanup(); > > - setup(); > + if (TEST_RETURN < 0) { > + if (tc->err != TEST_ERRNO) { > + tst_res(TFAIL | TTERRNO, > + "mq_timedreceive failed unexpectedly, expected %s", > + tst_strerrno(tc->err)); > + return; > + } > > - for (lc = 0; TEST_LOOPING(lc); ++lc) { > - tst_count = 0; > - for (testno = 0; testno < TST_TOTAL; ++testno) { > + if (tc->ret >= 0) { > + tst_res(TFAIL | TTERRNO, "mq_timedreceive returned %ld, expected %d", > + TEST_RETURN, tc->ret); > + return; > + } > + } > > - /* > - * Execute test > - */ > - for (i = 0; i < (int)ARRAY_SIZE(tcase); i++) { > - int ret; > - tst_resm(TINFO, "(case%02d) START", i); > - ret = do_test(&tcase[i]); > - tst_resm(TINFO, "(case%02d) END => %s", i, > - (ret == 0) ? "OK" : "NG"); > - result |= ret; > - } > - /* > - * Check results > - */ > - switch (result) { > - case RESULT_OK: > - tst_resm(TPASS, "mq_timedsend call succeeded"); > - break; > + if (tc->len != TEST_RETURN) { > + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong len returned %ld, expected %d", > + TEST_RETURN, tc->len); > + return; > + } > > - default: > - tst_brkm(TFAIL | TTERRNO, cleanup, > - "mq_timedsend failed"); > - } > + if (tc->prio != prio) { > + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong prio returned %d, expected %d", > + prio, tc->prio); > + return; > + } > > + for (j = 0; j < tc->len; j++) { > + if (rmsg[j] != smsg[j]) { > + tst_res(TFAIL | TTERRNO, > + "mq_timedreceive wrong data in loop %d returned %d, expected %d", > + i, rmsg[j], smsg[j]); > + return; > } > } > - cleanup(); > - tst_exit(); > + > + tst_res(TPASS, "mq_timedreceive returned %ld, priority %u, length: %lu", > + TEST_RETURN, prio, len); > } > + > +static struct tst_test test = { > + .tcnt = ARRAY_SIZE(tcase), > + .test = do_test, > + .setup = setup, > + .cleanup = cleanup, > + .forks_child = 1, > +}; > diff --git a/testcases/kernel/syscalls/utils/mq.h b/testcases/kernel/syscalls/utils/mq.h > new file mode 100644 > index 000000000..ff6404fac > --- /dev/null > +++ b/testcases/kernel/syscalls/utils/mq.h > @@ -0,0 +1,100 @@ > +/* > + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd > + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> > + * > + * Author(s): > + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, > + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, > + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> > + * > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it would be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef __MQ_H__ > +#define __MQ_H__ Can you drop the double underscore at the beginning here? Identifiers that start with underscores are reserved for system libraries such as libc. > +#include "tst_test.h" > +#include "tst_sig_proc.h" > +#include "tst_safe_posix_ipc.h" > + > +#define MAX_MSGSIZE 8192 > +#define MSG_LENGTH 10 > +#define QUEUE_NAME "/test_mqueue" > + > +static mqd_t fd, fd_root; > +static pid_t pid; > +static struct timespec timeout_ts; > +static struct timespec eintr_ts; > +char smsg[MAX_MSGSIZE]; > + > +static inline void create_queue(void) > +{ > + fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, 0700, NULL); > +} > + > +static inline void create_queue_nonblock(void) > +{ > + fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR | O_NONBLOCK, > + 0700, NULL); > +} > + > +static inline void create_queue_sig(void) > +{ > + clock_gettime(CLOCK_REALTIME, &eintr_ts); > + eintr_ts.tv_sec += 3; > + > + create_queue(); > + pid = create_sig_proc(SIGINT, 40, 200000); > +} > + > +static inline void create_queue_timeout(void) > +{ > + clock_gettime(CLOCK_REALTIME, &timeout_ts); > + timeout_ts.tv_nsec += 50000000; > + timeout_ts.tv_sec += timeout_ts.tv_nsec / 1000000000; > + timeout_ts.tv_nsec %= 1000000000; > + > + create_queue(); > +} > + > +static inline void open_fd(void) > +{ > + fd = fd_root; > +} This is utterly confusing once it gets extracted to the header. What we usually do in this situation is that the fd in the testcase structure is a pointer to an integer that gets initialized by a pointer to a variable that is intialized in the test setup. See for example fchown02.c testcase. > +static inline void unlink_queue(void) > +{ > + if (fd > 0) > + SAFE_CLOSE(fd); > + > + mq_unlink(QUEUE_NAME); > +} > + > +static inline void unlink_queue_sig(void) > +{ > + SAFE_KILL(pid, SIGTERM); > + SAFE_WAIT(NULL); > + > + unlink_queue(); > +} > + > +static inline void send_msg(int fd, int len, int prio) > +{ > + if (mq_timedsend(fd, smsg, len, prio, > + &((struct timespec){0})) < 0) > + tst_brk(TBROK | TERRNO, "mq_timedsend failed"); > +} Hmm, I find it mildly confusing that header defines global variables and functions that work with these, but I cannot think of a clearer way of doing this... I do wonder how much of this could be done once in the test setup, do we really have to create and destroy the queue and the non-blocking queue each time? Can't we open these once, at lest for a subset of the tests, in the test setup? > +#endif /* __MQ_H__ */ > -- > 2.12.2 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 5+ messages in thread
* [LTP] [PATCH 3/3] syscalls/mq_notify: Cleanup + use mq.h 2017-06-05 20:05 [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Petr Vorel 2017-06-05 20:05 ` [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup Petr Vorel @ 2017-06-05 20:05 ` Petr Vorel 2017-06-06 13:58 ` [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Cyril Hrubis 2 siblings, 0 replies; 5+ messages in thread From: Petr Vorel @ 2017-06-05 20:05 UTC (permalink / raw) To: ltp Signed-off-by: Petr Vorel <pvorel@suse.cz> --- testcases/kernel/syscalls/mq_notify/Makefile | 2 +- testcases/kernel/syscalls/mq_notify/mq_notify01.c | 204 +++++++++++----------- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/testcases/kernel/syscalls/mq_notify/Makefile b/testcases/kernel/syscalls/mq_notify/Makefile index 2e1628e9f..7b9304212 100644 --- a/testcases/kernel/syscalls/mq_notify/Makefile +++ b/testcases/kernel/syscalls/mq_notify/Makefile @@ -20,7 +20,7 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk -CPPFLAGS ?= -D_POSIX_C_SOURCE=$(shell getconf _POSIX_MESSAGE_PASSING)L +CPPFLAGS += -I$(abs_srcdir)/../utils LDLIBS += -lpthread -lrt include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/mq_notify/mq_notify01.c b/testcases/kernel/syscalls/mq_notify/mq_notify01.c index 2406dee85..29a2ba92a 100644 --- a/testcases/kernel/syscalls/mq_notify/mq_notify01.c +++ b/testcases/kernel/syscalls/mq_notify/mq_notify01.c @@ -1,102 +1,102 @@ /* - * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd - * Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, - * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, - * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> - * Copyright (c) 2016 Linux Test Project + * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd + * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Author(s): + * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, + * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, + * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _XOPEN_SOURCE 600 -#include <sys/types.h> -#include <sys/stat.h> + #include <limits.h> #include <errno.h> -#include <unistd.h> #include <string.h> -#include <mqueue.h> -#include <signal.h> -#include <stdlib.h> -#include <fcntl.h> +#include "mq.h" #include "tst_test.h" #include "tst_safe_posix_ipc.h" -#define MAX_MSGSIZE 8192 -#define MSG_SIZE 16 #define USER_DATA 0x12345678 -#define QUEUE_NAME "/test_mqueue" static char *str_debug; -static char smsg[MAX_MSGSIZE]; +static struct sigevent ev; static volatile sig_atomic_t notified, cmp_ok; static siginfo_t info; -enum test_type { - NORMAL, - FD_NONE, - FD_NOT_EXIST, - FD_FILE, - ALREADY_REGISTERED, -}; - struct test_case { + void (*setup)(void); + void (*cleanup)(void); + int fd; int notify; int ttype; - const char *desc; int ret; int err; }; -#define TYPE_NAME(x) .ttype = x, .desc = #x +static void create_queue_notify_queue(void) +{ + create_queue(); + if (mq_notify(fd, &ev) == -1) + tst_brk(TBROK | TERRNO, "mq_notify(%d, %p) failed", fd, &ev); +} + static struct test_case tcase[] = { { - TYPE_NAME(NORMAL), + .setup = create_queue, + .cleanup = unlink_queue, .notify = SIGEV_NONE, .ret = 0, .err = 0, }, { - TYPE_NAME(NORMAL), + .setup = create_queue, + .cleanup = unlink_queue, .notify = SIGEV_SIGNAL, .ret = 0, .err = 0, }, { - TYPE_NAME(NORMAL), + .setup = create_queue, + .cleanup = unlink_queue, .notify = SIGEV_THREAD, .ret = 0, .err = 0, }, { - TYPE_NAME(FD_NONE), + .fd = -1, .notify = SIGEV_NONE, .ret = -1, .err = EBADF, }, { - TYPE_NAME(FD_NOT_EXIST), + .fd = INT_MAX - 1, .notify = SIGEV_NONE, .ret = -1, .err = EBADF, }, { - TYPE_NAME(FD_FILE), + .setup = open_fd, .notify = SIGEV_NONE, .ret = -1, .err = EBADF, }, { - TYPE_NAME(ALREADY_REGISTERED), + .setup = create_queue_notify_queue, + .cleanup = unlink_queue, .notify = SIGEV_NONE, .ret = -1, .err = EBUSY, @@ -107,7 +107,7 @@ static void setup(void) { int i; - for (i = 0; i < MSG_SIZE; i++) + for (i = 0; i < MSG_LENGTH; i++) smsg[i] = i; } static void sigfunc(int signo LTP_ATTRIBUTE_UNUSED, siginfo_t *si, @@ -131,8 +131,6 @@ static void tfunc(union sigval sv) static void do_test(unsigned int i) { - int rc, fd = -1; - struct sigevent ev; struct sigaction sigact; struct timespec abs_timeout; struct test_case *tc = &tcase[i]; @@ -149,22 +147,11 @@ static void do_test(unsigned int i) */ mq_unlink(QUEUE_NAME); - switch (tc->ttype) { - case FD_NONE: - break; - case FD_NOT_EXIST: - fd = INT_MAX - 1; - break; - case FD_FILE: - fd = open("/", O_RDONLY); - if (fd < 0) { - tst_res(TBROK | TERRNO, "can't open \"/\"."); - goto CLEANUP; - } - break; - default: - fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL); - } + if (tc->fd) + fd = tc->fd; + + if (tc->setup) + tc->setup(); ev.sigev_notify = tc->notify; @@ -177,7 +164,10 @@ static void do_test(unsigned int i) memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = sigfunc; sigact.sa_flags = SA_SIGINFO; - rc = sigaction(SIGUSR1, &sigact, NULL); + if (sigaction(SIGUSR1, &sigact, NULL) == -1) { + tst_res(TFAIL | TTERRNO, "sigaction failed"); + return; + } break; case SIGEV_THREAD: notified = cmp_ok = 0; @@ -187,54 +177,64 @@ static void do_test(unsigned int i) break; } - if (tc->ttype == ALREADY_REGISTERED) { - rc = mq_notify(fd, &ev); - if (rc < 0) { - tst_res(TBROK | TERRNO, "mq_notify failed"); - goto CLEANUP; - } + TEST(mq_notify(fd, &ev)); + + if (TEST_RETURN < 0) { + if (tc->err != TEST_ERRNO) { + tst_res(TFAIL | TTERRNO, + "mq_notify failed unexpectedly, expected %s", + tst_strerrno(tc->err)); + } else + tst_res(TPASS | TTERRNO, "mq_notify failed expectedly"); + + if (tc->cleanup) + tc->cleanup(); + return; } - /* test */ - TEST(mq_notify(fd, &ev)); - if (TEST_RETURN >= 0) { - rc = mq_timedsend(fd, smsg, MSG_SIZE, 0, &abs_timeout); - if (rc < 0) { - tst_res(TFAIL | TTERRNO, "mq_timedsend failed"); - goto CLEANUP; - } + TEST(mq_timedsend(fd, smsg, MSG_LENGTH, 0, &abs_timeout)); - while (!notified) - usleep(10000); - - if (str_debug && tc->notify == SIGEV_SIGNAL) { - tst_res(TINFO, "si_code E:%d,\tR:%d", - info.si_code, SI_MESGQ); - tst_res(TINFO, "si_signo E:%d,\tR:%d", - info.si_signo, SIGUSR1); - tst_res(TINFO, "si_value E:0x%x,\tR:0x%x", - info.si_value.sival_int, USER_DATA); - tst_res(TINFO, "si_pid E:%d,\tR:%d", - info.si_pid, getpid()); - tst_res(TINFO, "si_uid E:%d,\tR:%d", - info.si_uid, getuid()); - } + if (tc->cleanup) + tc->cleanup(); + + if (TEST_RETURN < 0) { + tst_res(TFAIL | TTERRNO, "mq_timedsend failed"); + return; } - if ((TEST_RETURN != 0 && TEST_ERRNO != tc->err) || !cmp_ok) { - tst_res(TFAIL | TTERRNO, "%s r/w check returned: %ld, " - "expected: %d, expected errno: %s (%d)", tc->desc, - TEST_RETURN, tc->ret, tst_strerrno(tc->err), tc->err); - } else { - tst_res(TPASS | TTERRNO, "%s returned: %ld", - tc->desc, TEST_RETURN); + while (!notified) + usleep(10000); + + if (str_debug && tc->notify == SIGEV_SIGNAL) { + tst_res(TINFO, "si_code E:%d,\tR:%d", + info.si_code, SI_MESGQ); + tst_res(TINFO, "si_signo E:%d,\tR:%d", + info.si_signo, SIGUSR1); + tst_res(TINFO, "si_value E:0x%x,\tR:0x%x", + info.si_value.sival_int, USER_DATA); + tst_res(TINFO, "si_pid E:%d,\tR:%d", + info.si_pid, getpid()); + tst_res(TINFO, "si_uid E:%d,\tR:%d", + info.si_uid, getuid()); } -CLEANUP: - if (fd >= 0) { - close(fd); - mq_unlink(QUEUE_NAME); + if (TEST_RETURN < 0) { + if (tc->err != TEST_ERRNO) + tst_res(TFAIL | TTERRNO, + "mq_timedsend failed unexpectedly, expected %s", + tst_strerrno(tc->err)); + else + tst_res(TPASS | TTERRNO, "mq_timedsend failed expectedly"); + return; } + + if (tc->ret != TEST_RETURN) { + tst_res(TFAIL | TTERRNO, "mq_timedreceive returned %ld, expected %d", + TEST_RETURN, tc->ret); + return; + } + + tst_res(TPASS, "mq_notify and mq_timedsend exited expectedly"); } static struct tst_option options[] = { -- 2.12.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive 2017-06-05 20:05 [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Petr Vorel 2017-06-05 20:05 ` [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup Petr Vorel 2017-06-05 20:05 ` [LTP] [PATCH 3/3] syscalls/mq_notify: Cleanup + use mq.h Petr Vorel @ 2017-06-06 13:58 ` Cyril Hrubis 2 siblings, 0 replies; 5+ messages in thread From: Cyril Hrubis @ 2017-06-06 13:58 UTC (permalink / raw) To: ltp Hi! > + for (j = 0; j < tc->len; j++) { > + if (rmsg[j] != smsg[j]) { > + tst_res(TFAIL | TTERRNO, "mq_timedreceive wrong data in loop %d returned %d, expected %d", Let's keep the messages short and to the point, something as: tst_res(TFAIL, "mq_timedreceive(): wrong data %i at %u, expected %i", rmsg[j], j, smsg[j]); And also we should drop the TTERRNO since it's uninitialized in this case. Otherwise it's fine. -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-06-06 14:26 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-06-05 20:05 [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Petr Vorel 2017-06-05 20:05 ` [LTP] [PATCH 2/3] syscalls/mq_timedsend: Convert to new API + cleanup Petr Vorel 2017-06-06 14:26 ` Cyril Hrubis 2017-06-05 20:05 ` [LTP] [PATCH 3/3] syscalls/mq_notify: Cleanup + use mq.h Petr Vorel 2017-06-06 13:58 ` [LTP] [PATCH 1/3] syscalls/mq_timedreceive: Add check data returned from mq_timedreceive Cyril Hrubis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox