xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/setpgid/setpgid03.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines  Corp., 2001
4  * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
5  * Copyright (c) 2014 Cyril Hrubis <[email protected]>
6  * Copyright (C) 2021 SUSE LLC Andrea Cervesato <[email protected]>
7  */
8 
9 /*\
10  * [Description]
11  *
12  * Tests setpgid(2) errors:
13  *
14  * - EPERM The process specified by pid must not be a session leader.
15  *
16  * - EPERM The calling process, process specified by pid and the target
17  *         process group must be in the same session.
18  *
19  * - EACCESS Proccess cannot change process group ID of a child after child
20  *           has performed exec()
21  */
22 
23 #include <unistd.h>
24 #include <sys/wait.h>
25 #include "tst_test.h"
26 
27 #define TEST_APP "setpgid03_child"
28 
do_child(void)29 static void do_child(void)
30 {
31 	SAFE_SETSID();
32 	TST_CHECKPOINT_WAKE_AND_WAIT(0);
33 }
34 
run(void)35 static void run(void)
36 {
37 	pid_t child_pid;
38 
39 	child_pid = SAFE_FORK();
40 	if (!child_pid) {
41 		do_child();
42 		return;
43 	}
44 
45 	TST_CHECKPOINT_WAIT(0);
46 
47 	TST_EXP_FAIL(setpgid(child_pid, getppid()), EPERM);
48 	/* Child did setsid(), so its PGID is set to its PID. */
49 	TST_EXP_FAIL(setpgid(0, child_pid), EPERM);
50 
51 	TST_CHECKPOINT_WAKE(0);
52 
53 	/* child after exec() we are no longer allowed to set pgid */
54 	child_pid = SAFE_FORK();
55 	if (!child_pid)
56 		SAFE_EXECLP(TEST_APP, TEST_APP, NULL);
57 
58 	TST_CHECKPOINT_WAIT(0);
59 
60 	TST_EXP_FAIL(setpgid(child_pid, getppid()), EACCES);
61 
62 	TST_CHECKPOINT_WAKE(0);
63 }
64 
65 static struct tst_test test = {
66 	.test_all = run,
67 	.forks_child = 1,
68 	.needs_checkpoints = 1,
69 };
70