blob: 51e0eeb24f2139e3ddb1d71104e09aa96c07bbca [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
Steven Jackson249f4052016-12-13 16:16:00 +000031#include <sys/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 Kholmanskikh6bfe99a2013-12-12 13:21:54 +040046static void do_child(void);
47static void setup(void);
48static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000049
robbiewf1ca2382003-03-27 20:28:50 +000050int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000051{
Cyril Hrubis25af3d22014-01-20 16:31:48 +010052 int child_pid;
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040053 int status;
Cyril Hrubis25af3d22014-01-20 16:31:48 +010054 int rval;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020055 int lc;
plars865695b2001-08-27 22:15:12 +000056
Cyril Hrubisd6d11d02015-03-09 17:35:43 +010057 tst_parse_opts(ac, av, NULL, NULL);
robbiewd34d5812005-07-11 22:28:09 +000058#ifdef UCLINUX
59 maybe_run_child(&do_child, "");
60#endif
61
plars865695b2001-08-27 22:15:12 +000062 setup();
63
plars865695b2001-08-27 22:15:12 +000064 for (lc = 0; TEST_LOOPING(lc); lc++) {
65
Caspar Zhangd59a6592013-03-07 14:59:12 +080066 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000067
Cyril Hrubis25af3d22014-01-20 16:31:48 +010068 /* Child is in new session we are not alowed to change pgid */
69 if ((child_pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +000070 tst_brkm(TBROK, cleanup, "fork() failed");
plars865695b2001-08-27 22:15:12 +000071
Cyril Hrubis25af3d22014-01-20 16:31:48 +010072 if (child_pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +000073#ifdef UCLINUX
Cyril Hrubis25af3d22014-01-20 16:31:48 +010074 if (self_exec(av[0], "") < 0)
robbiewd34d5812005-07-11 22:28:09 +000075 tst_brkm(TBROK, cleanup, "self_exec failed");
robbiewd34d5812005-07-11 22:28:09 +000076#else
77 do_child();
78#endif
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040079 }
plars865695b2001-08-27 22:15:12 +000080
Cyril Hrubis9f136a42015-02-17 17:16:09 +010081 TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
Cyril Hrubis25af3d22014-01-20 16:31:48 +010082 rval = setpgid(child_pid, getppid());
83 if (rval == -1 && errno == EPERM) {
84 tst_resm(TPASS, "setpgid failed with EPERM");
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040085 } else {
86 tst_resm(TFAIL,
Cyril Hrubis25af3d22014-01-20 16:31:48 +010087 "retval %d, errno %d, expected errno %d",
88 rval, errno, EPERM);
plars865695b2001-08-27 22:15:12 +000089 }
Cyril Hrubis9f136a42015-02-17 17:16:09 +010090 TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +040091
92 if (wait(&status) < 0)
93 tst_resm(TFAIL | TERRNO, "wait() for child 1 failed");
94
95 if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
96 tst_resm(TFAIL, "child 1 failed with status %d",
97 WEXITSTATUS(status));
98
Cyril Hrubis25af3d22014-01-20 16:31:48 +010099 /* Child after exec() we are no longer allowed to set pgid */
100 if ((child_pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +0000101 tst_resm(TFAIL, "Fork failed");
Garrett Cooper2c282152010-12-16 00:55:50 -0800102
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100103 if (child_pid == 0) {
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400104 if (execlp(TEST_APP, TEST_APP, NULL) < 0)
plars865695b2001-08-27 22:15:12 +0000105 perror("exec failed");
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400106
plars865695b2001-08-27 22:15:12 +0000107 exit(127);
plars865695b2001-08-27 22:15:12 +0000108 }
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400109
Cyril Hrubis9f136a42015-02-17 17:16:09 +0100110 TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100111 rval = setpgid(child_pid, getppid());
112 if (rval == -1 && errno == EACCES) {
113 tst_resm(TPASS, "setpgid failed with EACCES");
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400114 } else {
115 tst_resm(TFAIL,
Cyril Hrubis25af3d22014-01-20 16:31:48 +0100116 "retval %d, errno %d, expected errno %d",
117 rval, errno, EACCES);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400118 }
Cyril Hrubis9f136a42015-02-17 17:16:09 +0100119 TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400120
121 if (wait(&status) < 0)
122 tst_resm(TFAIL | TERRNO, "wait() for child 2 failed");
123
124 if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
125 tst_resm(TFAIL, "child 2 failed with status %d",
126 WEXITSTATUS(status));
plars865695b2001-08-27 22:15:12 +0000127 }
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400128
plars865695b2001-08-27 22:15:12 +0000129 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800130 tst_exit();
plars865695b2001-08-27 22:15:12 +0000131}
132
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400133static void do_child(void)
robbiewd34d5812005-07-11 22:28:09 +0000134{
robbiewd34d5812005-07-11 22:28:09 +0000135 if (setsid() < 0) {
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400136 printf("CHILD: setsid() failed, errno: %d\n", errno);
137 exit(2);
robbiewd34d5812005-07-11 22:28:09 +0000138 }
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400139
Cyril Hrubis9f136a42015-02-17 17:16:09 +0100140 TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400141
Cyril Hrubis9f136a42015-02-17 17:16:09 +0100142 TST_SAFE_CHECKPOINT_WAIT(NULL, 0);
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400143
144 exit(0);
robbiewd34d5812005-07-11 22:28:09 +0000145}
146
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400147static void setup(void)
plars865695b2001-08-27 22:15:12 +0000148{
plars865695b2001-08-27 22:15:12 +0000149 tst_sig(FORK, DEF_HANDLER, cleanup);
150
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400151 tst_tmpdir();
152
Cyril Hrubis9f136a42015-02-17 17:16:09 +0100153 TST_CHECKPOINT_INIT(tst_rmdir);
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400154
plars865695b2001-08-27 22:15:12 +0000155 umask(0);
156
plars865695b2001-08-27 22:15:12 +0000157 TEST_PAUSE;
158}
159
Stanislav Kholmanskikh6bfe99a2013-12-12 13:21:54 +0400160static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000161{
Stanislav Kholmanskikh52167a12013-12-12 13:21:55 +0400162 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700163}