blob: 17cecbaf5d39728eff5253c753b09336ee50a8f0 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +04002 * Copyright (c) International Business Machines Corp., 2001
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +04003 * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
Cyril Hrubis25af3d22014-01-20 16:31:48 +01004 * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
plars865695b2001-08-27 22:15:12 +00005 *
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +04006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
plars865695b2001-08-27 22:15:12 +000010 *
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
plars865695b2001-08-27 22:15:12 +000015 *
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000019 */
20
21/*
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040022 * Test to check the error and trivial conditions in setpgid system call
Cyril Hrubis25af3d22014-01-20 16:31:48 +010023 *
24 * EPERM - The calling process, process specified by pid and the target
25 * process group must be in the same session.
26 *
27 * EACCESS - Proccess cannot change process group ID of a child after child
28 * has performed exec()
plars865695b2001-08-27 22:15:12 +000029 */
plarsa90f7cc2003-07-08 18:27:58 +000030
robbiewf1ca2382003-03-27 20:28:50 +000031#include <wait.h>
plars865695b2001-08-27 22:15:12 +000032#include <limits.h>
33#include <signal.h>
34#include <errno.h>
35#include <sys/param.h>
robbiewf1ca2382003-03-27 20:28:50 +000036#include <sys/types.h>
37#include <sys/stat.h>
plars865695b2001-08-27 22:15:12 +000038#include <unistd.h>
39#include "test.h"
plars865695b2001-08-27 22:15:12 +000040
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +040041#define TEST_APP "setpgid03_child"
42
plars865695b2001-08-27 22:15:12 +000043char *TCID = "setpgid03";
44int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000045
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +040046static struct tst_checkpoint checkpoint;
47
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040048static void do_child(void);
49static void setup(void);
50static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000051
robbiewf1ca2382003-03-27 20:28:50 +000052int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000053{
Cyril Hrubis25af3d22014-01-20 16:31:48 +010054 int child_pid;
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040055 int status;
Cyril Hrubis25af3d22014-01-20 16:31:48 +010056 int rval;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020057 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020058 const char *msg;
plars865695b2001-08-27 22:15:12 +000059
Cyril Hrubis25af3d22014-01-20 16:31:48 +010060 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080061 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewd34d5812005-07-11 22:28:09 +000062#ifdef UCLINUX
63 maybe_run_child(&do_child, "");
64#endif
65
plars865695b2001-08-27 22:15:12 +000066 setup();
67
plars865695b2001-08-27 22:15:12 +000068 for (lc = 0; TEST_LOOPING(lc); lc++) {
69
Caspar Zhangd59a6592013-03-07 14:59:12 +080070 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000071
Cyril Hrubis25af3d22014-01-20 16:31:48 +010072 /* Child is in new session we are not alowed to change pgid */
73 if ((child_pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +000074 tst_brkm(TBROK, cleanup, "fork() failed");
plars865695b2001-08-27 22:15:12 +000075
Cyril Hrubis25af3d22014-01-20 16:31:48 +010076 if (child_pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +000077#ifdef UCLINUX
Cyril Hrubis25af3d22014-01-20 16:31:48 +010078 if (self_exec(av[0], "") < 0)
robbiewd34d5812005-07-11 22:28:09 +000079 tst_brkm(TBROK, cleanup, "self_exec failed");
robbiewd34d5812005-07-11 22:28:09 +000080#else
81 do_child();
82#endif
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040083 }
plars865695b2001-08-27 22:15:12 +000084
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +040085 TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint);
Cyril Hrubis25af3d22014-01-20 16:31:48 +010086 rval = setpgid(child_pid, getppid());
87 if (rval == -1 && errno == EPERM) {
88 tst_resm(TPASS, "setpgid failed with EPERM");
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040089 } else {
90 tst_resm(TFAIL,
Cyril Hrubis25af3d22014-01-20 16:31:48 +010091 "retval %d, errno %d, expected errno %d",
92 rval, errno, EPERM);
plars865695b2001-08-27 22:15:12 +000093 }
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +040094 TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040095
96 if (wait(&status) < 0)
97 tst_resm(TFAIL | TERRNO, "wait() for child 1 failed");
98
99 if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
100 tst_resm(TFAIL, "child 1 failed with status %d",
101 WEXITSTATUS(status));
102
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100103 /* Child after exec() we are no longer allowed to set pgid */
104 if ((child_pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +0000105 tst_resm(TFAIL, "Fork failed");
Garrett Cooper2c282152010-12-16 00:55:50 -0800106
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100107 if (child_pid == 0) {
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400108 if (execlp(TEST_APP, TEST_APP, NULL) < 0)
plars865695b2001-08-27 22:15:12 +0000109 perror("exec failed");
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400110
plars865695b2001-08-27 22:15:12 +0000111 exit(127);
plars865695b2001-08-27 22:15:12 +0000112 }
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400113
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400114 TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint);
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100115 rval = setpgid(child_pid, getppid());
116 if (rval == -1 && errno == EACCES) {
117 tst_resm(TPASS, "setpgid failed with EACCES");
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400118 } else {
119 tst_resm(TFAIL,
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100120 "retval %d, errno %d, expected errno %d",
121 rval, errno, EACCES);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400122 }
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400123 TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400124
125 if (wait(&status) < 0)
126 tst_resm(TFAIL | TERRNO, "wait() for child 2 failed");
127
128 if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
129 tst_resm(TFAIL, "child 2 failed with status %d",
130 WEXITSTATUS(status));
plars865695b2001-08-27 22:15:12 +0000131 }
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400132
plars865695b2001-08-27 22:15:12 +0000133 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800134 tst_exit();
plars865695b2001-08-27 22:15:12 +0000135}
136
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400137static void do_child(void)
robbiewd34d5812005-07-11 22:28:09 +0000138{
robbiewd34d5812005-07-11 22:28:09 +0000139 if (setsid() < 0) {
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400140 printf("CHILD: setsid() failed, errno: %d\n", errno);
141 exit(2);
robbiewd34d5812005-07-11 22:28:09 +0000142 }
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400143
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400144 TST_CHECKPOINT_SIGNAL_PARENT(&checkpoint);
145
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400146 TST_CHECKPOINT_CHILD_WAIT(&checkpoint);
147
148 exit(0);
robbiewd34d5812005-07-11 22:28:09 +0000149}
150
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400151static void setup(void)
plars865695b2001-08-27 22:15:12 +0000152{
plars865695b2001-08-27 22:15:12 +0000153 tst_sig(FORK, DEF_HANDLER, cleanup);
154
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400155 tst_tmpdir();
156
Jan Stancek4caa6312014-10-06 14:57:56 +0200157 TST_CHECKPOINT_CREATE(&checkpoint);
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400158 checkpoint.timeout = 10000;
159
plars865695b2001-08-27 22:15:12 +0000160 umask(0);
161
plars865695b2001-08-27 22:15:12 +0000162 TEST_PAUSE;
163}
164
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400165static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000166{
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400167 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700168}