191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni/*
291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * Check decoding of wait4 syscall.
391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *
491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * All rights reserved.
691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *
791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * Redistribution and use in source and binary forms, with or without
891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * modification, are permitted provided that the following conditions
991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * are met:
1091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * 1. Redistributions of source code must retain the above copyright
1191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *    notice, this list of conditions and the following disclaimer.
1291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * 2. Redistributions in binary form must reproduce the above copyright
1391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *    notice, this list of conditions and the following disclaimer in the
1491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *    documentation and/or other materials provided with the distribution.
1591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * 3. The name of the author may not be used to endorse or promote products
1691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *    derived from this software without specific prior written permission.
1791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni *
1891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni */
2991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
3091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include "tests.h"
3191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <assert.h>
3291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <signal.h>
3391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <stdio.h>
3491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <unistd.h>
3591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <sys/wait.h>
3691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <sys/resource.h>
3791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
3891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nistatic const char *
3991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nisprint_rusage(const struct rusage *const ru)
4091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni{
4191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	static char buf[1024];
4291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	snprintf(buf, sizeof(buf),
4391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 "{ru_utime={tv_sec=%lu, tv_usec=%lu}"
4491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_stime={tv_sec=%lu, tv_usec=%lu}"
4591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#if VERBOSE
4691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_maxrss=%lu"
4791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_ixrss=%lu"
4891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_idrss=%lu"
4991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_isrss=%lu"
5091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_minflt=%lu"
5191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_majflt=%lu"
5291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_nswap=%lu"
5391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_inblock=%lu"
5491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_oublock=%lu"
5591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_msgsnd=%lu"
5691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_msgrcv=%lu"
5791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_nsignals=%lu"
5891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_nvcsw=%lu"
5991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ru_nivcsw=%lu}"
6091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#else
6191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 ", ...}"
6291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#endif
6391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_utime.tv_sec
6491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_utime.tv_usec
6591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_stime.tv_sec
6691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_stime.tv_usec
6791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#if VERBOSE
6891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_maxrss
6991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_ixrss
7091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_idrss
7191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_isrss
7291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_minflt
7391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_majflt
7491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_nswap
7591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_inblock
7691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_oublock
7791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_msgsnd
7891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_msgrcv
7991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_nsignals
8091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_nvcsw
8191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 , (long) ru->ru_nivcsw
8291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#endif
8391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		 );
8491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	return buf;
8591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni}
8691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
8791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nistatic pid_t
8891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nido_wait4(pid_t pid, int *wstatus, int options, struct rusage *ru)
8991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni{
9091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	sigset_t mask = {};
9191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	sigaddset(&mask, SIGCHLD);
9291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
9391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
9491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	pid_t rc = wait4(pid, wstatus, options, ru);
9591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(sigprocmask(SIG_UNBLOCK, &mask, NULL) == 0);
9691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	return rc;
9791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni}
9891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
9991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Niint
10091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nimain(void)
10191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni{
10291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("%s", "");
10391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
10491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	int fds[2];
10591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (pipe(fds))
10691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("pipe");
10791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
10891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	pid_t pid;
10991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	pid = fork();
11091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (pid < 0)
11191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("fork");
11291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
11391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (!pid) {
11491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		char c;
11591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		(void) close(1);
11691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		assert(read(0, &c, sizeof(c)) == 1);
11791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		return 42;
11891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	}
11991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
12091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	(void) close(0);
12191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
12291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	int *const s = tail_alloc(sizeof(*s));
12391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (wait4(pid, s, WNOHANG|__WALL, NULL))
12491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("wait4 #1");
12591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, %p, WNOHANG|__WALL, NULL) = 0\n", pid, s);
12691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
12791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	struct rusage *const rusage = tail_alloc(sizeof(*rusage));
12891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (wait4(pid, s, WNOHANG|__WALL, rusage))
12991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("wait4 #2");
13091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, %p, WNOHANG|__WALL, %p) = 0\n", pid, s, rusage);
13191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
13291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(write(1, "", 1) == 1);
13391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	(void) close(1);
13491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
13591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(do_wait4(pid, s, 0, rusage) == pid);
13691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(WIFEXITED(*s) && WEXITSTATUS(*s) == 42);
13791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, [{WIFEXITED(s) && WEXITSTATUS(s) == 42}], 0, %s)"
13891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		" = %d\n", pid, sprint_rusage(rusage), pid);
13991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
14091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	pid = fork();
14191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (pid < 0)
14291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("fork");
14391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
14491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (!pid) {
14591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		(void) raise(SIGUSR1);
14691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		return 1;
14791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	}
14891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
14991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(do_wait4(pid, s, __WALL, rusage) == pid);
15091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(WIFSIGNALED(*s) && WTERMSIG(*s) == SIGUSR1);
15191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1}]"
15291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		", __WALL, %s) = %d\n", pid, sprint_rusage(rusage), pid);
15391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
15491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (pipe(fds))
15591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("pipe");
15691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	pid = fork();
15791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (pid < 0)
15891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("fork");
15991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
16091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (!pid) {
16191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		(void) close(1);
16291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		raise(SIGSTOP);
16391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		char c;
16491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		assert(read(0, &c, sizeof(c)) == 1);
16591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		return 0;
16691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	}
16791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
16891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	(void) close(0);
16991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
17091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(do_wait4(pid, s, WSTOPPED, rusage) == pid);
17191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(WIFSTOPPED(*s) && WSTOPSIG(*s) == SIGSTOP);
17291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGSTOP}]"
17391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		", WSTOPPED, %s) = %d\n", pid, sprint_rusage(rusage), pid);
17491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
17591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	if (kill(pid, SIGCONT))
17691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		perror_msg_and_fail("kill(SIGCONT)");
17791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
17891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#if defined WCONTINUED && defined WIFCONTINUED
17991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(do_wait4(pid, s, WCONTINUED, rusage) == pid);
18091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(WIFCONTINUED(*s));
18191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, [{WIFCONTINUED(s)}], WCONTINUED"
18291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		", %s) = %d\n", pid, sprint_rusage(rusage), pid);
18391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#endif /* WCONTINUED && WIFCONTINUED */
18491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
18591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(write(1, "", 1) == 1);
18691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	(void) close(1);
18791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
18891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(do_wait4(pid, s, 0, rusage) == pid);
18991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(WIFEXITED(*s) && WEXITSTATUS(*s) == 0);
19091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(%d, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0"
19191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		", %s) = %d\n", pid, sprint_rusage(rusage), pid);
19291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
19391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	assert(wait4(-1, s, WNOHANG|WSTOPPED|__WALL, rusage) == -1);
19491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("wait4(-1, %p, WNOHANG|WSTOPPED|__WALL, %p) = -1 %s (%m)\n",
19591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni		s, rusage, errno2name());
19691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
19791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	tprintf("%s\n", "+++ exited with 0 +++");
19891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni	return 0;
19991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni}
20091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni