1  /* Basic tests for Linux process_mrelease.
       2     Copyright (C) 2022-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <stdlib.h>
      21  #include <support/check.h>
      22  #include <support/support.h>
      23  #include <support/xsocket.h>
      24  #include <support/xunistd.h>
      25  #include <sys/mman.h>
      26  #include <sys/pidfd.h>
      27  #include <sys/wait.h>
      28  
      29  static void
      30  exit_subprocess (int dummy)
      31  {
      32    exit (EXIT_FAILURE);
      33  }
      34  
      35  static void
      36  subprocess (void)
      37  {
      38    /* In case something goes wrong with parent before pidfd_send_signal.  */
      39    support_create_timer (5, 0, false, exit_subprocess);
      40  
      41    pause ();
      42    _exit (0);
      43  }
      44  
      45  static int
      46  do_test (void)
      47  {
      48    {
      49      int r = process_mrelease (-1, 0);
      50      TEST_COMPARE (r, -1);
      51      if (errno == ENOSYS)
      52        FAIL_UNSUPPORTED ("kernel does not support process_mrelease, "
      53  		        "skipping test");
      54      TEST_COMPARE (errno, EBADF);
      55    }
      56  
      57    pid_t pid = xfork ();
      58    if (pid == 0)
      59      subprocess ();
      60  
      61    int pidfd = pidfd_open (pid, 0);
      62    TEST_VERIFY (pidfd != -1);
      63  
      64    /* The syscall only succeeds if the target process is exiting and there
      65       is no guarantee that calling if after pidfd_send_signal will not error
      66       (ince the process might have already been reaped by the OS).  So just
      67       check if it does fail when the process is stll running.  */
      68    TEST_COMPARE (process_mrelease (pidfd, 0), -1);
      69    TEST_COMPARE (errno, EINVAL);
      70  
      71    TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0);
      72    {
      73      siginfo_t info;
      74      int r = waitid (P_PIDFD, pidfd, &info, WEXITED);
      75      TEST_COMPARE (r, 0);
      76      TEST_COMPARE (info.si_status, SIGKILL);
      77      TEST_COMPARE (info.si_code, CLD_KILLED);
      78    }
      79  
      80    TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), -1);
      81    TEST_COMPARE (errno, ESRCH);
      82  
      83    return 0;
      84  }
      85  
      86  #include <support/test-driver.c>