1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2018 Linux Test Project
4f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Ported to LTP: Wayne Boyer
7f08c3bdfSopenharmony_ci *  21/04/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
8f08c3bdfSopenharmony_ci */
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ci/*
11f08c3bdfSopenharmony_ci * NAME
12f08c3bdfSopenharmony_ci *	execve05.c
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * DESCRIPTION
15f08c3bdfSopenharmony_ci *	This testcase tests the basic functionality of the execve(2) system
16f08c3bdfSopenharmony_ci *	call.
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci * ALGORITHM
19f08c3bdfSopenharmony_ci *	This tests the functionality of the execve(2) system call by spawning
20f08c3bdfSopenharmony_ci *	a few children, each of which would execute "execve_child" simultaneously,
21f08c3bdfSopenharmony_ci *	and finally the parent ensures that they terminated correctly.
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * USAGE
24f08c3bdfSopenharmony_ci *	execve05 -i 5 -n 20
25f08c3bdfSopenharmony_ci */
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci#ifndef _GNU_SOURCE
28f08c3bdfSopenharmony_ci#define _GNU_SOURCE
29f08c3bdfSopenharmony_ci#endif
30f08c3bdfSopenharmony_ci#include <stdio.h>
31f08c3bdfSopenharmony_ci#include <stdlib.h>
32f08c3bdfSopenharmony_ci#include <errno.h>
33f08c3bdfSopenharmony_ci#include <unistd.h>
34f08c3bdfSopenharmony_ci#include <sys/types.h>
35f08c3bdfSopenharmony_ci#include <sys/stat.h>
36f08c3bdfSopenharmony_ci#include <sys/wait.h>
37f08c3bdfSopenharmony_ci#include <pwd.h>
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci#include "tst_test.h"
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci#define TEST_APP "execve_child"
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_cistatic int nchild = 8;
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_cistatic char *opt_nchild;
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic void do_child(void)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	char *argv[3] = {TEST_APP, "canary", NULL};
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci	TST_CHECKPOINT_WAIT(0);
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	TEST(execve(TEST_APP, argv, environ));
54f08c3bdfSopenharmony_ci	tst_res(TFAIL | TTERRNO, "execve() returned unexpected errno");
55f08c3bdfSopenharmony_ci}
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_cistatic void verify_execve(void)
58f08c3bdfSopenharmony_ci{
59f08c3bdfSopenharmony_ci	int i;
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	for (i = 0; i < nchild; i++) {
62f08c3bdfSopenharmony_ci		if (SAFE_FORK() == 0)
63f08c3bdfSopenharmony_ci			do_child();
64f08c3bdfSopenharmony_ci	}
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	TST_CHECKPOINT_WAKE2(0, nchild);
67f08c3bdfSopenharmony_ci}
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_cistatic void setup(void)
70f08c3bdfSopenharmony_ci{
71f08c3bdfSopenharmony_ci	if (opt_nchild)
72f08c3bdfSopenharmony_ci		nchild = SAFE_STRTOL(opt_nchild, 1, INT_MAX);
73f08c3bdfSopenharmony_ci}
74f08c3bdfSopenharmony_ci
75f08c3bdfSopenharmony_cistatic struct tst_test test = {
76f08c3bdfSopenharmony_ci	.test_all = verify_execve,
77f08c3bdfSopenharmony_ci	.options = (struct tst_option[]) {
78f08c3bdfSopenharmony_ci		{"n:", &opt_nchild, "Numbers of children"},
79f08c3bdfSopenharmony_ci		{}
80f08c3bdfSopenharmony_ci	},
81f08c3bdfSopenharmony_ci	.forks_child = 1,
82f08c3bdfSopenharmony_ci	.child_needs_reinit = 1,
83f08c3bdfSopenharmony_ci	.needs_checkpoints = 1,
84f08c3bdfSopenharmony_ci	.resource_files = (const char *const []) {
85f08c3bdfSopenharmony_ci		TEST_APP,
86f08c3bdfSopenharmony_ci		NULL
87f08c3bdfSopenharmony_ci	},
88f08c3bdfSopenharmony_ci	.setup = setup,
89f08c3bdfSopenharmony_ci};
90