1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Yang Xu <xuyang2018.jy@fujitsu.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/*\ 8f08c3bdfSopenharmony_ci * [Description] 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * Verify that the PIDFD_NONBLOCK flag works with pidfd_open() and 11f08c3bdfSopenharmony_ci * that waitid() with a non-blocking pidfd returns EAGAIN. 12f08c3bdfSopenharmony_ci */ 13f08c3bdfSopenharmony_ci 14f08c3bdfSopenharmony_ci#include <unistd.h> 15f08c3bdfSopenharmony_ci#include <sys/wait.h> 16f08c3bdfSopenharmony_ci#include <stdlib.h> 17f08c3bdfSopenharmony_ci#include "tst_test.h" 18f08c3bdfSopenharmony_ci#include "lapi/pidfd.h" 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#ifndef P_PIDFD 21f08c3bdfSopenharmony_ci#define P_PIDFD 3 22f08c3bdfSopenharmony_ci#endif 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistatic int pidfd = -1; 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cistatic void run(void) 27f08c3bdfSopenharmony_ci{ 28f08c3bdfSopenharmony_ci int flag, pid, ret; 29f08c3bdfSopenharmony_ci siginfo_t info; 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 32f08c3bdfSopenharmony_ci if (!pid) { 33f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAIT(0); 34f08c3bdfSopenharmony_ci exit(EXIT_SUCCESS); 35f08c3bdfSopenharmony_ci } 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci TST_EXP_FD_SILENT(pidfd_open(pid, PIDFD_NONBLOCK), 38f08c3bdfSopenharmony_ci "pidfd_open(%d, PIDFD_NONBLOCK)", pid); 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci pidfd = TST_RET; 41f08c3bdfSopenharmony_ci flag = SAFE_FCNTL(pidfd, F_GETFL); 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci if (!(flag & O_NONBLOCK)) 44f08c3bdfSopenharmony_ci tst_brk(TFAIL, "pidfd_open(%d, O_NONBLOCK) didn't set O_NONBLOCK flag", pid); 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci tst_res(TPASS, "pidfd_open(%d, O_NONBLOCK) sets O_NONBLOCK flag", pid); 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci TST_EXP_FAIL(waitid(P_PIDFD, pidfd, &info, WEXITED), EAGAIN, 49f08c3bdfSopenharmony_ci "waitid(P_PIDFD,...,WEXITED)"); 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE(0); 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci ret = TST_RETRY_FUNC(waitid(P_PIDFD, pidfd, &info, WEXITED), TST_RETVAL_EQ0); 54f08c3bdfSopenharmony_ci if (ret == 0) { 55f08c3bdfSopenharmony_ci tst_res(TPASS, "waitid(P_PIDFD) succeeded after child process terminated"); 56f08c3bdfSopenharmony_ci } else { 57f08c3bdfSopenharmony_ci tst_res(TFAIL, "waitid(P_PIDFD) failed after child process terminated"); 58f08c3bdfSopenharmony_ci SAFE_WAIT(NULL); 59f08c3bdfSopenharmony_ci } 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci SAFE_CLOSE(pidfd); 62f08c3bdfSopenharmony_ci} 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_cistatic void setup(void) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci pidfd_open_supported(); 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci TEST(pidfd_open(getpid(), PIDFD_NONBLOCK)); 69f08c3bdfSopenharmony_ci if (TST_RET == -1) { 70f08c3bdfSopenharmony_ci if (TST_ERR == EINVAL) { 71f08c3bdfSopenharmony_ci tst_brk(TCONF, "PIDFD_NONBLOCK was supported since linux 5.10"); 72f08c3bdfSopenharmony_ci return; 73f08c3bdfSopenharmony_ci } 74f08c3bdfSopenharmony_ci tst_brk(TFAIL | TTERRNO, 75f08c3bdfSopenharmony_ci "pidfd_open(getpid(),PIDFD_NONBLOCK) failed unexpectedly"); 76f08c3bdfSopenharmony_ci } 77f08c3bdfSopenharmony_ci SAFE_CLOSE(TST_RET); 78f08c3bdfSopenharmony_ci} 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_cistatic void cleanup(void) 81f08c3bdfSopenharmony_ci{ 82f08c3bdfSopenharmony_ci if (pidfd > -1) 83f08c3bdfSopenharmony_ci SAFE_CLOSE(pidfd); 84f08c3bdfSopenharmony_ci} 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_cistatic struct tst_test test = { 87f08c3bdfSopenharmony_ci .needs_root = 1, 88f08c3bdfSopenharmony_ci .forks_child = 1, 89f08c3bdfSopenharmony_ci .needs_checkpoints = 1, 90f08c3bdfSopenharmony_ci .setup = setup, 91f08c3bdfSopenharmony_ci .cleanup = cleanup, 92f08c3bdfSopenharmony_ci .test_all = run, 93f08c3bdfSopenharmony_ci}; 94