[LTP] [PATCH] syscalls/kill12: Convert to new API
Andrea Cervesato
andrea.cervesato@suse.com
Tue Jun 24 10:45:24 CEST 2025
Hi!
On 6/17/25 5:56 PM, Ricardo B. Marlière via ltp wrote:
> From: Ricardo B. Marlière <rbm@suse.com>
>
> Signed-off-by: Ricardo B. Marlière <rbm@suse.com>
> ---
> testcases/kernel/syscalls/kill/kill12.c | 277 +++++++++-----------------------
> 1 file changed, 72 insertions(+), 205 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/kill/kill12.c b/testcases/kernel/syscalls/kill/kill12.c
> index f864bdcb654c563cd4808bec7a4979fb160825c4..d843fe5fba62f63dc903759192fbfb7cd02bc7b6 100644
> --- a/testcases/kernel/syscalls/kill/kill12.c
> +++ b/testcases/kernel/syscalls/kill/kill12.c
> @@ -1,236 +1,103 @@
> -/* IBM Corporation */
> -/* 01/02/2003 Port to LTP avenkat@us.ibm.com */
> -/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
> -
> +// SPDX-License-Identifier: GPL-2.0-or-later
> /*
> - *
> - * Copyright (c) International Business Machines Corp., 2002
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
> - * the GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) International Business Machines Corp., 2002
> + * 01/02/2003 Port to LTP avenkat@us.ibm.com
> + * 06/30/2001 Port to Linux nsharoff@us.ibm.com
> + * Copyright (c) 2025 SUSE LLC Ricardo B. Marlière <rbm@suse.com>
> */
>
> - /*kill2.c */
> -/*======================================================================
> ->KEYS: < kill(), wait(), signal()
> ->WHAT: < Check that when a child is killed by its parent, it returns the
> - < correct values to the waiting parent--the child sets signal to
> - < ignore the kill
> ->HOW: < For each signal: Send that signal to a child that has elected
> - < to catch the signal, check that the correct status was returned
> - < to the waiting parent.
> - < NOTE: Signal 9 (kill) is not catchable, and must be dealt with
> - < separately.
> ->BUGS: < None known
> -======================================================================*/
> -#ifndef _GNU_SOURCE
> -#define _GNU_SOURCE 1
> -#endif
> -
> -#include <stdio.h>
> -#include <sys/types.h>
> -#include <signal.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> -#include <sys/wait.h>
> -#include <errno.h>
> +/*\
> + * Check that when a child is killed by its parent, it returns the
> + * correct values to the waiting parent - the child sets signal to
> + * ignore the kill
> + */
>
> -#include "test.h"
> -#define ITER 3
> -#define FAILED 0
> -#define PASSED 1
> +#define _GNU_SOURCE
> +#include <sys/wait.h>
Both are not needed with the suggestions below.
>
> -char *TCID = "kill12";
> +#include "tst_test.h"
>
> -int local_flag = PASSED;
> -int block_number;
> -FILE *temp;
> -int TST_TOTAL = 1;
> static int sig;
> +static int chflag;
>
> -int anyfail();
> -int blenter();
> -int instress();
> -void setup();
> -void terror();
> -void fail_exit();
> -void ok_exit();
> -int forkfail();
> -void do_child();
> +static void do_child(void);
>
> -int chflag;
> -
> -int main(int argc, char **argv)
> +static void run(void)
> {
> - int pid, npid;
> - int nsig, exno, nexno, status;
> - int ret_val = 0;
> - int core;
> - void chsig();
> -
> - tst_parse_opts(argc, argv, NULL, NULL);
> -
> - setup();
> - blenter();
> -
> - exno = 1;
> -
> - if (sigset(SIGCHLD, chsig) == SIG_ERR) {
> - fprintf(temp, "\tsigset failed, errno = %d\n", errno);
> - fail_exit();
> - }
> + int pid;
> + int nsig, nexno, status;
>
> for (sig = 1; sig < 14; sig++) {
Why not just "int sig" ?
> - fflush(temp);
> - chflag = 0;
> + /* SIGKILL and SIGSTOP can't be catched */
> + if (sig == SIGKILL || sig == SIGSTOP)
> + continue;
>
> - pid = tst_fork();
> - if (pid < 0) {
> - forkfail();
> - }
> + chflag = 0;
>
> - if (pid == 0) {
> + pid = SAFE_FORK();
> + if (!pid)
> do_child();
> - } else {
> - //fprintf(temp, "Testing signal %d\n", sig);
> -
> - while (!chflag) /* wait for child */
> - sleep(1);
> -
> - kill(pid, sig); /* child should ignroe this sig */
> - kill(pid, SIGCHLD); /* child should exit */
> -
> -#ifdef BCS
> - while ((npid = wait(&status)) != pid
> - || (npid == -1 && errno == EINTR)) ;
> - if (npid != pid) {
> - fprintf(temp,
> - "wait error: wait returned wrong pid\n");
> - ret_val = 1;
> - }
> -#else
> - while ((npid = waitpid(pid, &status, 0)) != -1
> - || errno == EINTR) ;
> -#endif
> -
> - /*
> - nsig = status & 0177;
> - core = status & 0200;
> - nexno = (status & 0xff00) >> 8;
> - */
> - /***** LTP Port *****/
> - nsig = WTERMSIG(status);
> -#ifdef WCOREDUMP
> - core = WCOREDUMP(status);
> -#endif
> - nexno = WIFEXITED(status);
> - /***** ** ** *****/
> -
> - /* nsig is the signal number returned by wait
> - it should be 0, except when sig = 9 */
> -
> - if ((sig == 9) && (nsig != sig)) {
> - fprintf(temp, "wait error: unexpected signal"
> - " returned when the signal sent was 9"
> - " The status of the process is %d \n",
> - status);
> - ret_val = 1;
> - }
> - if ((sig != 9) && (nsig != 0)) {
> - fprintf(temp, "wait error: unexpected signal "
> - "returned, the status of the process is "
> - "%d \n", status);
> - ret_val = 1;
> - }
> -
> - /* nexno is the exit number returned by wait
> - it should be 1, except when sig = 9 */
> -
> - if (sig == 9)
> - if (nexno != 0) {
> - fprintf(temp, "signal error: unexpected"
> - " exit number returned when"
> - " signal sent was 9, the status"
> - " of the process is %d \n",
> - status);
> - ret_val = 1;
> - } else;
> - else if (nexno != 1) {
> - fprintf(temp, "signal error: unexpected exit "
> - "number returned,the status of the"
> - " process is %d\n", status);
> - ret_val = 1;
> - }
> - }
> +
> + while (!chflag) /* wait for child */
> + sleep(1);
No need to sync parent and child with a while loop. We have checkpoints:
pid = SAFE_FORK();
if (!pid) {
TST_CHECKPOINT_WAKE_AND_WAIT(0);
exit(1);
}
TST_CHECKPOINT_WAIT(0);
> +
> + SAFE_KILL(pid, sig); /* child should ignore this sig */
> + SAFE_KILL(pid, SIGCHLD); /* child should exit */
> + SAFE_WAITPID(pid, &status, 0);
> + nsig = WTERMSIG(status);
> + nexno = WIFEXITED(status);
> +
> + /* nsig is the signal number returned by wait, it should be 0 */
> + if (nsig != 0)
> + tst_res(TFAIL,
> + "wait error: unexpected signal "
> + "returned, the status of the process is %d",
> + status);
> +
> + /* nexno is the exit number returned by wait, it should be 1 */
> + if (nexno != 1)
> + tst_res(TFAIL,
> + "signal error: unexpected exit "
> + "number returned,the status of the"
> + " process is %d\n",
> + status);
These two statements can be shrinked to TST_EXP_EQ_LI(WTERMSIG(status),
sig) , etc.
> }
> - if (ret_val)
> - local_flag = FAILED;
>
> - anyfail();
> - tst_exit();
> + tst_res(TPASS, "Test passed");
No need for this once we check the child status with TST_EXP_EQ_LI().
> }
>
> -void chsig(void)
> +static void chsig(LTP_ATTRIBUTE_UNUSED int signum,
> + LTP_ATTRIBUTE_UNUSED siginfo_t *si,
> + LTP_ATTRIBUTE_UNUSED void *uc)
> {
> chflag++;
> }
No need for this with checkpoints.
>
> -int anyfail(void)
> +static void do_child(void)
> {
> - (local_flag == FAILED) ? tst_resm(TFAIL,
> - "Test failed") : tst_resm(TPASS,
> - "Test passed");
> - tst_exit();
> -}
> + struct sigaction sa = {
> + .sa_handler = SIG_IGN,
> + .sa_flags = 0,
> + };
No need for this with checkpoints.
>
> -void do_child(void)
> -{
> - int exno = 1;
> -
> - sigset(sig, SIG_IGN); /* set to ignore signal */
> - kill(getppid(), SIGCHLD); /* tell parent we are ready */
> + SAFE_SIGACTION(sig, &sa, NULL);
> + SAFE_KILL(getppid(), SIGCHLD); /* tell parent we are ready */
> while (!chflag)
> - sleep(1); /* wait for parent */
> -
> - exit(exno);
> -}
> -
> -void setup(void)
> -{
> - temp = stderr;
> -}
> -
> -int blenter(void)
> -{
> - //tst_resm(TINFO, "Enter block %d", block_number);
> - local_flag = PASSED;
> - return 0;
> + sleep(1); /* wait for parent */
> + exit(1);
> }
>
> -void terror(char *message)
> +static void setup(void)
> {
> - tst_resm(TBROK, "Reason: %s:%s", message, strerror(errno));
> + struct sigaction sa = {
> + .sa_sigaction = chsig,
> + .sa_flags = 0,
> + };
> + SAFE_SIGACTION(SIGCHLD, &sa, NULL);
> }
>
> -void fail_exit(void)
> -{
> - local_flag = FAILED;
> - anyfail();
> -
> -}
> -
> -int forkfail(void)
> -{
> - tst_brkm(TBROK, NULL, "FORK FAILED - terminating test.");
> -}
> +static struct tst_test test = {
> + .test_all = run,
> + .setup = setup,
> + .forks_child = 1,
> +};
>
> ---
> base-commit: df591113afeb31107bc45bd5ba28a99b556d1028
> change-id: 20250617-conversions-kill-d79ed23a8c6b
>
> Best regards,
- Andrea
More information about the ltp
mailing list