(root)/
strace-6.5/
tests-mx32/
siginfo.c
       1  /*
       2   * Check SIGCHLD siginfo_t decoding.
       3   *
       4   * Copyright (c) 2015-2018 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2022 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <assert.h>
      13  #include <signal.h>
      14  #include <string.h>
      15  #include <unistd.h>
      16  #include <sys/wait.h>
      17  
      18  #include "time_enjoyment.h"
      19  
      20  enum {
      21  	CPUTIME_LIMIT_NSEC = 100000000,
      22  };
      23  
      24  static siginfo_t sinfo;
      25  
      26  static void
      27  handler(int no, siginfo_t *si, void *uc)
      28  {
      29  	memcpy(&sinfo, si, sizeof(sinfo));
      30  }
      31  
      32  int
      33  main(void)
      34  {
      35  	char utime_str[64];
      36  	char stime_str[64];
      37  
      38  	tprintf("%s", "");
      39  
      40  	int fds[2];
      41  	if (pipe(fds))
      42  		perror_msg_and_fail("pipe");
      43  
      44  	pid_t pid = fork();
      45  	if (pid < 0)
      46  		perror_msg_and_fail("fork");
      47  
      48  	if (!pid) {
      49  		char c;
      50  		(void) close(1);
      51  		assert(read(0, &c, sizeof(c)) == 1);
      52  		return 42;
      53  	}
      54  
      55  	(void) close(0);
      56  
      57  	struct sigaction sa = {
      58  		.sa_sigaction = handler,
      59  		.sa_flags = SA_SIGINFO
      60  	};
      61  	assert(sigaction(SIGCHLD, &sa, NULL) == 0);
      62  
      63  	sigset_t block_mask, unblock_mask;
      64  	assert(sigprocmask(SIG_SETMASK, NULL, &block_mask) == 0);
      65  	sigaddset(&block_mask, SIGCHLD);
      66  	assert(sigprocmask(SIG_SETMASK, &block_mask, NULL) == 0);
      67  
      68  	unblock_mask = block_mask;
      69  	sigdelset(&unblock_mask, SIGCHLD);
      70  
      71  	assert(write(1, "", 1) == 1);
      72  	(void) close(1);
      73  
      74  	sigsuspend(&unblock_mask);
      75  	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED"
      76  		", si_pid=%d, si_uid=%d, si_status=%d"
      77  		", si_utime=%s, si_stime=%s} ---\n",
      78  		sinfo.si_pid, sinfo.si_uid, sinfo.si_status,
      79  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_utime),
      80  			    ARRSZ_PAIR(utime_str)),
      81  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_stime),
      82  			    ARRSZ_PAIR(stime_str)));
      83  
      84  	int s;
      85  	assert(wait(&s) == pid);
      86  	assert(WIFEXITED(s) && WEXITSTATUS(s) == 42);
      87  
      88  	if (pipe(fds))
      89  		perror_msg_and_fail("pipe");
      90  	pid = fork();
      91  	if (pid < 0)
      92  		perror_msg_and_fail("fork");
      93  
      94  	if (!pid) {
      95  		(void) close(1);
      96  		char c;
      97  		assert(read(0, &c, sizeof(c)) == 1);
      98  		enjoy_time(CPUTIME_LIMIT_NSEC);
      99  		(void) raise(SIGUSR1);
     100  		return 1;
     101  	}
     102  
     103  	(void) close(0);
     104  
     105  	assert(write(1, "", 1) == 1);
     106  	(void) close(1);
     107  
     108  	sigsuspend(&unblock_mask);
     109  	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED"
     110  		", si_pid=%d, si_uid=%d, si_status=SIGUSR1"
     111  		", si_utime=%s, si_stime=%s} ---\n",
     112  		sinfo.si_pid, sinfo.si_uid,
     113  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_utime),
     114  			    ARRSZ_PAIR(utime_str)),
     115  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_stime),
     116  			    ARRSZ_PAIR(stime_str)));
     117  
     118  	assert(wait(&s) == pid);
     119  	assert(WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1);
     120  
     121  	if (pipe(fds))
     122  		perror_msg_and_fail("pipe");
     123  	pid = fork();
     124  	if (pid < 0)
     125  		perror_msg_and_fail("fork");
     126  
     127  	if (!pid) {
     128  		(void) close(1);
     129  		enjoy_time(CPUTIME_LIMIT_NSEC);
     130  		raise(SIGSTOP);
     131  		char c;
     132  		assert(read(0, &c, sizeof(c)) == 1);
     133  		return 0;
     134  	}
     135  
     136  	(void) close(0);
     137  
     138  	sigsuspend(&unblock_mask);
     139  	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_STOPPED"
     140  		", si_pid=%d, si_uid=%d, si_status=SIGSTOP"
     141  		", si_utime=%s, si_stime=%s} ---\n",
     142  		sinfo.si_pid, sinfo.si_uid,
     143  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_utime),
     144  			    ARRSZ_PAIR(utime_str)),
     145  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_stime),
     146  			    ARRSZ_PAIR(stime_str)));
     147  
     148  	assert(kill(pid, SIGCONT) == 0);
     149  
     150  	sigsuspend(&unblock_mask);
     151  	tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_CONTINUED"
     152  		", si_pid=%d, si_uid=%d, si_status=SIGCONT"
     153  		", si_utime=%s, si_stime=%s} ---\n",
     154  		sinfo.si_pid, sinfo.si_uid,
     155  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_utime),
     156  			    ARRSZ_PAIR(utime_str)),
     157  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_stime),
     158  			    ARRSZ_PAIR(stime_str)));
     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=%d, si_status=0"
     166  		", si_utime=%s, si_stime=%s} ---\n",
     167  		sinfo.si_pid, sinfo.si_uid,
     168  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_utime),
     169  			    ARRSZ_PAIR(utime_str)),
     170  		clock_t_str(zero_extend_signed_to_ull(sinfo.si_stime),
     171  			    ARRSZ_PAIR(stime_str)));
     172  
     173  	assert(wait(&s) == pid && s == 0);
     174  
     175  	tprintf("%s\n", "+++ exited with 0 +++");
     176  	return 0;
     177  }