xref: /netbsd-src/tests/lib/libc/sys/t_msgctl.c (revision 6618a9bf1f38af5e586d846dc683ef0f5ec8e713)
1*6618a9bfSkre /* $NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $ */
262a65142Sjruoho 
362a65142Sjruoho /*-
462a65142Sjruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
562a65142Sjruoho  * All rights reserved.
662a65142Sjruoho  *
762a65142Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
862a65142Sjruoho  * by Jukka Ruohonen.
962a65142Sjruoho  *
1062a65142Sjruoho  * Redistribution and use in source and binary forms, with or without
1162a65142Sjruoho  * modification, are permitted provided that the following conditions
1262a65142Sjruoho  * are met:
1362a65142Sjruoho  * 1. Redistributions of source code must retain the above copyright
1462a65142Sjruoho  *    notice, this list of conditions and the following disclaimer.
1562a65142Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
1662a65142Sjruoho  *    notice, this list of conditions and the following disclaimer in the
1762a65142Sjruoho  *    documentation and/or other materials provided with the distribution.
1862a65142Sjruoho  *
1962a65142Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2062a65142Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2162a65142Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2262a65142Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2362a65142Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2462a65142Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2562a65142Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2662a65142Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2762a65142Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2862a65142Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2962a65142Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
3062a65142Sjruoho  */
3162a65142Sjruoho #include <sys/cdefs.h>
32*6618a9bfSkre __RCSID("$NetBSD: t_msgctl.c,v 1.7 2017/10/07 17:15:44 kre Exp $");
3362a65142Sjruoho 
3462a65142Sjruoho #include <sys/msg.h>
3562a65142Sjruoho #include <sys/stat.h>
3662a65142Sjruoho #include <sys/sysctl.h>
3762a65142Sjruoho #include <sys/wait.h>
3862a65142Sjruoho 
3962a65142Sjruoho #include <atf-c.h>
4062a65142Sjruoho #include <errno.h>
4193538aecSchristos #include <limits.h>
4262a65142Sjruoho #include <pwd.h>
434ad1e3d9Skre #include <signal.h>
4462a65142Sjruoho #include <stdio.h>
4562a65142Sjruoho #include <stdlib.h>
4662a65142Sjruoho #include <string.h>
4762a65142Sjruoho #include <sysexits.h>
4862a65142Sjruoho #include <time.h>
4962a65142Sjruoho #include <unistd.h>
5062a65142Sjruoho 
5162a65142Sjruoho #define MSG_KEY		12345689
5262a65142Sjruoho #define MSG_MTYPE_1	0x41
5362a65142Sjruoho 
5462a65142Sjruoho struct msg {
5562a65142Sjruoho 	long		 mtype;
5662a65142Sjruoho 	char		 buf[3];
5762a65142Sjruoho };
5862a65142Sjruoho 
5962a65142Sjruoho static void		clean(void);
6062a65142Sjruoho 
6162a65142Sjruoho static void
clean(void)6262a65142Sjruoho clean(void)
6362a65142Sjruoho {
6462a65142Sjruoho 	int id;
6562a65142Sjruoho 
6662a65142Sjruoho 	if ((id = msgget(MSG_KEY, 0)) != -1)
6762a65142Sjruoho 		(void)msgctl(id, IPC_RMID, 0);
6862a65142Sjruoho }
6962a65142Sjruoho 
7062a65142Sjruoho ATF_TC_WITH_CLEANUP(msgctl_err);
ATF_TC_HEAD(msgctl_err,tc)7162a65142Sjruoho ATF_TC_HEAD(msgctl_err, tc)
7262a65142Sjruoho {
7362a65142Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
7462a65142Sjruoho }
7562a65142Sjruoho 
ATF_TC_BODY(msgctl_err,tc)7662a65142Sjruoho ATF_TC_BODY(msgctl_err, tc)
7762a65142Sjruoho {
7862a65142Sjruoho 	const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
7962a65142Sjruoho 	struct msqid_ds msgds;
8062a65142Sjruoho 	size_t i;
8162a65142Sjruoho 	int id;
8262a65142Sjruoho 
8362a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
8462a65142Sjruoho 
8562a65142Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
8662a65142Sjruoho 	ATF_REQUIRE(id != -1);
8762a65142Sjruoho 
8862a65142Sjruoho 	errno = 0;
8962a65142Sjruoho 	ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
9062a65142Sjruoho 
9162a65142Sjruoho 	errno = 0;
9262a65142Sjruoho 	ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
9362a65142Sjruoho 
9462a65142Sjruoho 	for (i = 0; i < __arraycount(cmd); i++) {
9562a65142Sjruoho 		errno = 0;
9662a65142Sjruoho 		ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
9762a65142Sjruoho 	}
9862a65142Sjruoho 
9962a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
10062a65142Sjruoho }
10162a65142Sjruoho 
ATF_TC_CLEANUP(msgctl_err,tc)10262a65142Sjruoho ATF_TC_CLEANUP(msgctl_err, tc)
10362a65142Sjruoho {
10462a65142Sjruoho 	clean();
10562a65142Sjruoho }
10662a65142Sjruoho 
10762a65142Sjruoho ATF_TC_WITH_CLEANUP(msgctl_perm);
ATF_TC_HEAD(msgctl_perm,tc)10862a65142Sjruoho ATF_TC_HEAD(msgctl_perm, tc)
10962a65142Sjruoho {
1108e19d927Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
11162a65142Sjruoho 	atf_tc_set_md_var(tc, "require.user", "root");
11262a65142Sjruoho }
11362a65142Sjruoho 
ATF_TC_BODY(msgctl_perm,tc)11462a65142Sjruoho ATF_TC_BODY(msgctl_perm, tc)
11562a65142Sjruoho {
11662a65142Sjruoho 	struct msqid_ds msgds;
11762a65142Sjruoho 	struct passwd *pw;
11862a65142Sjruoho 	pid_t pid;
11962a65142Sjruoho 	int sta;
12062a65142Sjruoho 	int id;
12162a65142Sjruoho 
12262a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
12362a65142Sjruoho 
12462a65142Sjruoho 	pw = getpwnam("nobody");
12562a65142Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
12662a65142Sjruoho 
12762a65142Sjruoho 	ATF_REQUIRE(id != -1);
12862a65142Sjruoho 	ATF_REQUIRE(pw != NULL);
12962a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
13062a65142Sjruoho 
13162a65142Sjruoho 	pid = fork();
13262a65142Sjruoho 	ATF_REQUIRE(pid >= 0);
13362a65142Sjruoho 
13462a65142Sjruoho 	if (pid == 0) {
13562a65142Sjruoho 
13662a65142Sjruoho 		if (setuid(pw->pw_uid) != 0)
13762a65142Sjruoho 			_exit(EX_OSERR);
13862a65142Sjruoho 
13962a65142Sjruoho 		msgds.msg_perm.uid = getuid();
14062a65142Sjruoho 		msgds.msg_perm.gid = getgid();
14162a65142Sjruoho 
14262a65142Sjruoho 		errno = 0;
14362a65142Sjruoho 
14462a65142Sjruoho 		if (msgctl(id, IPC_SET, &msgds) == 0)
14562a65142Sjruoho 			_exit(EXIT_FAILURE);
14662a65142Sjruoho 
14762a65142Sjruoho 		if (errno != EPERM)
14862a65142Sjruoho 			_exit(EXIT_FAILURE);
14962a65142Sjruoho 
15062a65142Sjruoho 		(void)memset(&msgds, 0, sizeof(struct msqid_ds));
15162a65142Sjruoho 
15262a65142Sjruoho 		if (msgctl(id, IPC_STAT, &msgds) != 0)
15362a65142Sjruoho 			_exit(EX_OSERR);
15462a65142Sjruoho 
15562a65142Sjruoho 		msgds.msg_qbytes = 1;
15662a65142Sjruoho 
15762a65142Sjruoho 		if (msgctl(id, IPC_SET, &msgds) == 0)
15862a65142Sjruoho 			_exit(EXIT_FAILURE);
15962a65142Sjruoho 
16062a65142Sjruoho 		if (errno != EPERM)
16162a65142Sjruoho 			_exit(EXIT_FAILURE);
16262a65142Sjruoho 
16362a65142Sjruoho 		_exit(EXIT_SUCCESS);
16462a65142Sjruoho 	}
16562a65142Sjruoho 
16662a65142Sjruoho 	(void)wait(&sta);
16762a65142Sjruoho 
16862a65142Sjruoho 	if (WIFEXITED(sta) == 0) {
16962a65142Sjruoho 
17062a65142Sjruoho 		if (WEXITSTATUS(sta) == EX_OSERR)
17162a65142Sjruoho 			atf_tc_fail("system call failed");
17262a65142Sjruoho 
17362a65142Sjruoho 		if (WEXITSTATUS(sta) == EXIT_FAILURE)
17462a65142Sjruoho 			atf_tc_fail("UID %u manipulated root's "
17562a65142Sjruoho 			    "message queue", pw->pw_uid);
17662a65142Sjruoho 	}
17762a65142Sjruoho 
17862a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
17962a65142Sjruoho }
18062a65142Sjruoho 
ATF_TC_CLEANUP(msgctl_perm,tc)18162a65142Sjruoho ATF_TC_CLEANUP(msgctl_perm, tc)
18262a65142Sjruoho {
18362a65142Sjruoho 	clean();
18462a65142Sjruoho }
18562a65142Sjruoho 
18662a65142Sjruoho ATF_TC_WITH_CLEANUP(msgctl_pid);
ATF_TC_HEAD(msgctl_pid,tc)18762a65142Sjruoho ATF_TC_HEAD(msgctl_pid, tc)
18862a65142Sjruoho {
18962a65142Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
19062a65142Sjruoho }
19162a65142Sjruoho 
ATF_TC_BODY(msgctl_pid,tc)19262a65142Sjruoho ATF_TC_BODY(msgctl_pid, tc)
19362a65142Sjruoho {
19462a65142Sjruoho 	struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
19562a65142Sjruoho 	struct msqid_ds msgds;
19662a65142Sjruoho 	int id, sta;
19762a65142Sjruoho 	pid_t pid;
19862a65142Sjruoho 
19962a65142Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
20062a65142Sjruoho 	ATF_REQUIRE(id != -1);
20162a65142Sjruoho 
20262a65142Sjruoho 	pid = fork();
20362a65142Sjruoho 	ATF_REQUIRE(pid >= 0);
20462a65142Sjruoho 
20562a65142Sjruoho 	if (pid == 0) {
20662a65142Sjruoho 
20762a65142Sjruoho 		(void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
20862a65142Sjruoho 
20962a65142Sjruoho 		_exit(EXIT_SUCCESS);
21062a65142Sjruoho 	}
21162a65142Sjruoho 
21262a65142Sjruoho 	(void)sleep(1);
21362a65142Sjruoho 	(void)wait(&sta);
21462a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
21562a65142Sjruoho 
21662a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
21762a65142Sjruoho 
21862a65142Sjruoho 	if (pid != msgds.msg_lspid)
21962a65142Sjruoho 		atf_tc_fail("the PID of last msgsnd(2) was not updated");
22062a65142Sjruoho 
22162a65142Sjruoho 	pid = fork();
22262a65142Sjruoho 	ATF_REQUIRE(pid >= 0);
22362a65142Sjruoho 
22462a65142Sjruoho 	if (pid == 0) {
22562a65142Sjruoho 
22662a65142Sjruoho 		(void)msgrcv(id, &msg,
22762a65142Sjruoho 		    sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
22862a65142Sjruoho 
22962a65142Sjruoho 		_exit(EXIT_SUCCESS);
23062a65142Sjruoho 	}
23162a65142Sjruoho 
23262a65142Sjruoho 	(void)sleep(1);
23362a65142Sjruoho 	(void)wait(&sta);
23462a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
23562a65142Sjruoho 
23662a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
23762a65142Sjruoho 
23862a65142Sjruoho 	if (pid != msgds.msg_lrpid)
23962a65142Sjruoho 		atf_tc_fail("the PID of last msgrcv(2) was not updated");
24062a65142Sjruoho 
24162a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
24262a65142Sjruoho }
24362a65142Sjruoho 
ATF_TC_CLEANUP(msgctl_pid,tc)24462a65142Sjruoho ATF_TC_CLEANUP(msgctl_pid, tc)
24562a65142Sjruoho {
24662a65142Sjruoho 	clean();
24762a65142Sjruoho }
24862a65142Sjruoho 
24962a65142Sjruoho ATF_TC_WITH_CLEANUP(msgctl_set);
ATF_TC_HEAD(msgctl_set,tc)25062a65142Sjruoho ATF_TC_HEAD(msgctl_set, tc)
25162a65142Sjruoho {
25262a65142Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
25362a65142Sjruoho 	atf_tc_set_md_var(tc, "require.user", "root");
25462a65142Sjruoho }
25562a65142Sjruoho 
ATF_TC_BODY(msgctl_set,tc)25662a65142Sjruoho ATF_TC_BODY(msgctl_set, tc)
25762a65142Sjruoho {
25862a65142Sjruoho 	struct msqid_ds msgds;
25962a65142Sjruoho 	struct passwd *pw;
26062a65142Sjruoho 	int id;
26162a65142Sjruoho 
26262a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
26362a65142Sjruoho 
26462a65142Sjruoho 	pw = getpwnam("nobody");
26562a65142Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
26662a65142Sjruoho 
26762a65142Sjruoho 	ATF_REQUIRE(id != -1);
26862a65142Sjruoho 	ATF_REQUIRE(pw != NULL);
26962a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
27062a65142Sjruoho 
27162a65142Sjruoho 	msgds.msg_perm.uid = pw->pw_uid;
27262a65142Sjruoho 
27362a65142Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
27462a65142Sjruoho 		atf_tc_fail("root failed to change the UID of message queue");
27562a65142Sjruoho 
27662a65142Sjruoho 	msgds.msg_perm.uid = getuid();
27762a65142Sjruoho 	msgds.msg_perm.gid = pw->pw_gid;
27862a65142Sjruoho 
27962a65142Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
28062a65142Sjruoho 		atf_tc_fail("root failed to change the GID of message queue");
28162a65142Sjruoho 
28262a65142Sjruoho 	/*
283fbcca3eaSjruoho 	 * Note: setting the qbytes to zero fails even as root.
28462a65142Sjruoho 	 */
28562a65142Sjruoho 	msgds.msg_qbytes = 1;
28662a65142Sjruoho 	msgds.msg_perm.gid = getgid();
28762a65142Sjruoho 
28862a65142Sjruoho 	if (msgctl(id, IPC_SET, &msgds) != 0)
28962a65142Sjruoho 		atf_tc_fail("root failed to change qbytes of message queue");
29062a65142Sjruoho 
29162a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
29262a65142Sjruoho }
29362a65142Sjruoho 
ATF_TC_CLEANUP(msgctl_set,tc)29462a65142Sjruoho ATF_TC_CLEANUP(msgctl_set, tc)
29562a65142Sjruoho {
29662a65142Sjruoho 	clean();
29762a65142Sjruoho }
29862a65142Sjruoho 
29962a65142Sjruoho ATF_TC_WITH_CLEANUP(msgctl_time);
ATF_TC_HEAD(msgctl_time,tc)30062a65142Sjruoho ATF_TC_HEAD(msgctl_time, tc)
30162a65142Sjruoho {
302fbcca3eaSjruoho 	atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
30362a65142Sjruoho }
30462a65142Sjruoho 
ATF_TC_BODY(msgctl_time,tc)30562a65142Sjruoho ATF_TC_BODY(msgctl_time, tc)
30662a65142Sjruoho {
30762a65142Sjruoho 	struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
30862a65142Sjruoho 	struct msqid_ds msgds;
30962a65142Sjruoho 	time_t t;
31062a65142Sjruoho 	int id;
31162a65142Sjruoho 
31262a65142Sjruoho 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
31362a65142Sjruoho 	ATF_REQUIRE(id != -1);
31462a65142Sjruoho 
31562a65142Sjruoho 	t = time(NULL);
31662a65142Sjruoho 
31762a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
31862a65142Sjruoho 	(void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
31962a65142Sjruoho 	(void)msgctl(id, IPC_STAT, &msgds);
32062a65142Sjruoho 
321f161b30dSjoerg 	if (llabs(t - msgds.msg_stime) > 1)
32262a65142Sjruoho 		atf_tc_fail("time of last msgsnd(2) was not updated");
32362a65142Sjruoho 
32462a65142Sjruoho 	if (msgds.msg_rtime != 0)
32562a65142Sjruoho 		atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
32662a65142Sjruoho 
32762a65142Sjruoho 	t = time(NULL);
32862a65142Sjruoho 
32962a65142Sjruoho 	(void)memset(&msgds, 0, sizeof(struct msqid_ds));
33062a65142Sjruoho 	(void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
33162a65142Sjruoho 	(void)msgctl(id, IPC_STAT, &msgds);
33262a65142Sjruoho 
333f161b30dSjoerg 	if (llabs(t - msgds.msg_rtime) > 1)
33462a65142Sjruoho 		atf_tc_fail("time of last msgrcv(2) was not updated");
33562a65142Sjruoho 
33662a65142Sjruoho 	/*
337fbcca3eaSjruoho 	 * Note: this is non-zero even after the memset(3).
33862a65142Sjruoho 	 */
33962a65142Sjruoho 	if (msgds.msg_stime == 0)
34062a65142Sjruoho 		atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
34162a65142Sjruoho 
34262a65142Sjruoho 	ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
34362a65142Sjruoho }
34462a65142Sjruoho 
ATF_TC_CLEANUP(msgctl_time,tc)34562a65142Sjruoho ATF_TC_CLEANUP(msgctl_time, tc)
34662a65142Sjruoho {
34762a65142Sjruoho 	clean();
34862a65142Sjruoho }
34962a65142Sjruoho 
3504ad1e3d9Skre static volatile int sig_caught;
3514ad1e3d9Skre 
3524ad1e3d9Skre static void
sigsys_handler(int signum)3534ad1e3d9Skre sigsys_handler(int signum)
3544ad1e3d9Skre {
3554ad1e3d9Skre 
3564ad1e3d9Skre 	sig_caught = signum;
3574ad1e3d9Skre }
3584ad1e3d9Skre 
3594ad1e3d9Skre static int
no_kernel_sysvmsg(void)3604ad1e3d9Skre no_kernel_sysvmsg(void)
3614ad1e3d9Skre {
3624ad1e3d9Skre 	int id;
363*6618a9bfSkre 	void (*osig)(int);
3644ad1e3d9Skre 
3654ad1e3d9Skre 	sig_caught = 0;
366*6618a9bfSkre 	osig = signal(SIGSYS, sigsys_handler);
3674ad1e3d9Skre 	id = msgget(MSG_KEY, IPC_CREAT | 0600);
3684ad1e3d9Skre 	if (sig_caught || id == -1)
3694ad1e3d9Skre 		return 1;
3704ad1e3d9Skre 
3714ad1e3d9Skre 	(void)msgctl(id, IPC_RMID, 0);
372*6618a9bfSkre 	(void)signal(SIGSYS, osig);
3734ad1e3d9Skre 
3744ad1e3d9Skre 	return 0;
3754ad1e3d9Skre }
3764ad1e3d9Skre 
3774ad1e3d9Skre ATF_TC(msgctl_query);
ATF_TC_HEAD(msgctl_query,tc)3784ad1e3d9Skre ATF_TC_HEAD(msgctl_query, tc)
3794ad1e3d9Skre {
3804ad1e3d9Skre 	atf_tc_set_md_var(tc, "descr", "Skip msgctl_* tests - no SYSVMSG");
3814ad1e3d9Skre }
ATF_TC_BODY(msgctl_query,tc)3824ad1e3d9Skre ATF_TC_BODY(msgctl_query, tc)
3834ad1e3d9Skre {
3844ad1e3d9Skre 	atf_tc_skip("No SYSVMSG in kernel");
3854ad1e3d9Skre }
3864ad1e3d9Skre 
ATF_TP_ADD_TCS(tp)38762a65142Sjruoho ATF_TP_ADD_TCS(tp)
38862a65142Sjruoho {
38962a65142Sjruoho 
3904ad1e3d9Skre 	if (no_kernel_sysvmsg()) {
3914ad1e3d9Skre 		ATF_TP_ADD_TC(tp, msgctl_query);
3924ad1e3d9Skre 	} else {
39362a65142Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_err);
39462a65142Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_perm);
39562a65142Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_pid);
39662a65142Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_set);
39762a65142Sjruoho 		ATF_TP_ADD_TC(tp, msgctl_time);
3984ad1e3d9Skre 	}
39962a65142Sjruoho 
40062a65142Sjruoho 	return atf_no_error();
40162a65142Sjruoho }
402