1865695bbc89088b9526ea9045410e5afb70a985cplars/*
26bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * Copyright (c) International Business Machines  Corp., 2001
352167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
425af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
5865695bbc89088b9526ea9045410e5afb70a985cplars *
66bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * This program is free software;  you can redistribute it and/or modify
76bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * it under the terms of the GNU General Public License as published by
86bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * the Free Software Foundation; either version 2 of the License, or
96bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * (at your option) any later version.
10865695bbc89088b9526ea9045410e5afb70a985cplars *
116bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * This program is distributed in the hope that it will be useful,
126bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * but WITHOUT ANY WARRANTY;  without even the implied warranty of
136bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
146bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * the GNU General Public License for more details.
15865695bbc89088b9526ea9045410e5afb70a985cplars *
166bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * You should have received a copy of the GNU General Public License
176bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * along with this program;  if not, write to the Free Software
186bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19865695bbc89088b9526ea9045410e5afb70a985cplars */
20865695bbc89088b9526ea9045410e5afb70a985cplars
21865695bbc89088b9526ea9045410e5afb70a985cplars/*
226bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh * Test to check the error and trivial conditions in setpgid system call
2325af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis *
2425af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis * EPERM   -  The calling process, process specified by pid and the target
2525af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis *            process group must be in the same session.
2625af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis *
2725af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis * EACCESS -  Proccess cannot change process group ID of a child after child
2825af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis *            has performed exec()
29865695bbc89088b9526ea9045410e5afb70a985cplars */
30a90f7cc18089a2fc34317c2089b9076e0bcffa7bplars
31249f40545ff10418724fcd8cfa1e10b892725f38Steven Jackson#include <sys/wait.h>
32865695bbc89088b9526ea9045410e5afb70a985cplars#include <limits.h>
33865695bbc89088b9526ea9045410e5afb70a985cplars#include <signal.h>
34865695bbc89088b9526ea9045410e5afb70a985cplars#include <errno.h>
35865695bbc89088b9526ea9045410e5afb70a985cplars#include <sys/param.h>
36f1ca238a510625f6fddf407badcbae5634c9678drobbiew#include <sys/types.h>
37f1ca238a510625f6fddf407badcbae5634c9678drobbiew#include <sys/stat.h>
38865695bbc89088b9526ea9045410e5afb70a985cplars#include <unistd.h>
39865695bbc89088b9526ea9045410e5afb70a985cplars#include "test.h"
40865695bbc89088b9526ea9045410e5afb70a985cplars
4152167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh#define TEST_APP "setpgid03_child"
4252167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
43865695bbc89088b9526ea9045410e5afb70a985cplarschar *TCID = "setpgid03";
44865695bbc89088b9526ea9045410e5afb70a985cplarsint TST_TOTAL = 1;
45865695bbc89088b9526ea9045410e5afb70a985cplars
466bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void do_child(void);
476bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void setup(void);
486bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void cleanup(void);
49865695bbc89088b9526ea9045410e5afb70a985cplars
50f1ca238a510625f6fddf407badcbae5634c9678drobbiewint main(int ac, char **av)
51865695bbc89088b9526ea9045410e5afb70a985cplars{
5225af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis	int child_pid;
536bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh	int status;
5425af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis	int rval;
5589af32a63ce8a780ea39337339e14caae244b5a4Cyril Hrubis	int lc;
56865695bbc89088b9526ea9045410e5afb70a985cplars
57d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis	tst_parse_opts(ac, av, NULL, NULL);
58d34d581c6a320e356a6cda923c7aa399479e812crobbiew#ifdef UCLINUX
59d34d581c6a320e356a6cda923c7aa399479e812crobbiew	maybe_run_child(&do_child, "");
60d34d581c6a320e356a6cda923c7aa399479e812crobbiew#endif
61d34d581c6a320e356a6cda923c7aa399479e812crobbiew
62865695bbc89088b9526ea9045410e5afb70a985cplars	setup();
63865695bbc89088b9526ea9045410e5afb70a985cplars
64865695bbc89088b9526ea9045410e5afb70a985cplars	for (lc = 0; TEST_LOOPING(lc); lc++) {
65865695bbc89088b9526ea9045410e5afb70a985cplars
66d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang		tst_count = 0;
67865695bbc89088b9526ea9045410e5afb70a985cplars
6825af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		/* Child is in new session we are not alowed to change pgid */
6925af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if ((child_pid = FORK_OR_VFORK()) == -1)
70865695bbc89088b9526ea9045410e5afb70a985cplars			tst_brkm(TBROK, cleanup, "fork() failed");
71865695bbc89088b9526ea9045410e5afb70a985cplars
7225af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if (child_pid == 0) {
73d34d581c6a320e356a6cda923c7aa399479e812crobbiew#ifdef UCLINUX
7425af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis			if (self_exec(av[0], "") < 0)
75d34d581c6a320e356a6cda923c7aa399479e812crobbiew				tst_brkm(TBROK, cleanup, "self_exec failed");
76d34d581c6a320e356a6cda923c7aa399479e812crobbiew#else
77d34d581c6a320e356a6cda923c7aa399479e812crobbiew			do_child();
78d34d581c6a320e356a6cda923c7aa399479e812crobbiew#endif
79865695bbc89088b9526ea9045410e5afb70a985cplars		}
806bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
819f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
8225af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		rval = setpgid(child_pid, getppid());
8325af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if (rval == -1 && errno == EPERM) {
8425af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis			tst_resm(TPASS, "setpgid failed with EPERM");
856bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		} else {
866bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL,
8725af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis				"retval %d, errno %d, expected errno %d",
8825af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis				rval, errno, EPERM);
89865695bbc89088b9526ea9045410e5afb70a985cplars		}
909f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
916bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
926bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		if (wait(&status) < 0)
936bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL | TERRNO, "wait() for child 1 failed");
946bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
956bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
966bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL, "child 1 failed with status %d",
976bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh				WEXITSTATUS(status));
986bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
9925af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		/* Child after exec() we are no longer allowed to set pgid */
10025af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if ((child_pid = FORK_OR_VFORK()) == -1)
101865695bbc89088b9526ea9045410e5afb70a985cplars			tst_resm(TFAIL, "Fork failed");
1022c28215423293e443469a07ae7011135d058b671Garrett Cooper
10325af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if (child_pid == 0) {
10452167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh			if (execlp(TEST_APP, TEST_APP, NULL) < 0)
105865695bbc89088b9526ea9045410e5afb70a985cplars				perror("exec failed");
10652167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
107865695bbc89088b9526ea9045410e5afb70a985cplars			exit(127);
1086bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		}
1096bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
1109f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
11125af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		rval = setpgid(child_pid, getppid());
11225af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis		if (rval == -1 && errno == EACCES) {
11325af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis			tst_resm(TPASS, "setpgid failed with EACCES");
114865695bbc89088b9526ea9045410e5afb70a985cplars		} else {
1156bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL,
11625af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis				"retval %d, errno %d, expected errno %d",
11725af3d2fd09190c9ce98f302dead19da9b9e0dc6Cyril Hrubis				rval, errno, EACCES);
118865695bbc89088b9526ea9045410e5afb70a985cplars		}
1199f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
1206bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
1216bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		if (wait(&status) < 0)
1226bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL | TERRNO, "wait() for child 2 failed");
1236bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
1246bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh		if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
1256bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh			tst_resm(TFAIL, "child 2 failed with status %d",
1266bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh				WEXITSTATUS(status));
127865695bbc89088b9526ea9045410e5afb70a985cplars	}
1286bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikh
129865695bbc89088b9526ea9045410e5afb70a985cplars	cleanup();
1301e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper	tst_exit();
131865695bbc89088b9526ea9045410e5afb70a985cplars}
132865695bbc89088b9526ea9045410e5afb70a985cplars
1336bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void do_child(void)
134d34d581c6a320e356a6cda923c7aa399479e812crobbiew{
135d34d581c6a320e356a6cda923c7aa399479e812crobbiew	if (setsid() < 0) {
13652167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh		printf("CHILD: setsid() failed, errno: %d\n", errno);
13752167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh		exit(2);
138d34d581c6a320e356a6cda923c7aa399479e812crobbiew	}
13952167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
1409f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
14152167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
1429f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);
14352167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
14452167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh	exit(0);
145d34d581c6a320e356a6cda923c7aa399479e812crobbiew}
146d34d581c6a320e356a6cda923c7aa399479e812crobbiew
1476bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void setup(void)
148865695bbc89088b9526ea9045410e5afb70a985cplars{
149865695bbc89088b9526ea9045410e5afb70a985cplars	tst_sig(FORK, DEF_HANDLER, cleanup);
150865695bbc89088b9526ea9045410e5afb70a985cplars
15152167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh	tst_tmpdir();
15252167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
1539f136a48c6205362cd8d35c726491ca93cb16514Cyril Hrubis	TST_CHECKPOINT_INIT(tst_rmdir);
15452167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh
155865695bbc89088b9526ea9045410e5afb70a985cplars	umask(0);
156865695bbc89088b9526ea9045410e5afb70a985cplars
157865695bbc89088b9526ea9045410e5afb70a985cplars	TEST_PAUSE;
158865695bbc89088b9526ea9045410e5afb70a985cplars}
159865695bbc89088b9526ea9045410e5afb70a985cplars
1606bfe99a261764879d0aad700d4e3818a137fa423Stanislav Kholmanskikhstatic void cleanup(void)
161865695bbc89088b9526ea9045410e5afb70a985cplars{
16252167a1eb08841f53952854657f61d86cc493995Stanislav Kholmanskikh	tst_rmdir();
163ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
164