Skip to contentSkip to conversation

ipc/libnewipc.c: add CREATE_MSG to optimize duplicate code

PATCH New Xiao Yang 2 participants 11 messages Dec 16, 2016 – Jan 23, 2017 Library code

lore
Share & tools
lore

Xiao Yang

author
#0 lore raw

PATCH 1/2 ipc/libnewipc.c: add CREATE_MSG to optimize duplicate code

---
 testcases/kernel/syscalls/ipc/libnewipc/libnewipc.c | 14 ++++++++++++++
 testcases/kernel/syscalls/ipc/libnewipc/libnewipc.h |  4 ++++
 testcases/kernel/syscalls/ipc/msgget/msgget02.c     |  4 +---
 3 files changed, 19 insertions(+), 3 deletions(-)
testcases/kernel/syscalls/ipc/libnewipc/libnewipc.c +14 -0
index 8ea421f..9452309 100644
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
+#include <sys/msg.h>
 
 #define	TST_NO_DEFAULT_MAIN
 
@@ -79,3 +80,16 @@ int get_used_queues(const char *file, const int lineno)
 
 	return used_queues;
 }
+
+int create_msg(const char *file, const int lineno, key_t key, int msgflg)
+{
+	int rval;
+
+	rval = msgget(key, msgflg);
+	if (rval == -1) {
+		tst_brk(TBROK | TERRNO, "Can't create message queue at %s:%d",
+			file, lineno);
+	}
+
+	return rval;
+}
testcases/kernel/syscalls/ipc/libnewipc/libnewipc.h +4 -0
index 39148be..3c313bd 100644
@@ -50,4 +50,8 @@ int get_used_queues(const char *file, const int lineno);
 #define GET_USED_QUEUES() \
 	get_used_queues(__FILE__, __LINE__)
 
+int create_msg(const char *file, const int lineno, key_t key, int msgflg);
+#define CREATE_MSG(key, msgflg) \
+	create_msg(__FILE__, __LINE__, key, msgflg)
+
 #endif /* newlibipc.h */
testcases/kernel/syscalls/ipc/msgget/msgget02.c +1 -3
index a3fcb38..1195cc9 100644
@@ -96,9 +96,7 @@ static void setup(void)
 	msgkey = GETIPCKEY();
 	msgkey1 = GETIPCKEY();
 
-	queue_id = msgget(msgkey, IPC_CREAT | IPC_EXCL);
-	if (queue_id == -1)
-		tst_brk(TBROK | TERRNO, "can't create message queue");
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL);
 
 	pw = SAFE_GETPWNAM("nobody");
 }
Signature · 1 line
1.8.3.1
author
#1 lore raw

PATCH 2/2 ipc/msgsnd0*: cleanup && convert to new API

1) The msgsnd03 was merged into msgsnd02
2) The msgsnd04 was merged into msgsnd05
3) take use of CREATE_MSG

---
 runtest/ltplite                                 |   2 -
 runtest/stress.part3                            |   2 -
 runtest/syscalls                                |   2 -
 runtest/syscalls-ipc                            |   2 -
 testcases/kernel/syscalls/.gitignore            |   2 -
 testcases/kernel/syscalls/ipc/msgsnd/Makefile   |  29 +--
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c | 198 +++++-----------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c | 245 ++++++++------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c | 178 ---------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c | 155 -------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c | 285 ++++++++----------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c | 252 +++++----------------
 12 files changed, 318 insertions(+), 1034 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c
 delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c
runtest/ltplite +0 -2
index 83141d1..d4580ad 100644
@@ -514,8 +514,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/stress.part3 +0 -2
index fcf27d0..41f8b25 100644
@@ -429,8 +429,6 @@ msgrcv07 msgrcv07
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/syscalls +0 -2
index 884ab80..dd9f9a9 100644
@@ -693,8 +693,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/syscalls-ipc +0 -2
index 8212222..91060b9 100644
@@ -27,8 +27,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
testcases/kernel/syscalls/.gitignore +0 -2
index 3201fa9..84c7977 100644
@@ -414,8 +414,6 @@
 /ipc/msgrcv/msgrcv08
 /ipc/msgsnd/msgsnd01
 /ipc/msgsnd/msgsnd02
-/ipc/msgsnd/msgsnd03
-/ipc/msgsnd/msgsnd04
 /ipc/msgsnd/msgsnd05
 /ipc/msgsnd/msgsnd06
 /ipc/semctl/semctl01
testcases/kernel/syscalls/ipc/msgsnd/Makefile +16 -13
index f467389..207fb16 100644
@@ -1,23 +1,26 @@
 #
-#  Copyright (c) International Business Machines  Corp., 2001
+# Copyright (c) International Business Machines  Corp., 2001
 #
-#  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 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.
+# 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+# You should have received a copy of the GNU General Public License
+# along with this program.
 #
 
 top_srcdir              ?= ../../../../..
 
+ifeq ($(UCLINUX),1)
+FILTER_OUT_MAKE_TARGETS += msgsnd05 msgsnd06
+endif
+
 include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
+include $(abs_srcdir)/../Makefile2.inc
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +55 -143

224 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +98 -147

273 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c deleted +0 -178

178 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c deleted +0 -155

155 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +88 -197

322 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +61 -191

283 lines not on this page · raw message

Signature · 1 line
1.8.3.1
author
#2 lore raw

PATCH 2/2 ipc/msgsnd0*: cleanup && convert to new API

Ping :-)

Quoted 1,598 lines · Xiao Yang

1) The msgsnd03 was merged into msgsnd02
2) The msgsnd04 was merged into msgsnd05
3) take use of CREATE_MSG

---
  runtest/ltplite                                 |   2 -
  runtest/stress.part3                            |   2 -
  runtest/syscalls                                |   2 -
  runtest/syscalls-ipc                            |   2 -
  testcases/kernel/syscalls/.gitignore            |   2 -
  testcases/kernel/syscalls/ipc/msgsnd/Makefile   |  29 +--
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c | 198 +++++-----------
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c | 245 ++++++++------------
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c | 178 ---------------
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c | 155 -------------
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c | 285 ++++++++----------------
  testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c | 252 +++++----------------
  12 files changed, 318 insertions(+), 1034 deletions(-)

delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c

runtest/ltplite +0 -2
index 83141d1..d4580ad 100644
@@ -514,8 +514,6 @@ msgrcv08 msgrcv08
 
  msgsnd01 msgsnd01
  msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
  msgsnd05 msgsnd05
  msgsnd06 msgsnd06
 
runtest/stress.part3 +0 -2
index fcf27d0..41f8b25 100644
@@ -429,8 +429,6 @@ msgrcv07 msgrcv07
 
  msgsnd01 msgsnd01
  msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
  msgsnd05 msgsnd05
  msgsnd06 msgsnd06
 
runtest/syscalls +0 -2
index 884ab80..dd9f9a9 100644
@@ -693,8 +693,6 @@ msgrcv08 msgrcv08
 
  msgsnd01 msgsnd01
  msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
  msgsnd05 msgsnd05
  msgsnd06 msgsnd06
 
runtest/syscalls-ipc +0 -2
index 8212222..91060b9 100644
@@ -27,8 +27,6 @@ msgrcv08 msgrcv08
 
  msgsnd01 msgsnd01
  msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
  msgsnd05 msgsnd05
  msgsnd06 msgsnd06
 
testcases/kernel/syscalls/.gitignore +0 -2
index 3201fa9..84c7977 100644
@@ -414,8 +414,6 @@
  /ipc/msgrcv/msgrcv08
  /ipc/msgsnd/msgsnd01
  /ipc/msgsnd/msgsnd02
-/ipc/msgsnd/msgsnd03
-/ipc/msgsnd/msgsnd04
  /ipc/msgsnd/msgsnd05
  /ipc/msgsnd/msgsnd06
  /ipc/semctl/semctl01
testcases/kernel/syscalls/ipc/msgsnd/Makefile +16 -13
index f467389..207fb16 100644
@@ -1,23 +1,26 @@
  #
-#  Copyright (c) International Business Machines  Corp., 2001
+# Copyright (c) International Business Machines  Corp., 2001
  #
-#  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 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.
+# 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+# You should have received a copy of the GNU General Public License
+# along with this program.
  #
 
  top_srcdir              ?= ../../../../..
 
+ifeq ($(UCLINUX),1)
+FILTER_OUT_MAKE_TARGETS += msgsnd05 msgsnd06
+endif
+
  include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
+include $(abs_srcdir)/../Makefile2.inc
  include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +55 -143
index 0ca2be0..64fff40 100644
@@ -1,169 +1,81 @@
  /*
+ * Copyright (c) International Business Machines  Corp., 2001
   *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
   *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
   */
 
  /*
- * NAME
- *	msgsnd01.c
- *
   * DESCRIPTION
- *	msgsnd01 - test that msgsnd() enqueues a message correctly
- *
- * ALGORITHM
- *	create a message queue
- *	initialize a message buffer with a known message and type
- *	loop if that option was specified
- *	enqueue the message
- *	check the return code
- *	  if failure, issue a FAIL message.
- *	otherwise,
- *	  if doing functionality testing
- *		stat the message queue
- *		check for # of bytes = MSGSIZE and # of messages = 1
- *	  	if correct,
- *			issue a PASS message
- *		otherwise
- *			issue a FAIL message
- *	call cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	None
+ * test that msgsnd() enqueues a message correctly
   */
 
-#include "test.h"
-
-#include "ipcmsg.h"
-
-void cleanup(void);
-void setup(void);
-
-char *TCID = "msgsnd01";
-int TST_TOTAL = 1;
+#include<errno.h>
+#include<sys/types.h>
+#include<sys/ipc.h>
+#include<sys/msg.h>
 
-int msg_q_1;
-MSGBUF msg_buf, rd_buf;
+#include "tst_test.h"
+#include "libnewipc.h"
 
-struct msqid_ds qs_buf;
+static key_t msgkey;
+static int queue_id;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} rcv_buf, snd_buf = {MSGTYPE, "hello, world"};
 
-int main(int ac, char **av)
+static void verify_msgsnd(void)
  {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * Use TEST macro to make the call
-		 */
-
-		TEST(msgsnd(msg_q_1,&msg_buf, MSGSIZE, 0));
-
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL, "%s call failed - errno = %d : %s",
-				 TCID, TEST_ERRNO, strerror(TEST_ERRNO));
-			continue;
-		}
-
-		/* get the queue status */
-		if (msgctl(msg_q_1, IPC_STAT,&qs_buf) == -1) {
-			tst_brkm(TBROK, cleanup, "Could not "
-				 "get queue status");
-		}
+	struct msqid_ds qs_buf;
 
-		if (qs_buf.msg_cbytes != MSGSIZE) {
-			tst_resm(TFAIL, "queue bytes != MSGSIZE");
-		}
-
-		if (qs_buf.msg_qnum != 1) {
-			tst_resm(TFAIL, "queue message != 1");
-		}
+	TEST(msgsnd(queue_id,&snd_buf, MSGSIZE, 0));
+	if (TEST_RETURN == -1) {
+		tst_res(TFAIL | TTERRNO, "msgsnd() failed");
+		return;
+	}
 
-		tst_resm(TPASS, "queue bytes = MSGSIZE and "
-			 "queue messages = 1");
+	if (msgctl(queue_id, IPC_STAT,&qs_buf) == -1)
+		tst_brk(TBROK | TERRNO, "msgctl() failed to get queue status");
 
-		/*
-		 * remove the message by reading from the queue
-		 */
-		if (msgrcv(msg_q_1,&rd_buf, MSGSIZE, 1, 0) == -1) {
-			tst_brkm(TBROK, cleanup, "Could not read from queue");
-		}
-	}
+	if (qs_buf.msg_cbytes == MSGSIZE&&  qs_buf.msg_qnum == 1)
+		tst_res(TPASS, "queue bytes and number of queues matched");
+	else
+		tst_res(TFAIL, "queue bytes or number of queues mismatched");
 
-	cleanup();
-	tst_exit();
+	if (msgrcv(queue_id,&rcv_buf, MSGSIZE, 1, 0) == -1)
+		tst_brk(TBROK | TERRNO, "msgrcv() failed");
  }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
  {
+	msgkey = GETIPCKEY();
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	msgkey = getipckey();
-
-	/* create a message queue with read/write permissions */
-	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "Can't create message queue");
-	}
-
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
  }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
  {
-	/* if it exists, remove the message queue if it exists */
-	rm_queue(msg_q_1);
-
-	tst_rmdir();
-
+	if (queue_id != -1&&  msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+			queue_id);
+	}
  }
+
+static struct tst_test test = {
+	.tid = "msgsnd01",
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_msgsnd,
+	.needs_tmpdir = 1
+};
testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +98 -147
index 6547ab2..9367775 100644
@@ -1,175 +1,126 @@
  /*
+ * Copyright (c) International Business Machines  Corp., 2001
   *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
   *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
   */
 
  /*
- * NAME
- *	msgsnd02.c
- *
   * DESCRIPTION
- *	msgsnd02 - test for EACCES and EFAULT errors
- *
- * ALGORITHM
- *	create a message queue without write permission
- *	create a trivial message buffer
- *	loop if that option was specified
- *	call msgsnd() using two different invalid cases
- *	check the errno value
- *	  issue a PASS message if we get EACCES or EFAULT
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	call cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd02 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
+ * 1) test for EACCES error
+ * 2) test for EFAULT error
+ * 3) test for EINVAL error
   */
-#include<pwd.h>
-#include "test.h"
-
-#include "ipcmsg.h"
-
-void cleanup(void);
-void setup(void);
 
-char *TCID = "msgsnd02";
-int TST_TOTAL = 2;
-
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-MSGBUF msg_buf;			/* a buffer for the message to queue */
-int bad_q = -1;			/* a value to use as a bad queue ID */
-
-struct test_case_t {
-	int *queue_id;
-	MSGBUF *buffer;
-	int error;
-} TC[] = {
-	/* EACCES - there is no write permission for the queue */
-	{
-	&msg_q_1,&msg_buf, EACCES},
-	    /* EFAULT - the message buffer address is invalid */
-	{
-&msg_q_1, NULL, EFAULT},};
+#include<errno.h>
+#include<string.h>
+#include<stdlib.h>
+#include<sys/types.h>
+#include<sys/ipc.h>
+#include<sys/msg.h>
+#include<pwd.h>
 
-int main(int ac, char **av)
+#include "tst_test.h"
+#include "libnewipc.h"
+
+static key_t msgkey;
+static int queue_id = -1;
+static int bad_id = -1;
+static struct passwd *pw;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
+
+static struct tcase {
+	int *id;
+	struct buf *buffer;
+	long mtype;
+	int msgsz;
+	int exp_err;
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+} tcases[] = {
+	{&queue_id,&snd_buf, 1, MSGSIZE, EACCES, 1},
+	{&queue_id, NULL, 1, MSGSIZE, EFAULT, 0},
+	{&bad_id,&snd_buf, 1, MSGSIZE, EINVAL, 0},
+	{&queue_id,&snd_buf, 0, MSGSIZE, EINVAL, 0},
+	{&queue_id,&snd_buf, -1, MSGSIZE, EINVAL, 0},
+	{&queue_id,&snd_buf, 1, -1, EINVAL, 0}
+};
+
+static void verify_msgsnd(struct tcase *tc)
  {
-	int lc;
-	int i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * loop through the test cases
-		 */
+	snd_buf.type = tc->mtype;
 
-		for (i = 0; i<  TST_TOTAL; i++) {
-			TEST(msgsnd(*(TC[i].queue_id), TC[i].buffer, 1, 0));
-
-			if (TEST_RETURN != -1) {
-				tst_resm(TFAIL, "call succeeded unexpectedly");
-				continue;
-			}
-
-			if (TEST_ERRNO == TC[i].error) {
-				tst_resm(TPASS, "expected failure - "
-					 "errno = %d : %s", TEST_ERRNO,
-					 strerror(TEST_ERRNO));
-			} else {
-				tst_resm(TFAIL, "unexpected error - %d : %s",
-					 TEST_ERRNO, strerror(TEST_ERRNO));
-			}
-		}
+	TEST(msgsnd(*tc->id, tc->buffer, tc->msgsz, 0));
+	if (TEST_RETURN != -1) {
+		tst_res(TFAIL, "smgsnd() succeeded unexpectedly");
+		return;
  	}
 
-	cleanup();
-
-	tst_exit();
+	if (TEST_ERRNO == tc->exp_err) {
+		tst_res(TPASS | TTERRNO, "msgsnd() failed as expected");
+	} else {
+		tst_res(TFAIL | TTERRNO, "msgsnd() failed unexpectedly,"
+			" expected %s", tst_strerrno(tc->exp_err));
+	}
  }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void do_test(unsigned int n)
  {
-	tst_require_root();
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+	pid_t pid;
+	struct tcase *tc =&tcases[n];
 
-	TEST_PAUSE;
-
-	/* Switch to nobody user for correct error code collection */
-	ltpuser = getpwnam(nobody_uid);
-	if (setuid(ltpuser->pw_uid) == -1) {
-		tst_resm(TINFO, "setuid failed to "
-			 "to set the effective uid to %d", ltpuser->pw_uid);
-		perror("setuid");
+	if (tc->exp_user == 0) {
+		verify_msgsnd(tc);
+		return;
  	}
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	msgkey = getipckey();
-
-	/* create a message queue without write permission */
-	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RD)) == -1) {
-		tst_brkm(TBROK, cleanup, "Can't create message queue");
+	pid = SAFE_FORK();
+	if (pid) {
+		tst_reap_children();
+	} else {
+		SAFE_SETUID(pw->pw_uid);
+		verify_msgsnd(tc);
+		exit(0);
  	}
-
-	/* initialize the message buffer with something trivial */
-	msg_buf.mtype = MSGTYPE;
-	msg_buf.mtext[0] = 'a';
  }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void setup(void)
  {
-	/* if it exists, remove the message queue that was created */
-	rm_queue(msg_q_1);
+	msgkey = GETIPCKEY();
 
-	tst_rmdir();
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
 
+	pw = SAFE_GETPWNAM("nobody");
  }
+
+static void cleanup(void)
+{
+	if (queue_id != -1&&  msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+			queue_id);
+	}
+}
+
+static struct tst_test test = {
+	.tid = "msgsnd02",
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = do_test
+};
testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c deleted +0 -178
deleted file mode 100644
index ef6e58e..0000000
@@ -1,178 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   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
- */
-
-/*
- * NAME
- *	msgsnd03.c
- *
- * DESCRIPTION
- *	msgsnd03 - test for EINVAL error
- *
- * ALGORITHM
- *	create a message queue with read/write permissions
- *	create a trivial message buffer
- *	loop if that option was specified
- *	call msgsnd() using four different invalid cases
- *	check the errno value
- *	  issue a PASS message if we get EINVAL
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	call cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd03 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
- */
-
-#include "test.h"
-
-#include "ipcmsg.h"
-
-void cleanup(void);
-void setup(void);
-
-char *TCID = "msgsnd03";
-int TST_TOTAL = 4;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-MSGBUF msg_buf;			/* a buffer for the message to queue */
-int bad_q = -1;			/* a value to use as a bad queue ID */
-
-struct test_case_t {
-	int *queue_id;
-	MSGBUF *buffer;
-	long mtype;
-	int msg_size;
-	int error;
-} TC[] = {
-	/* EINVAL - the queue ID is invalid */
-	{
-	&bad_q,&msg_buf, 1, 1, EINVAL},
-	    /* EINVAL - the message type is not positive (0) */
-	{
-	&msg_q_1,&msg_buf, 0, 1, EINVAL},
-	    /* EINVAL - the message type is not positive (>0) */
-	{
-	&msg_q_1,&msg_buf, -1, 1, EINVAL},
-	    /* EINVAL - the message size is less than zero */
-	{
-	&msg_q_1,&msg_buf, 1, -1, EINVAL}
-};
-
-int main(int ac, char **av)
-{
-	int lc;
-	int i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * loop through the test cases
-		 */
-
-		for (i = 0; i<  TST_TOTAL; i++) {
-
-			/* set the message type */
-			msg_buf.mtype = TC[i].mtype;
-
-			/* make the call with the TEST macro */
-			TEST(msgsnd(*(TC[i].queue_id), TC[i].buffer,
-				    TC[i].msg_size, 0));
-
-			if (TEST_RETURN != -1) {
-				tst_resm(TFAIL, "call succeeded unexpectedly");
-				continue;
-			}
-
-			if (TEST_ERRNO == TC[i].error) {
-				tst_resm(TPASS, "expected failure - "
-					 "errno = %d : %s", TEST_ERRNO,
-					 strerror(TEST_ERRNO));
-			} else {
-				tst_resm(TFAIL, "unexpected error - %d : %s",
-					 TEST_ERRNO, strerror(TEST_ERRNO));
-			}
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	msgkey = getipckey();
-
-	/* create a message queue with read/write permission */
-	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "Can't create message queue");
-	}
-
-	/* initialize the message buffer with something trivial */
-	msg_buf.mtype = MSGTYPE;
-	msg_buf.mtext[0] = 'a';
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
-{
-	/* if it exists, remove the message queue that was created */
-	rm_queue(msg_q_1);
-
-	tst_rmdir();
-
-}
testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c deleted +0 -155
deleted file mode 100644
index 4432d67..0000000
@@ -1,155 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   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
- */
-
-/*
- * NAME
- *	msgsnd04.c
- *
- * DESCRIPTION
- *	msgsnd04 - test for EAGAIN error
- *
- * ALGORITHM
- *	create a message queue with read/write permissions
- *	initialize a message buffer with a known message and type
- *	enqueue the message in a loop until the queue is full
- *	loop if that option was specified
- *	attempt to enqueue another message - msgsnd()
- *	check the errno value
- *	  issue a PASS message if we get EAGAIN
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	call cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd04 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
- */
-
-#include "test.h"
-
-#include "ipcmsg.h"
-
-void cleanup(void);
-void setup(void);
-
-char *TCID = "msgsnd04";
-int TST_TOTAL = 1;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-MSGBUF msg_buf;
-
-int main(int ac, char **av)
-{
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * Attempt to write another message to the full queue.
-		 */
-
-		TEST(msgsnd(msg_q_1,&msg_buf, MSGSIZE, IPC_NOWAIT));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case EAGAIN:
-			tst_resm(TPASS, "expected failure - errno = %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	msgkey = getipckey();
-
-	/* create a message queue with read/write permission */
-	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "Can't create message queue");
-	}
-
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
-
-	/* write messages to the queue until it is full */
-	while (msgsnd(msg_q_1,&msg_buf, MSGSIZE, IPC_NOWAIT) != -1) {
-		msg_buf.mtype += 1;
-	}
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
-{
-	/* if it exists, remove the message queue that was created */
-	rm_queue(msg_q_1);
-
-	tst_rmdir();
-
-}
testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +88 -197
index 16d62f8..0d13065 100644
@@ -1,234 +1,125 @@
  /*
+ * Copyright (c) International Business Machines  Corp., 2001
   *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
   *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
   */
 
  /*
- * NAME
- *	msgsnd05.c
- *
   * DESCRIPTION
- *	msgsnd05 - test for EINTR error
- *
- * ALGORITHM
- *	create a message queue with read/write permissions
- *	initialize a message buffer with a known message and type
- *	enqueue the message in a loop until the queue is full
- *	loop if that option was specified
- *	fork a child process
- *	child attempts to enqueue a message to the full queue and sleeps
- *	parent sends a SIGHUP to the child then waits for the child to complete
- *	child get a return from msgsnd()
- *	check the errno value
- *	  issue a PASS message if we get EINTR
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	child exits, parent calls cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd05 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *      14/03/2008 Matthieu Fertré ([email protected])
- *      - Fix concurrency issue. Due to the use of usleep function to
- *        synchronize processes, synchronization issues can occur on a loaded
- *        system. Fix this by using pipes to synchronize processes.
- *
- * RESTRICTIONS
- *	none
+ * 1) test for EAGAIN error
+ * 2) test for EINTR error
   */
 
-#include "test.h"
-
-#include "ipcmsg.h"
-
+#include<errno.h>
+#include<stdlib.h>
  #include<sys/types.h>
-#include<sys/wait.h>
-
-void do_child(void);
-void cleanup(void);
-void setup(void);
-#ifdef UCLINUX
-#define PIPE_NAME	"msgsnd05"
-void do_child_uclinux(void);
-#endif
-
-char *TCID = "msgsnd05";
-int TST_TOTAL = 1;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-
-MSGBUF msg_buf;
-
-int main(int ac, char **av)
+#include<sys/ipc.h>
+#include<sys/msg.h>
+
+#include "tst_test.h"
+#include "libnewipc.h"
+
+static key_t msgkey;
+static int queue_id = -1;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
+
+static struct tcase {
+	int flag;
+	int exp_err;
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+} tcases[] = {
+	{IPC_NOWAIT, EAGAIN, 0},
+	{0, EINTR, 1}
+};
+
+static void verify_msgsnd(struct tcase *tc)
  {
-	int lc;
-	pid_t c_pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_child_uclinux, "d",&msg_q_1);
-#endif
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * fork a child that will attempt to write a message
-		 * to the queue without IPC_NOWAIT
-		 */
-		if ((c_pid = FORK_OR_VFORK()) == -1) {
-			tst_brkm(TBROK, cleanup, "could not fork");
-		}
-
-		if (c_pid == 0) {	/* child */
-			/*
-			 * Attempt to write another message to the full queue.
-			 * Without the IPC_NOWAIT flag, the child sleeps
-			 */
-
-#ifdef UCLINUX
-			if (self_exec(av[0], "d", msg_q_1)<  0) {
-				tst_brkm(TBROK, cleanup, "could not self_exec");
-			}
-#else
-			do_child();
-#endif
-		} else {
-			TST_PROCESS_STATE_WAIT(cleanup, c_pid, 'S');
-
-			/* send a signal that must be caught to the child */
-			if (kill(c_pid, SIGHUP) == -1)
-				tst_brkm(TBROK, cleanup, "kill failed");
-
-			waitpid(c_pid, NULL, 0);
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
-}
-
-/*
- * do_child()
- */
-void do_child(void)
-{
-	TEST(msgsnd(msg_q_1,&msg_buf, MSGSIZE, 0));
-
+	TEST(msgsnd(queue_id,&snd_buf, MSGSIZE, tc->flag));
  	if (TEST_RETURN != -1) {
-		tst_resm(TFAIL, "call succeeded when error expected");
-		exit(-1);
+		tst_res(TFAIL, "msgsnd() succeeded unexpectedly");
+		return;
  	}
 
-	switch (TEST_ERRNO) {
-	case EINTR:
-		tst_resm(TPASS, "expected failure - errno = %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
-	default:
-		tst_resm(TFAIL,
-			 "call failed with an unexpected error - %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
+	if (TEST_ERRNO == tc->exp_err) {
+		tst_res(TPASS | TTERRNO, "msgsnd() failed as expected");
+	} else {
+		tst_res(TFAIL | TTERRNO, "msgsnd() failed unexpectedly,"
+			" expected %s", tst_strerrno(tc->exp_err));
  	}
-
-	exit(0);
  }
 
-void sighandler(int sig)
+static void sighandler(int sig)
  {
  	if (sig == SIGHUP)
  		return;
  	else
-		tst_brkm(TBROK, NULL, "received unexpected signal %d", sig);
+		tst_brk(TBROK, "received unexpected signal %d", sig);
  }
 
-#ifdef UCLINUX
-/*
- * do_child_uclinux() - capture signals, initialize buffer, then run do_child()
- */
-void do_child_uclinux(void)
+static void do_test(unsigned int n)
  {
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
-
-	tst_sig(FORK, sighandler, cleanup);
+	pid_t pid;
+	struct tcase *tc =&tcases[n];
 
-	do_child();
-}
-#endif
+	if (tc->exp_user == 0) {
+		verify_msgsnd(tc);
+		return;
+	}
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-	/* capture signals in our own handler */
-	tst_sig(FORK, sighandler, cleanup);
+	pid = SAFE_FORK();
+	if (!pid) {
+		verify_msgsnd(tc);
+		exit(0);
+	}
 
-	TEST_PAUSE;
+	TST_PROCESS_STATE_WAIT(pid, 'S');
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
+	SAFE_KILL(pid, SIGHUP);
+	tst_reap_children();
+}
 
-	msgkey = getipckey();
+static void setup(void)
+{
+	SAFE_SIGNAL(SIGHUP, sighandler);
 
-	/* create a message queue with read/write permission */
-	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "Can't create message queue");
-	}
+	msgkey = GETIPCKEY();
 
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
 
-	/* write messages to the queue until it is full */
-	while (msgsnd(msg_q_1,&msg_buf, MSGSIZE, IPC_NOWAIT) != -1) {
-		msg_buf.mtype += 1;
-	}
+	while (msgsnd(queue_id,&snd_buf, MSGSIZE, IPC_NOWAIT) != -1)
+		snd_buf.type += 1;
  }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
  {
-	/* if it exists, remove the message queue that was created */
-	rm_queue(msg_q_1);
-
-	tst_rmdir();
-
+	if (queue_id != -1&&  msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+			queue_id);
+	}
  }
+
+static struct tst_test test = {
+	.tid = "msgsnd05",
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = do_test
+};
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +61 -191
index 42f6e79..737fc7f 100644
@@ -1,222 +1,92 @@
  /*
+ * Copyright (c) International Business Machines  Corp., 2001
   *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
   *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
   */
 
  /*
- * NAME
- *	msgsnd06.c
- *
   * DESCRIPTION
- *	msgsnd06 - test for EIDRM error
- *
- * ALGORITHM
- *	loop if that option was specified
- *	create a message queue with read/write permissions
- *	initialize a message buffer with a known message and type
- *	enqueue messages in a loop until the queue is full
- *	fork a child process
- *	child attempts to enqueue a message to the full queue and sleeps
- *	parent removes the queue and then exits
- *	child get a return from msgsnd()
- *	check the errno value
- *	  issue a PASS message if we get EIDRM
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	call cleanup
- *
- * USAGE:<for command-line>
- *  msgsnd06 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *      14/03/2008 Matthieu Fertré ([email protected])
- *      - Fix concurrency issue. Due to the use of usleep function to
- *        synchronize processes, synchronization issues can occur on a loaded
- *        system. Fix this by using pipes to synchronize processes.
- *
- * RESTRICTIONS
- *	none
+ * test for EIDRM error
   */
 
-#include<sys/wait.h>
-#include "test.h"
+#include<errno.h>
+#include<stdlib.h>
+#include<sys/types.h>
+#include<sys/ipc.h>
+#include<sys/msg.h>
 
-#include "ipcmsg.h"
+#include "tst_test.h"
+#include "libnewipc.h"
 
-void cleanup(void);
-void setup(void);
-void do_child(void);
+static key_t msgkey;
+static int queue_id = -1;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
 
-char *TCID = "msgsnd06";
-int TST_TOTAL = 1;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-
-MSGBUF msg_buf;
-
-int main(int ac, char **av)
+static void verify_msgsnd(void)
  {
-	int lc;
-	pid_t c_pid;
-	int status, e_code;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-#define PIPE_NAME	"msgsnd06"
-	maybe_run_child(&do_child, "d",&msg_q_1);
-#endif
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		msgkey = getipckey();
-
-		/* create a message queue with read/write permission */
-		if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW))
-		    == -1) {
-			tst_brkm(TBROK, cleanup, "Can't create message queue");
-		}
-
-		/* initialize the message buffer */
-		init_buf(&msg_buf, MSGTYPE, MSGSIZE);
-
-		/* write messages to the queue until it is full */
-		while (msgsnd(msg_q_1,&msg_buf, MSGSIZE, IPC_NOWAIT) != -1) {
-			msg_buf.mtype += 1;
-		}
-
-		/*
-		 * fork a child that will attempt to write a message
-		 * to the queue without IPC_NOWAIT
-		 */
-		if ((c_pid = FORK_OR_VFORK()) == -1) {
-			tst_brkm(TBROK, cleanup, "could not fork");
-		}
-
-		if (c_pid == 0) {	/* child */
-
-#ifdef UCLINUX
-			if (self_exec(av[0], "d", msg_q_1)<  0) {
-				tst_brkm(TBROK, cleanup, "could not self_exec");
-			}
-#else
-			do_child();
-#endif
-		} else {
-			TST_PROCESS_STATE_WAIT(cleanup, c_pid, 'S');
-
-			/* remove the queue */
-			rm_queue(msg_q_1);
-
-			/* wait for the child to finish */
-			wait(&status);
-			/* make sure the child returned a good exit status */
-			e_code = status>>  8;
-			if (e_code != 0) {
-				tst_resm(TFAIL, "Failures reported above");
-			}
-		}
+	TEST(msgsnd(queue_id,&snd_buf, MSGSIZE, 0));
+	if (TEST_RETURN != -1) {
+		tst_res(TFAIL, "msgsnd() succeeded unexpectedly");
+		return;
  	}
 
-	cleanup();
-
-	tst_exit();
+	if (TEST_ERRNO == EIDRM) {
+		tst_res(TPASS | TTERRNO, "msgsnd() failed as expected");
+	} else {
+		tst_res(TFAIL | TTERRNO,
+			"msgsnd() failed unexpectedly, expected EIDRM");
+	}
  }
 
-/*
- * do_child()
- */
-void do_child(void)
+static void do_test(void)
  {
-	int retval = 0;
+	pid_t pid;
 
-#ifdef UCLINUX
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
 
-#endif
-	/*
-	 * Attempt to write another message to the full queue.
-	 * Without the IPC_NOWAIT flag, the child sleeps
-	 */
-	TEST(msgsnd(msg_q_1,&msg_buf, MSGSIZE, 0));
+	while (msgsnd(queue_id,&snd_buf, MSGSIZE, IPC_NOWAIT) != -1)
+		snd_buf.type += 1;
 
-	if (TEST_RETURN != -1) {
-		retval = 1;
-		tst_resm(TFAIL, "call succeeded when error expected");
-		exit(retval);
+	pid = SAFE_FORK();
+	if (!pid) {
+		verify_msgsnd();
+		exit(0);
  	}
 
-	switch (TEST_ERRNO) {
-	case EIDRM:
-		tst_resm(TPASS, "expected failure - errno = %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
+	TST_PROCESS_STATE_WAIT(pid, 'S');
 
-		/* mark the queue as invalid as it was removed */
-		msg_q_1 = -1;
-		break;
-	default:
-		retval = 1;
-		tst_resm(TFAIL,
-			 "call failed with an unexpected error - %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
+	if (queue_id != -1&&  msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+				queue_id);
  	}
-	exit(retval);
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
+	tst_reap_children();
  }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void setup(void)
  {
-
-	tst_rmdir();
-
+	msgkey = GETIPCKEY();
  }
+
+static struct tst_test test = {
+	.tid = "msgsnd06",
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.test_all = do_test
+};
#3 lore raw

PATCH 2/2 ipc/msgsnd0*: cleanup && convert to new API

In reply to Xiao Yang

Hi!

testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c line 69

Quoted 8 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +2 -5
+static void cleanup(void)
 {
-	/* if it exists, remove the message queue if it exists */
-	rm_queue(msg_q_1);
-
-	tst_rmdir();
-
+	if (queue_id != -1 && msgctl(queue_id, IPC_RMID, NULL)) {

You should initialized the queue_id to -1, since otherwise you may attempt to remove queue id 0 if cleanup is executed before msgget() returns and queue_id is initialized.

testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c

Quoted 12 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +11 -0
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+			queue_id);
+	}
 }
+
+static struct tst_test test = {
+	.tid = "msgsnd01",
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_msgsnd,
+	.needs_tmpdir = 1
+}

Otherwise it looks fine.

Quoted 2 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +0 -0
index 6547ab2..9367775 100644

...

Quoted 35 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +27 -7
+static key_t msgkey;
+static int queue_id = -1;
+static int bad_id = -1;
+static struct passwd *pw;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
+
+static struct tcase {
+	int *id;
+	struct buf *buffer;
+	long mtype;
+	int msgsz;
+	int exp_err;
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+} tcases[] = {
+	{&queue_id, &snd_buf, 1, MSGSIZE, EACCES, 1},
+	{&queue_id, NULL, 1, MSGSIZE, EFAULT, 0},
+	{&bad_id, &snd_buf, 1, MSGSIZE, EINVAL, 0},
+	{&queue_id, &snd_buf, 0, MSGSIZE, EINVAL, 0},
+	{&queue_id, &snd_buf, -1, MSGSIZE, EINVAL, 0},
+	{&queue_id, &snd_buf, 1, -1, EINVAL, 0}
+};
+
+static void verify_msgsnd(struct tcase *tc)
 {
-	int lc;
-	int i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-

testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c line 64

Quoted 10 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +1 -9
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * loop through the test cases
-		 */
+	snd_buf.type = tc->mtype;

This is kind of hack. Why can't we create three struct buf variables and assign them to the tcases structure instead of modyfing it this way?

Otherwise it looks fine.

Quoted 216 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +47 -148
index 16d62f8..0d13065 100644
@@ -1,234 +1,125 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
  *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  */
 
 /*
- * NAME
- *	msgsnd05.c
- *
  * DESCRIPTION
- *	msgsnd05 - test for EINTR error
- *
- * ALGORITHM
- *	create a message queue with read/write permissions
- *	initialize a message buffer with a known message and type
- *	enqueue the message in a loop until the queue is full
- *	loop if that option was specified
- *	fork a child process
- *	child attempts to enqueue a message to the full queue and sleeps
- *	parent sends a SIGHUP to the child then waits for the child to complete
- *	child get a return from msgsnd()
- *	check the errno value
- *	  issue a PASS message if we get EINTR
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	child exits, parent calls cleanup
- *
- * USAGE:  <for command-line>
- *  msgsnd05 [-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.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *      14/03/2008 Matthieu Fertr?? ([email protected])
- *      - Fix concurrency issue. Due to the use of usleep function to
- *        synchronize processes, synchronization issues can occur on a loaded
- *        system. Fix this by using pipes to synchronize processes.
- *
- * RESTRICTIONS
- *	none
+ * 1) test for EAGAIN error
+ * 2) test for EINTR error
  */
 
-#include "test.h"
-
-#include "ipcmsg.h"
-
+#include <errno.h>
+#include <stdlib.h>
 #include <sys/types.h>
-#include <sys/wait.h>
-
-void do_child(void);
-void cleanup(void);
-void setup(void);
-#ifdef UCLINUX
-#define PIPE_NAME	"msgsnd05"
-void do_child_uclinux(void);
-#endif
-
-char *TCID = "msgsnd05";
-int TST_TOTAL = 1;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-
-MSGBUF msg_buf;
-
-int main(int ac, char **av)
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#include "tst_test.h"
+#include "libnewipc.h"
+
+static key_t msgkey;
+static int queue_id = -1;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
+
+static struct tcase {
+	int flag;
+	int exp_err;
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+} tcases[] = {
+	{IPC_NOWAIT, EAGAIN, 0},
+	{0, EINTR, 1}
+};
+
+static void verify_msgsnd(struct tcase *tc)
 {
-	int lc;
-	pid_t c_pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_child_uclinux, "d", &msg_q_1);
-#endif
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * fork a child that will attempt to write a message
-		 * to the queue without IPC_NOWAIT
-		 */
-		if ((c_pid = FORK_OR_VFORK()) == -1) {
-			tst_brkm(TBROK, cleanup, "could not fork");
-		}
-
-		if (c_pid == 0) {	/* child */
-			/*
-			 * Attempt to write another message to the full queue.
-			 * Without the IPC_NOWAIT flag, the child sleeps
-			 */
-
-#ifdef UCLINUX
-			if (self_exec(av[0], "d", msg_q_1) < 0) {
-				tst_brkm(TBROK, cleanup, "could not self_exec");
-			}
-#else
-			do_child();
-#endif
-		} else {
-			TST_PROCESS_STATE_WAIT(cleanup, c_pid, 'S');
-
-			/* send a signal that must be caught to the child */
-			if (kill(c_pid, SIGHUP) == -1)
-				tst_brkm(TBROK, cleanup, "kill failed");
-
-			waitpid(c_pid, NULL, 0);
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
-}
-
-/*
- * do_child()
- */
-void do_child(void)
-{
-	TEST(msgsnd(msg_q_1, &msg_buf, MSGSIZE, 0));
-
+	TEST(msgsnd(queue_id, &snd_buf, MSGSIZE, tc->flag));
 	if (TEST_RETURN != -1) {
-		tst_resm(TFAIL, "call succeeded when error expected");
-		exit(-1);
+		tst_res(TFAIL, "msgsnd() succeeded unexpectedly");
+		return;
 	}
 
-	switch (TEST_ERRNO) {
-	case EINTR:
-		tst_resm(TPASS, "expected failure - errno = %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
-	default:
-		tst_resm(TFAIL,
-			 "call failed with an unexpected error - %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
+	if (TEST_ERRNO == tc->exp_err) {
+		tst_res(TPASS | TTERRNO, "msgsnd() failed as expected");
+	} else {
+		tst_res(TFAIL | TTERRNO, "msgsnd() failed unexpectedly,"
+			" expected %s", tst_strerrno(tc->exp_err));
 	}
-
-	exit(0);

testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c line 71

Quoted 10 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +2 -2
 }
 
-void sighandler(int sig)
+static void sighandler(int sig)
 {
 	if (sig == SIGHUP)
 		return;
 	else
-		tst_brkm(TBROK, NULL, "received unexpected signal %d", sig);
+		tst_brk(TBROK, "received unexpected signal %d", sig);

Using tst_brk() in signal handler is NOT safe.

Looking at the code the best solution would be to just call _exit(TBROK); here instead, which is one of the things you can do safely in a signal handler.

Otherwise it looks fine.

Quoted 66 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +11 -42
index 42f6e79..737fc7f 100644
@@ -1,222 +1,92 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * 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 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.
  *
- *   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
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  */
 
 /*
- * NAME
- *	msgsnd06.c
- *
  * DESCRIPTION
- *	msgsnd06 - test for EIDRM error
- *
- * ALGORITHM
- *	loop if that option was specified
- *	create a message queue with read/write permissions
- *	initialize a message buffer with a known message and type
- *	enqueue messages in a loop until the queue is full
- *	fork a child process
- *	child attempts to enqueue a message to the full queue and sleeps
- *	parent removes the queue and then exits
- *	child get a return from msgsnd()
- *	check the errno value
- *	  issue a PASS message if we get EIDRM
- *	otherwise, the tests fails
- *	  issue a FAIL message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  msgsnd06 [-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.
- *

testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c line 20

Quoted 10 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +1 -9
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *      14/03/2008 Matthieu Fertr?? ([email protected])
- *      - Fix concurrency issue. Due to the use of usleep function to
- *        synchronize processes, synchronization issues can occur on a loaded
- *        system. Fix this by using pipes to synchronize processes.
- *
- * RESTRICTIONS
- *	none
+ * test for EIDRM error

This may be a bit more detailed, i.e. something as:

Tests if EIDRM is returned when message queue was removed while msgsnd() was trying to send a message.

Quoted 156 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +34 -107
-#include <sys/wait.h>
-#include "test.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
 
-#include "ipcmsg.h"
+#include "tst_test.h"
+#include "libnewipc.h"
 
-void cleanup(void);
-void setup(void);
-void do_child(void);
+static key_t msgkey;
+static int queue_id = -1;
+static struct buf {
+	long type;
+	char text[MSGSIZE];
+} snd_buf = {1, "hello, world"};
 
-char *TCID = "msgsnd06";
-int TST_TOTAL = 1;
-
-int msg_q_1 = -1;		/* The message queue id created in setup */
-
-MSGBUF msg_buf;
-
-int main(int ac, char **av)
+static void verify_msgsnd(void)
 {
-	int lc;
-	pid_t c_pid;
-	int status, e_code;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-#define PIPE_NAME	"msgsnd06"
-	maybe_run_child(&do_child, "d", &msg_q_1);
-#endif
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		msgkey = getipckey();
-
-		/* create a message queue with read/write permission */
-		if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW))
-		    == -1) {
-			tst_brkm(TBROK, cleanup, "Can't create message queue");
-		}
-
-		/* initialize the message buffer */
-		init_buf(&msg_buf, MSGTYPE, MSGSIZE);
-
-		/* write messages to the queue until it is full */
-		while (msgsnd(msg_q_1, &msg_buf, MSGSIZE, IPC_NOWAIT) != -1) {
-			msg_buf.mtype += 1;
-		}
-
-		/*
-		 * fork a child that will attempt to write a message
-		 * to the queue without IPC_NOWAIT
-		 */
-		if ((c_pid = FORK_OR_VFORK()) == -1) {
-			tst_brkm(TBROK, cleanup, "could not fork");
-		}
-
-		if (c_pid == 0) {	/* child */
-
-#ifdef UCLINUX
-			if (self_exec(av[0], "d", msg_q_1) < 0) {
-				tst_brkm(TBROK, cleanup, "could not self_exec");
-			}
-#else
-			do_child();
-#endif
-		} else {
-			TST_PROCESS_STATE_WAIT(cleanup, c_pid, 'S');
-
-			/* remove the queue */
-			rm_queue(msg_q_1);
-
-			/* wait for the child to finish */
-			wait(&status);
-			/* make sure the child returned a good exit status */
-			e_code = status >> 8;
-			if (e_code != 0) {
-				tst_resm(TFAIL, "Failures reported above");
-			}
-		}
+	TEST(msgsnd(queue_id, &snd_buf, MSGSIZE, 0));
+	if (TEST_RETURN != -1) {
+		tst_res(TFAIL, "msgsnd() succeeded unexpectedly");
+		return;
 	}
 
-	cleanup();
-
-	tst_exit();
+	if (TEST_ERRNO == EIDRM) {
+		tst_res(TPASS | TTERRNO, "msgsnd() failed as expected");
+	} else {
+		tst_res(TFAIL | TTERRNO,
+			"msgsnd() failed unexpectedly, expected EIDRM");
+	}
 }
 
-/*
- * do_child()
- */
-void do_child(void)
+static void do_test(void)
 {
-	int retval = 0;
+	pid_t pid;
 
-#ifdef UCLINUX
-	/* initialize the message buffer */
-	init_buf(&msg_buf, MSGTYPE, MSGSIZE);
+	queue_id = CREATE_MSG(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
 
-#endif
-	/*
-	 * Attempt to write another message to the full queue.
-	 * Without the IPC_NOWAIT flag, the child sleeps
-	 */
-	TEST(msgsnd(msg_q_1, &msg_buf, MSGSIZE, 0));
+	while (msgsnd(queue_id, &snd_buf, MSGSIZE, IPC_NOWAIT) != -1)
+		snd_buf.type += 1;
 
-	if (TEST_RETURN != -1) {
-		retval = 1;
-		tst_resm(TFAIL, "call succeeded when error expected");
-		exit(retval);
+	pid = SAFE_FORK();
+	if (!pid) {
+		verify_msgsnd();
+		exit(0);
 	}
 
-	switch (TEST_ERRNO) {
-	case EIDRM:
-		tst_resm(TPASS, "expected failure - errno = %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
+	TST_PROCESS_STATE_WAIT(pid, 'S');
 
-		/* mark the queue as invalid as it was removed */
-		msg_q_1 = -1;

testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c line 74

Quoted 10 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +3 -7
-		break;
-	default:
-		retval = 1;
-		tst_resm(TFAIL,
-			 "call failed with an unexpected error - %d : %s",
-			 TEST_ERRNO, strerror(TEST_ERRNO));
-		break;
+	if (queue_id != -1 && msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+				queue_id);

Uh, the queue_id canot be -1 here, right?

Also this is tst_brk(TBROK | TERRNO, ...) not TWARN, we are not in cleanup here.

And the queue_id should be reset to -1 right after it was removed succesfully and there should be a cleanup that removes the queue if queue_id is not set to -1, because the test may still call tst_brk() somewhere between the creation and removal of the queue. We have to be careful with System V queues since these are global persistent objects that can outlive the test easily.

Quoted 52 lines
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +12 -26
 	}
-	exit(retval);
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See ../lib/libipc.c for more information.
-	 */
-	tst_tmpdir();
+	tst_reap_children();
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void setup(void)
 {
-
-	tst_rmdir();
-
+	msgkey = GETIPCKEY();
 }
+
+static struct tst_test test = {
+	.tid = "msgsnd06",
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.test_all = do_test
+};
Signature · 7 lines
1.8.3.1




-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
Signature · 2 lines
Cyril Hrubis
[email protected]
#4 lore raw

PATCH 1/2 ipc/libnewipc.c: add CREATE_MSG to optimize duplicate code

In reply to Xiao Yang

Hi!

testcases/kernel/syscalls/ipc/libnewipc/libnewipc.h int get_used_queues(const char *file, const int lineno); · line 55

Quoted 3 lines
testcases/kernel/syscalls/ipc/libnewipc/libnewipc.h +3 -0
+int create_msg(const char *file, const int lineno, key_t key, int msgflg);
+#define CREATE_MSG(key, msgflg) \
+	create_msg(__FILE__, __LINE__, key, msgflg)

Looking at this, we should rather start tst_safe_sysv_ipc.h and implement it as SAFE_MSGGET() so that possibly reusable outside the ipc directory as well.

Signature · 2 lines
Cyril Hrubis
[email protected]
author
#5 lore raw

PATCH v2 1/3 lib/tst_safe_sysv_ipc.c : Add tst_safe_sysv_ipc.c

Add SAFE_MSGGET(), SAFE_MSGSND(), SAFE_MSGRCV() and SAFE_MSGCTL() macros to simplify IPC related cases.

---
 include/tst_safe_sysv_ipc.h | 40 +++++++++++++++++++++++
 include/tst_test.h          |  1 +
 lib/tst_safe_sysv_ipc.c     | 78 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 include/tst_safe_sysv_ipc.h
 create mode 100644 lib/tst_safe_sysv_ipc.c
include/tst_safe_sysv_ipc.h new file +40 -0
new file mode 100644
index 0000000..29ded4f
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Xiao yang <[email protected]>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TST_SAFE_SYSV_IPC_H__
+# define TST_SAFE_SYSV_IPC_H__
+
+int safe_msgget(const char *file, const int lineno, key_t key, int msgflg);
+#define SAFE_MSGGET(key, msgflg) \
+	safe_msgget(__FILE__, __LINE__, (key), (msgflg))
+
+int safe_msgsnd(const char *file, const int lineno, int msqid, const void *msgp,
+		size_t msgsz, int msgflg);
+#define SAFE_MSGSND(msqid, msgp, msgsz, msgflg) \
+	safe_msgsnd(__FILE__, __LINE__, (msqid), (msgp), (msgsz), (msgflg))
+
+ssize_t safe_msgrcv(const char *file, const int lineno, int msqid, void *msgp,
+		size_t msgsz, long msgtyp, int msgflg);
+#define SAFE_MSGRCV(msqid, msgp, msgsz, msgtyp, msgflg) \
+	safe_msgrcv(__FILE__, __LINE__, (msqid), (msgp), (msgsz), (msgtyp), (msgflg))
+
+int safe_msgctl(const char *file, const int lineno, int msqid, int cmd,
+		struct msqid_ds *buf);
+#define SAFE_MSGCTL(msqid, cmd, buf) \
+	safe_msgctl(__FILE__, __LINE__, (msqid), (cmd), (buf))
+
+#endif
include/tst_test.h +1 -0
index acb4b93..c68d880 100644
@@ -34,6 +34,7 @@
 #include "tst_kvercmp.h"
 #include "tst_clone.h"
 #include "tst_kernel.h"
+#include "tst_safe_sysv_ipc.h"
 
 /*
  * Reports testcase result.
lib/tst_safe_sysv_ipc.c new file +78 -0

78 lines not on this page · raw message

Signature · 1 line
1.8.3.1
author
#6 lore raw

PATCH v2 2/3 ipc/msgget0*: Make use of IPC related macros

---
 testcases/kernel/syscalls/ipc/msgget/msgget01.c | 6 ++----
 testcases/kernel/syscalls/ipc/msgget/msgget02.c | 4 +---
 2 files changed, 3 insertions(+), 7 deletions(-)
testcases/kernel/syscalls/ipc/msgget/msgget01.c +2 -4
index 8d2db4d..e19e0da 100644
@@ -48,11 +48,9 @@ static void verify_msgget(void)
 
 	queue_id = TEST_RETURN;
 
-	if (msgsnd(queue_id, &snd_buf, MSGSIZE, 0) == -1)
-		tst_brk(TBROK | TERRNO, "msgsnd() failed");
+	SAFE_MSGSND(queue_id, &snd_buf, MSGSIZE, 0);
 
-	if (msgrcv(queue_id, &rcv_buf, MSGSIZE, MSGTYPE, IPC_NOWAIT) == -1)
-		tst_brk(TBROK | TERRNO, "msgrcv() failed");
+	SAFE_MSGRCV(queue_id, &rcv_buf, MSGSIZE, MSGTYPE, IPC_NOWAIT);
 
 	if (strcmp(snd_buf.text, rcv_buf.text) == 0)
 		tst_res(TPASS, "message received = message sent");
testcases/kernel/syscalls/ipc/msgget/msgget02.c +1 -3
index a3fcb38..d5e2820 100644
@@ -96,9 +96,7 @@ static void setup(void)
 	msgkey = GETIPCKEY();
 	msgkey1 = GETIPCKEY();
 
-	queue_id = msgget(msgkey, IPC_CREAT | IPC_EXCL);
-	if (queue_id == -1)
-		tst_brk(TBROK | TERRNO, "can't create message queue");
+	queue_id = SAFE_MSGGET(msgkey, IPC_CREAT | IPC_EXCL);
 
 	pw = SAFE_GETPWNAM("nobody");
 }
Signature · 1 line
1.8.3.1
#7 lore raw

PATCH v2 2/3 ipc/msgget0*: Make use of IPC related macros

Hi!
I've changed these two test to include the tst_safe_sysv_ipc.h header and pushed, thanks.

Signature · 2 lines
Cyril Hrubis
[email protected]
author
#8 lore raw

PATCH v2 3/3 ipc/msgsnd0*: cleanup && convert to new API

In reply to Xiao Yang

1) The msgsnd03 was merged into msgsnd02
2) The msgsnd04 was merged into msgsnd05
3) take use of IPC related macros

---
 runtest/ltplite                                    |   2 -
 runtest/stress.part3                               |   2 -
 runtest/syscalls                                   |   2 -
 runtest/syscalls-ipc                               |   2 -
 testcases/kernel/syscalls/.gitignore               |   2 -
 .../kernel/syscalls/ipc/msgsnd/.msgsnd02.c.swo     | Bin 0 -> 12288 bytes
 testcases/kernel/syscalls/ipc/msgsnd/Makefile      |  29 ++-
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c    | 196 ++++----------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c    | 255 ++++++++----------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c    | 178 -------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c    | 155 -----------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c    | 287 +++++++--------------
 testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c    | 252 +++++-------------
 13 files changed, 326 insertions(+), 1036 deletions(-)
 create mode 100644 testcases/kernel/syscalls/ipc/msgsnd/.msgsnd02.c.swo
 delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c
 delete mode 100644 testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c
runtest/ltplite +0 -2
index 83141d1..d4580ad 100644
@@ -514,8 +514,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/stress.part3 +0 -2
index fcf27d0..41f8b25 100644
@@ -429,8 +429,6 @@ msgrcv07 msgrcv07
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/syscalls +0 -2
index 884ab80..dd9f9a9 100644
@@ -693,8 +693,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
runtest/syscalls-ipc +0 -2
index 8212222..91060b9 100644
@@ -27,8 +27,6 @@ msgrcv08 msgrcv08
 
 msgsnd01 msgsnd01
 msgsnd02 msgsnd02
-msgsnd03 msgsnd03
-msgsnd04 msgsnd04
 msgsnd05 msgsnd05
 msgsnd06 msgsnd06
 
testcases/kernel/syscalls/.gitignore +0 -2
index 3201fa9..84c7977 100644
@@ -414,8 +414,6 @@
 /ipc/msgrcv/msgrcv08
 /ipc/msgsnd/msgsnd01
 /ipc/msgsnd/msgsnd02
-/ipc/msgsnd/msgsnd03
-/ipc/msgsnd/msgsnd04
 /ipc/msgsnd/msgsnd05
 /ipc/msgsnd/msgsnd06
 /ipc/semctl/semctl01
testcases/kernel/syscalls/ipc/msgsnd/.msgsnd02.c.swo new file binary +0 -0
new file mode 100644
index 0000000000000000000000000000000000000000..f916bda9a903750736dfb29f914eb3fd68f7c09b
GIT binary patch
testcases/kernel/syscalls/ipc/msgsnd/Makefile +16 -13
index f467389..207fb16 100644
@@ -1,23 +1,26 @@
 #
-#  Copyright (c) International Business Machines  Corp., 2001
+# Copyright (c) International Business Machines  Corp., 2001
 #
-#  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 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.
+# 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+# You should have received a copy of the GNU General Public License
+# along with this program.
 #
 
 top_srcdir              ?= ../../../../..
 
+ifeq ($(UCLINUX),1)
+FILTER_OUT_MAKE_TARGETS += msgsnd05 msgsnd06
+endif
+
 include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
+include $(abs_srcdir)/../Makefile2.inc
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +53 -143

222 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +107 -148

282 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd03.c deleted +0 -178

178 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd04.c deleted +0 -155

155 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +90 -197

324 lines not on this page · raw message

testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +60 -192

282 lines not on this page · raw message

Signature · 1 line
1.8.3.1
#9 lore raw

PATCH v2 3/3 ipc/msgsnd0*: cleanup && convert to new API

Hi!

testcases/kernel/syscalls/ipc/msgsnd/.msgsnd02.c.swo

Quoted 2 lines
testcases/kernel/syscalls/ipc/msgsnd/.msgsnd02.c.swo new file +0 -0
new file mode 100644

I've removed this file, as it was included in the commit by accident.

And I've also modified the SAFE_MSGCTL() to set the msqid to -1 on cmd == IPC_RMID (similarily what we do for fd for SAFE_CLOSE()). Since with that we can safely add a cleanup() to the msgsnd06 that removes the queue if the test exits with TBROK somewhere between the queue being created and removed.

Pushed with this diff:

testcases/kernel/syscalls/ipc/msgsnd/msgsnd01.c +1 -0
index 49aaf1f..7101bdb 100644
@@ -26,6 +26,7 @@
 #include <sys/msg.h>
 
 #include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
 #include "libnewipc.h"
 
 static key_t msgkey;
testcases/kernel/syscalls/ipc/msgsnd/msgsnd02.c +1 -0
index 219d40f..5bdc6c8 100644
@@ -39,6 +39,7 @@
 #include <pwd.h>
 
 #include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
 #include "libnewipc.h"
 
 static key_t msgkey;
testcases/kernel/syscalls/ipc/msgsnd/msgsnd05.c +2 -2
index 42c89a8..3d13f3e 100644
@@ -31,6 +31,7 @@
 #include <sys/msg.h>
 
 #include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
 #include "libnewipc.h"
 
 static key_t msgkey;
@@ -86,6 +87,7 @@ static void do_test(unsigned int n)
 
 	pid = SAFE_FORK();
 	if (!pid) {
+		SAFE_SIGNAL(SIGHUP, sighandler);
 		verify_msgsnd(tc);
 		_exit(0);
 	}
@@ -97,8 +99,6 @@ static void do_test(unsigned int n)
 
 static void setup(void)
 {
-	SAFE_SIGNAL(SIGHUP, sighandler);
-
 	msgkey = GETIPCKEY();
 
 	queue_id = SAFE_MSGGET(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW);
testcases/kernel/syscalls/ipc/msgsnd/msgsnd06.c +10 -0
index 2436481..787cf97 100644
@@ -28,6 +28,7 @@
 #include <sys/msg.h>
 
 #include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
 #include "libnewipc.h"
 
 static key_t msgkey;
@@ -80,11 +81,20 @@ static void setup(void)
 	msgkey = GETIPCKEY();
 }
 
+static void cleanup(void)
+{
+	if (queue_id != -1 && msgctl(queue_id, IPC_RMID, NULL)) {
+		tst_res(TWARN | TERRNO, "failed to delete message queue %i",
+			queue_id);
+	}
+}
+
 static struct tst_test test = {
 	.tid = "msgsnd06",
 	.needs_tmpdir = 1,
 	.needs_root = 1,
 	.forks_child = 1,
 	.setup = setup,
+	.cleanup = cleanup,
 	.test_all = do_test
 };

Thanks!

Signature · 2 lines
Cyril Hrubis
[email protected]
#10 lore raw

PATCH v2 1/3 lib/tst_safe_sysv_ipc.c : Add tst_safe_sysv_ipc.c

In reply to Xiao Yang

Hi!

include/tst_test.h line 37

Quoted 9 lines
include/tst_test.h +1 -0
index acb4b93..c68d880 100644
@@ -34,6 +34,7 @@
 #include "tst_kvercmp.h"
 #include "tst_clone.h"
 #include "tst_kernel.h"
+#include "tst_safe_sysv_ipc.h"

I've removed this include from the tst_test.h since the tst_test.h header is polluted enough already and these safe macros would be used only by a very small number of tests anyway.

include/tst_test.h

Quoted 8 lines
include/tst_test.h +8 -0
+int safe_msgget(const char *file, const int lineno, key_t key, int msgflg)
+{
+	int rval;
+
+	rval = msgget(key, msgflg);
+	if (rval == -1) {
+		tst_brk(TBROK | TERRNO, "%s:%d: msgget() failed",
+			file, lineno);

And I've also changed these tst_brk() messages to print the parameters passed to the msg*() functions as well in order to provide as much information as possible.

include/tst_test.h

Quoted 4 lines
include/tst_test.h +4 -0
+	}
+
+	return rval;
+}

And pushed, thanks.

Signature · 2 lines
Cyril Hrubis
[email protected]