Home | History | Annotate | Download | only in tests-m32
      1 /*
      2  * Check SIGCHLD siginfo_t decoding.
      3  *
      4  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "tests.h"
     31 #include <assert.h>
     32 #include <signal.h>
     33 #include <string.h>
     34 #include <unistd.h>
     35 #include <sys/wait.h>
     36 
     37 static siginfo_t sinfo;
     38 
     39 static void
     40 handler(int no, siginfo_t *si, void *uc)
     41 {
     42 	memcpy(&sinfo, si, sizeof(sinfo));
     43 }
     44 
     45 int
     46 main(void)
     47 {
     48 	tprintf("%s", "");
     49 
     50 	int fds[2];
     51 	if (pipe(fds))
     52 		perror_msg_and_fail("pipe");
     53 
     54 	pid_t pid = fork();
     55 	if (pid < 0)
     56 		perror_msg_and_fail("fork");
     57 
     58 	if (!pid) {
     59 		char c;
     60 		(void) close(1);
     61 		assert(read(0, &c, sizeof(c)) == 1);
     62 		return 42;
     63 	}
     64 
     65 	(void) close(0);
     66 
     67 	struct sigaction sa = {
     68 		.sa_sigaction = handler,
     69 		.sa_flags = SA_SIGINFO
     70 	};
     71 	assert(sigaction(SIGCHLD, &sa, NULL) == 0);
     72 
     73 	sigset_t block_mask, unblock_mask;
     74 	assert(sigprocmask(SIG_SETMASK, NULL, &block_mask) == 0);
     75 	sigaddset(&block_mask, SIGCHLD);
     76 	assert(sigprocmask(SIG_SETMASK, &block_mask, NULL) == 0);
     77 
     78 	unblock_mask = block_mask;
     79 	sigdelset(&unblock_mask, SIGCHLD);
     80 
     81 	assert(write(1, "", 1) == 1);
     82 	(void) close(1);
     83 
     84 	sigsuspend(&unblock_mask);
     85 	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED"
     86 		", si_pid=%d, si_uid=%u, si_status=%d"
     87 		", si_utime=%llu, si_stime=%llu} ---\n",
     88 		sinfo.si_pid, sinfo.si_uid, sinfo.si_status,
     89 		zero_extend_signed_to_ull(sinfo.si_utime),
     90 		zero_extend_signed_to_ull(sinfo.si_stime));
     91 
     92 	int s;
     93 	assert(wait(&s) == pid);
     94 	assert(WIFEXITED(s) && WEXITSTATUS(s) == 42);
     95 
     96 	if (pipe(fds))
     97 		perror_msg_and_fail("pipe");
     98 	pid = fork();
     99 	if (pid < 0)
    100 		perror_msg_and_fail("fork");
    101 
    102 	if (!pid) {
    103 		(void) close(1);
    104 		char c;
    105 		assert(read(0, &c, sizeof(c)) == 1);
    106 		(void) raise(SIGUSR1);
    107 		return 1;
    108 	}
    109 
    110 	(void) close(0);
    111 
    112 	assert(write(1, "", 1) == 1);
    113 	(void) close(1);
    114 
    115 	sigsuspend(&unblock_mask);
    116 	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED"
    117 		", si_pid=%d, si_uid=%u, si_status=SIGUSR1"
    118 		", si_utime=%llu, si_stime=%llu} ---\n",
    119 		sinfo.si_pid, sinfo.si_uid,
    120 		zero_extend_signed_to_ull(sinfo.si_utime),
    121 		zero_extend_signed_to_ull(sinfo.si_stime));
    122 
    123 	assert(wait(&s) == pid);
    124 	assert(WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1);
    125 
    126 	if (pipe(fds))
    127 		perror_msg_and_fail("pipe");
    128 	pid = fork();
    129 	if (pid < 0)
    130 		perror_msg_and_fail("fork");
    131 
    132 	if (!pid) {
    133 		(void) close(1);
    134 		raise(SIGSTOP);
    135 		char c;
    136 		assert(read(0, &c, sizeof(c)) == 1);
    137 		return 0;
    138 	}
    139 
    140 	(void) close(0);
    141 
    142 	sigsuspend(&unblock_mask);
    143 	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_STOPPED"
    144 		", si_pid=%d, si_uid=%u, si_status=SIGSTOP"
    145 		", si_utime=%llu, si_stime=%llu} ---\n",
    146 		sinfo.si_pid, sinfo.si_uid,
    147 		zero_extend_signed_to_ull(sinfo.si_utime),
    148 		zero_extend_signed_to_ull(sinfo.si_stime));
    149 
    150 	assert(kill(pid, SIGCONT) == 0);
    151 
    152 	sigsuspend(&unblock_mask);
    153 	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_CONTINUED"
    154 		", si_pid=%d, si_uid=%u, si_status=SIGCONT"
    155 		", si_utime=%llu, si_stime=%llu} ---\n",
    156 		sinfo.si_pid, sinfo.si_uid,
    157 		zero_extend_signed_to_ull(sinfo.si_utime),
    158 		zero_extend_signed_to_ull(sinfo.si_stime));
    159 
    160 	assert(write(1, "", 1) == 1);
    161 	(void) close(1);
    162 
    163 	sigsuspend(&unblock_mask);
    164 	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED"
    165 		", si_pid=%d, si_uid=%u, si_status=0"
    166 		", si_utime=%llu, si_stime=%llu} ---\n",
    167 		sinfo.si_pid, sinfo.si_uid,
    168 		zero_extend_signed_to_ull(sinfo.si_utime),
    169 		zero_extend_signed_to_ull(sinfo.si_stime));
    170 
    171 	assert(wait(&s) == pid && s == 0);
    172 
    173 	tprintf("%s\n", "+++ exited with 0 +++");
    174 	return 0;
    175 }
    176