xref: /netbsd/tests/lib/libc/sys/t_msgctl.c (revision 1a54b3c7)
1*1a54b3c7Skre /* $NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $ */
23440ea09Sjruoho 
33440ea09Sjruoho /*-
43440ea09Sjruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
53440ea09Sjruoho  * All rights reserved.
63440ea09Sjruoho  *
73440ea09Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
83440ea09Sjruoho  * by Jukka Ruohonen.
93440ea09Sjruoho  *
103440ea09Sjruoho  * Redistribution and use in source and binary forms, with or without
113440ea09Sjruoho  * modification, are permitted provided that the following conditions
123440ea09Sjruoho  * are met:
133440ea09Sjruoho  * 1. Redistributions of source code must retain the above copyright
143440ea09Sjruoho  *    notice, this list of conditions and the following disclaimer.
153440ea09Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
163440ea09Sjruoho  *    notice, this list of conditions and the following disclaimer in the
173440ea09Sjruoho  *    documentation and/or other materials provided with the distribution.
183440ea09Sjruoho  *
193440ea09Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
203440ea09Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
213440ea09Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223440ea09Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
233440ea09Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
243440ea09Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
253440ea09Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
263440ea09Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
273440ea09Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
283440ea09Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
293440ea09Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
303440ea09Sjruoho  */
313440ea09Sjruoho #include <sys/cdefs.h>
32*1a54b3c7Skre __RCSID("$NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $");
333440ea09Sjruoho 
343440ea09Sjruoho #include <sys/msg.h>
353440ea09Sjruoho #include <sys/stat.h>
363440ea09Sjruoho #include <sys/sysctl.h>
373440ea09Sjruoho #include <sys/wait.h>
383440ea09Sjruoho 
393440ea09Sjruoho #include <atf-c.h>
403440ea09Sjruoho #include <errno.h>
417f3cf0deSchristos #include <limits.h>
423440ea09Sjruoho #include <pwd.h>
438484134bSkre #include <signal.h>
443440ea09Sjruoho #include <stdio.h>
453440ea09Sjruoho #include <stdlib.h>
463440ea09Sjruoho #include <string.h>
473440ea09Sjruoho #include <sysexits.h>
483440ea09Sjruoho #include <time.h>
493440ea09Sjruoho #include <unistd.h>
503440ea09Sjruoho 
513440ea09Sjruoho #define MSG_KEY		12345689
523440ea09Sjruoho #define MSG_MTYPE_1	0x41
533440ea09Sjruoho 
543440ea09Sjruoho struct msg {
553440ea09Sjruoho 	long		 mtype;
563440ea09Sjruoho 	char		 buf[3];
573440ea09Sjruoho };
583440ea09Sjruoho 
593440ea09Sjruoho static void		clean(void);
603440ea09Sjruoho 
613440ea09Sjruoho static void
clean(void)623440ea09Sjruoho clean(void)
633440ea09Sjruoho {
643440ea09Sjruoho 	int id;
653440ea09Sjruoho 
663440ea09Sjruoho 	if ((id = msgget(MSG_KEY, 0)) != -1)
673440ea09Sjruoho 		(void)msgctl(id, IPC_RMID, 0);
683440ea09Sjruoho }
693440ea09Sjruoho 
703440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_err);
ATF_TC_HEAD(msgctl_err,tc)713440ea09Sjruoho ATF_TC_HEAD(msgctl_err, tc)
723440ea09Sjruoho {
733440ea09Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
743440ea09Sjruoho }
753440ea09Sjruoho 
ATF_TC_BODY(msgctl_err,tc)763440ea09Sjruoho ATF_TC_BODY(msgctl_err, tc)
773440ea09Sjruoho {
783440ea09Sjruoho 	const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
793440ea09Sjruoho 	struct msqid_ds msgds;
803440ea09Sjruoho 	size_t i;
813440ea09Sjruoho 	int id;
823440ea09Sjruoho 
833440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
843440ea09Sjruoho 
853440ea09Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
863440ea09Sjruoho 	ATF_REQUIRE(id != -1);
873440ea09Sjruoho 
883440ea09Sjruoho 	errno = 0;
893440ea09Sjruoho 	ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
903440ea09Sjruoho 
913440ea09Sjruoho 	errno = 0;
923440ea09Sjruoho 	ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
933440ea09Sjruoho 
943440ea09Sjruoho 	for (i = 0; i < __arraycount(cmd); i++) {
953440ea09Sjruoho 		errno = 0;
963440ea09Sjruoho 		ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
973440ea09Sjruoho 	}
983440ea09Sjruoho 
993440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
1003440ea09Sjruoho }
1013440ea09Sjruoho 
ATF_TC_CLEANUP(msgctl_err,tc)1023440ea09Sjruoho ATF_TC_CLEANUP(msgctl_err, tc)
1033440ea09Sjruoho {
1043440ea09Sjruoho 	clean();
1053440ea09Sjruoho }
1063440ea09Sjruoho 
1073440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_perm);
ATF_TC_HEAD(msgctl_perm,tc)1083440ea09Sjruoho ATF_TC_HEAD(msgctl_perm, tc)
1093440ea09Sjruoho {
11085177a7aSjruoho 	atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
1113440ea09Sjruoho 	atf_tc_set_md_var(tc, "require.user", "root");
1123440ea09Sjruoho }
1133440ea09Sjruoho 
ATF_TC_BODY(msgctl_perm,tc)1143440ea09Sjruoho ATF_TC_BODY(msgctl_perm, tc)
1153440ea09Sjruoho {
1163440ea09Sjruoho 	struct msqid_ds msgds;
1173440ea09Sjruoho 	struct passwd *pw;
1183440ea09Sjruoho 	pid_t pid;
1193440ea09Sjruoho 	int sta;
1203440ea09Sjruoho 	int id;
1213440ea09Sjruoho 
1223440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
1233440ea09Sjruoho 
1243440ea09Sjruoho 	pw = getpwnam("nobody");
1253440ea09Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
1263440ea09Sjruoho 
1273440ea09Sjruoho 	ATF_REQUIRE(id != -1);
1283440ea09Sjruoho 	ATF_REQUIRE(pw != NULL);
1293440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
1303440ea09Sjruoho 
1313440ea09Sjruoho 	pid = fork();
1323440ea09Sjruoho 	ATF_REQUIRE(pid >= 0);
1333440ea09Sjruoho 
1343440ea09Sjruoho 	if (pid == 0) {
1353440ea09Sjruoho 
1363440ea09Sjruoho 		if (setuid(pw->pw_uid) != 0)
1373440ea09Sjruoho 			_exit(EX_OSERR);
1383440ea09Sjruoho 
1393440ea09Sjruoho 		msgds.msg_perm.uid = getuid();
1403440ea09Sjruoho 		msgds.msg_perm.gid = getgid();
1413440ea09Sjruoho 
1423440ea09Sjruoho 		errno = 0;
1433440ea09Sjruoho 
1443440ea09Sjruoho 		if (msgctl(id, IPC_SET, &msgds) == 0)
1453440ea09Sjruoho 			_exit(EXIT_FAILURE);
1463440ea09Sjruoho 
1473440ea09Sjruoho 		if (errno != EPERM)
1483440ea09Sjruoho 			_exit(EXIT_FAILURE);
1493440ea09Sjruoho 
1503440ea09Sjruoho 		(void)memset(&msgds, 0, sizeof(struct msqid_ds));
1513440ea09Sjruoho 
1523440ea09Sjruoho 		if (msgctl(id, IPC_STAT, &msgds) != 0)
1533440ea09Sjruoho 			_exit(EX_OSERR);
1543440ea09Sjruoho 
1553440ea09Sjruoho 		msgds.msg_qbytes = 1;
1563440ea09Sjruoho 
1573440ea09Sjruoho 		if (msgctl(id, IPC_SET, &msgds) == 0)
1583440ea09Sjruoho 			_exit(EXIT_FAILURE);
1593440ea09Sjruoho 
1603440ea09Sjruoho 		if (errno != EPERM)
1613440ea09Sjruoho 			_exit(EXIT_FAILURE);
1623440ea09Sjruoho 
1633440ea09Sjruoho 		_exit(EXIT_SUCCESS);
1643440ea09Sjruoho 	}
1653440ea09Sjruoho 
1663440ea09Sjruoho 	(void)wait(&sta);
1673440ea09Sjruoho 
1683440ea09Sjruoho 	if (WIFEXITED(sta) == 0) {
1693440ea09Sjruoho 
1703440ea09Sjruoho 		if (WEXITSTATUS(sta) == EX_OSERR)
1713440ea09Sjruoho 			atf_tc_fail("system call failed");
1723440ea09Sjruoho 
1733440ea09Sjruoho 		if (WEXITSTATUS(sta) == EXIT_FAILURE)
1743440ea09Sjruoho 			atf_tc_fail("UID %u manipulated root's "
1753440ea09Sjruoho 			    "message queue", pw->pw_uid);
1763440ea09Sjruoho 	}
1773440ea09Sjruoho 
1783440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
1793440ea09Sjruoho }
1803440ea09Sjruoho 
ATF_TC_CLEANUP(msgctl_perm,tc)1813440ea09Sjruoho ATF_TC_CLEANUP(msgctl_perm, tc)
1823440ea09Sjruoho {
1833440ea09Sjruoho 	clean();
1843440ea09Sjruoho }
1853440ea09Sjruoho 
1863440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_pid);
ATF_TC_HEAD(msgctl_pid,tc)1873440ea09Sjruoho ATF_TC_HEAD(msgctl_pid, tc)
1883440ea09Sjruoho {
1893440ea09Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
1903440ea09Sjruoho }
1913440ea09Sjruoho 
ATF_TC_BODY(msgctl_pid,tc)1923440ea09Sjruoho ATF_TC_BODY(msgctl_pid, tc)
1933440ea09Sjruoho {
1943440ea09Sjruoho 	struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
1953440ea09Sjruoho 	struct msqid_ds msgds;
1963440ea09Sjruoho 	int id, sta;
1973440ea09Sjruoho 	pid_t pid;
1983440ea09Sjruoho 
1993440ea09Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
2003440ea09Sjruoho 	ATF_REQUIRE(id != -1);
2013440ea09Sjruoho 
2023440ea09Sjruoho 	pid = fork();
2033440ea09Sjruoho 	ATF_REQUIRE(pid >= 0);
2043440ea09Sjruoho 
2053440ea09Sjruoho 	if (pid == 0) {
2063440ea09Sjruoho 
2073440ea09Sjruoho 		(void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
2083440ea09Sjruoho 
2093440ea09Sjruoho 		_exit(EXIT_SUCCESS);
2103440ea09Sjruoho 	}
2113440ea09Sjruoho 
2123440ea09Sjruoho 	(void)sleep(1);
2133440ea09Sjruoho 	(void)wait(&sta);
2143440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
2153440ea09Sjruoho 
2163440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2173440ea09Sjruoho 
2183440ea09Sjruoho 	if (pid != msgds.msg_lspid)
2193440ea09Sjruoho 		atf_tc_fail("the PID of last msgsnd(2) was not updated");
2203440ea09Sjruoho 
2213440ea09Sjruoho 	pid = fork();
2223440ea09Sjruoho 	ATF_REQUIRE(pid >= 0);
2233440ea09Sjruoho 
2243440ea09Sjruoho 	if (pid == 0) {
2253440ea09Sjruoho 
2263440ea09Sjruoho 		(void)msgrcv(id, &msg,
2273440ea09Sjruoho 		    sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
2283440ea09Sjruoho 
2293440ea09Sjruoho 		_exit(EXIT_SUCCESS);
2303440ea09Sjruoho 	}
2313440ea09Sjruoho 
2323440ea09Sjruoho 	(void)sleep(1);
2333440ea09Sjruoho 	(void)wait(&sta);
2343440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
2353440ea09Sjruoho 
2363440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2373440ea09Sjruoho 
2383440ea09Sjruoho 	if (pid != msgds.msg_lrpid)
2393440ea09Sjruoho 		atf_tc_fail("the PID of last msgrcv(2) was not updated");
2403440ea09Sjruoho 
2413440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
2423440ea09Sjruoho }
2433440ea09Sjruoho 
ATF_TC_CLEANUP(msgctl_pid,tc)2443440ea09Sjruoho ATF_TC_CLEANUP(msgctl_pid, tc)
2453440ea09Sjruoho {
2463440ea09Sjruoho 	clean();
2473440ea09Sjruoho }
2483440ea09Sjruoho 
2493440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_set);
ATF_TC_HEAD(msgctl_set,tc)2503440ea09Sjruoho ATF_TC_HEAD(msgctl_set, tc)
2513440ea09Sjruoho {
2523440ea09Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
2533440ea09Sjruoho 	atf_tc_set_md_var(tc, "require.user", "root");
2543440ea09Sjruoho }
2553440ea09Sjruoho 
ATF_TC_BODY(msgctl_set,tc)2563440ea09Sjruoho ATF_TC_BODY(msgctl_set, tc)
2573440ea09Sjruoho {
2583440ea09Sjruoho 	struct msqid_ds msgds;
2593440ea09Sjruoho 	struct passwd *pw;
2603440ea09Sjruoho 	int id;
2613440ea09Sjruoho 
2623440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
2633440ea09Sjruoho 
2643440ea09Sjruoho 	pw = getpwnam("nobody");
2653440ea09Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
2663440ea09Sjruoho 
2673440ea09Sjruoho 	ATF_REQUIRE(id != -1);
2683440ea09Sjruoho 	ATF_REQUIRE(pw != NULL);
2693440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
2703440ea09Sjruoho 
2713440ea09Sjruoho 	msgds.msg_perm.uid = pw->pw_uid;
2723440ea09Sjruoho 
2733440ea09Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
2743440ea09Sjruoho 		atf_tc_fail("root failed to change the UID of message queue");
2753440ea09Sjruoho 
2763440ea09Sjruoho 	msgds.msg_perm.uid = getuid();
2773440ea09Sjruoho 	msgds.msg_perm.gid = pw->pw_gid;
2783440ea09Sjruoho 
2793440ea09Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
2803440ea09Sjruoho 		atf_tc_fail("root failed to change the GID of message queue");
2813440ea09Sjruoho 
2823440ea09Sjruoho 	/*
2833a2bdf61Sjruoho 	 * Note: setting the qbytes to zero fails even as root.
2843440ea09Sjruoho 	 */
2853440ea09Sjruoho 	msgds.msg_qbytes = 1;
2863440ea09Sjruoho 	msgds.msg_perm.gid = getgid();
2873440ea09Sjruoho 
2883440ea09Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
2893440ea09Sjruoho 		atf_tc_fail("root failed to change qbytes of message queue");
2903440ea09Sjruoho 
2913440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
2923440ea09Sjruoho }
2933440ea09Sjruoho 
ATF_TC_CLEANUP(msgctl_set,tc)2943440ea09Sjruoho ATF_TC_CLEANUP(msgctl_set, tc)
2953440ea09Sjruoho {
2963440ea09Sjruoho 	clean();
2973440ea09Sjruoho }
2983440ea09Sjruoho 
2993440ea09Sjruoho ATF_TC_WITH_CLEANUP(msgctl_time);
ATF_TC_HEAD(msgctl_time,tc)3003440ea09Sjruoho ATF_TC_HEAD(msgctl_time, tc)
3013440ea09Sjruoho {
3023a2bdf61Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
3033440ea09Sjruoho }
3043440ea09Sjruoho 
ATF_TC_BODY(msgctl_time,tc)3053440ea09Sjruoho ATF_TC_BODY(msgctl_time, tc)
3063440ea09Sjruoho {
3073440ea09Sjruoho 	struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
3083440ea09Sjruoho 	struct msqid_ds msgds;
3093440ea09Sjruoho 	time_t t;
3103440ea09Sjruoho 	int id;
3113440ea09Sjruoho 
3123440ea09Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
3133440ea09Sjruoho 	ATF_REQUIRE(id != -1);
3143440ea09Sjruoho 
3153440ea09Sjruoho 	t = time(NULL);
3163440ea09Sjruoho 
3173440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
3183440ea09Sjruoho 	(void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
3193440ea09Sjruoho 	(void)msgctl(id, IPC_STAT, &msgds);
3203440ea09Sjruoho 
32161b6ad23Sjoerg 	if (llabs(t - msgds.msg_stime) > 1)
3223440ea09Sjruoho 		atf_tc_fail("time of last msgsnd(2) was not updated");
3233440ea09Sjruoho 
3243440ea09Sjruoho 	if (msgds.msg_rtime != 0)
3253440ea09Sjruoho 		atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
3263440ea09Sjruoho 
3273440ea09Sjruoho 	t = time(NULL);
3283440ea09Sjruoho 
3293440ea09Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
3303440ea09Sjruoho 	(void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
3313440ea09Sjruoho 	(void)msgctl(id, IPC_STAT, &msgds);
3323440ea09Sjruoho 
33361b6ad23Sjoerg 	if (llabs(t - msgds.msg_rtime) > 1)
3343440ea09Sjruoho 		atf_tc_fail("time of last msgrcv(2) was not updated");
3353440ea09Sjruoho 
3363440ea09Sjruoho 	/*
3373a2bdf61Sjruoho 	 * Note: this is non-zero even after the memset(3).
3383440ea09Sjruoho 	 */
3393440ea09Sjruoho 	if (msgds.msg_stime == 0)
3403440ea09Sjruoho 		atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
3413440ea09Sjruoho 
3423440ea09Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
3433440ea09Sjruoho }
3443440ea09Sjruoho 
ATF_TC_CLEANUP(msgctl_time,tc)3453440ea09Sjruoho ATF_TC_CLEANUP(msgctl_time, tc)
3463440ea09Sjruoho {
3473440ea09Sjruoho 	clean();
3483440ea09Sjruoho }
3493440ea09Sjruoho 
3508484134bSkre static volatile int sig_caught;
3518484134bSkre 
3528484134bSkre static void
sigsys_handler(int signum)3538484134bSkre sigsys_handler(int signum)
3548484134bSkre {
3558484134bSkre 
3568484134bSkre 	sig_caught = signum;
3578484134bSkre }
3588484134bSkre 
3598484134bSkre static int
no_kernel_sysvmsg(void)3608484134bSkre no_kernel_sysvmsg(void)
3618484134bSkre {
3628484134bSkre 	int id;
363*1a54b3c7Skre 	void (*osig)(int);
3648484134bSkre 
3658484134bSkre 	sig_caught = 0;
366*1a54b3c7Skre 	osig = signal(SIGSYS, sigsys_handler);
3678484134bSkre 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
3688484134bSkre 	if (sig_caught || id == -1)
3698484134bSkre 		return 1;
3708484134bSkre 
3718484134bSkre 	(void)msgctl(id, IPC_RMID, 0);
372*1a54b3c7Skre 	(void)signal(SIGSYS, osig);
3738484134bSkre 
3748484134bSkre 	return 0;
3758484134bSkre }
3768484134bSkre 
3778484134bSkre ATF_TC(msgctl_query);
ATF_TC_HEAD(msgctl_query,tc)3788484134bSkre ATF_TC_HEAD(msgctl_query, tc)
3798484134bSkre {
3808484134bSkre 	atf_tc_set_md_var(tc, "descr", "Skip msgctl_* tests - no SYSVMSG");
3818484134bSkre }
ATF_TC_BODY(msgctl_query,tc)3828484134bSkre ATF_TC_BODY(msgctl_query, tc)
3838484134bSkre {
3848484134bSkre 	atf_tc_skip("No SYSVMSG in kernel");
3858484134bSkre }
3868484134bSkre 
ATF_TP_ADD_TCS(tp)3873440ea09Sjruoho ATF_TP_ADD_TCS(tp)
3883440ea09Sjruoho {
3893440ea09Sjruoho 
3908484134bSkre 	if (no_kernel_sysvmsg()) {
3918484134bSkre 		ATF_TP_ADD_TC(tp, msgctl_query);
3928484134bSkre 	} else {
3933440ea09Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_err);
3943440ea09Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_perm);
3953440ea09Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_pid);
3963440ea09Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_set);
3973440ea09Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_time);
3988484134bSkre 	}
3993440ea09Sjruoho 
4003440ea09Sjruoho 	return atf_no_error();
4013440ea09Sjruoho }
402