mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
139 lines
3.2 KiB
C
139 lines
3.2 KiB
C
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
#include "../network/test.h"
|
|
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
|
|
static pid_t current;
|
|
static pid_t child1, child2;
|
|
|
|
FN_SETUP(setpgrp)
|
|
{
|
|
CHECK(setpgid(0, 0));
|
|
}
|
|
END_SETUP()
|
|
|
|
FN_SETUP(spawn_child)
|
|
{
|
|
current = CHECK(getpid());
|
|
|
|
if ((child1 = CHECK(fork())) == 0) {
|
|
sleep(60);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ((child2 = CHECK(fork())) == 0) {
|
|
sleep(60);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
END_SETUP()
|
|
|
|
FN_TEST(setpgid_invalid)
|
|
{
|
|
// Non-present process groups
|
|
TEST_ERRNO(setpgid(child1, child2), EPERM);
|
|
TEST_ERRNO(setpgid(child2, child1), EPERM);
|
|
TEST_ERRNO(setpgid(child1, 0x3c3c3c3c), EPERM);
|
|
TEST_ERRNO(setpgid(child2, 0x3c3c3c3c), EPERM);
|
|
|
|
// Non-present processes
|
|
TEST_ERRNO(setpgid(0x3c3c3c3c, current), ESRCH);
|
|
TEST_ERRNO(setpgid(0x3c3c3c3c, current), ESRCH);
|
|
|
|
// Non-current and non-child processes
|
|
TEST_ERRNO(setpgid(getppid(), 0), ESRCH);
|
|
TEST_ERRNO(setpgid(getppid(), 0x3c3c3c3c), ESRCH);
|
|
}
|
|
END_TEST()
|
|
|
|
FN_TEST(setpgid)
|
|
{
|
|
// PGID members
|
|
// | |
|
|
// v v
|
|
// Process groups: [current] = { current, child1, child2 }
|
|
|
|
TEST_SUCC(setpgid(0, 0));
|
|
TEST_SUCC(setpgid(0, current));
|
|
TEST_SUCC(setpgid(current, 0));
|
|
TEST_SUCC(setpgid(current, getpid()));
|
|
|
|
TEST_ERRNO(setpgid(child1, child2), EPERM);
|
|
TEST_ERRNO(setpgid(child2, child1), EPERM);
|
|
|
|
// Process groups: [current] = { current, child2 }, [child1] = { child1 }
|
|
TEST_SUCC(setpgid(child1, 0));
|
|
|
|
// Process groups: [current] = { current }, [child1] = { child1, child2 }
|
|
TEST_SUCC(setpgid(child2, child1));
|
|
|
|
// Process groups: [current] = { current, child1 }, [child1] = { child2 }
|
|
TEST_SUCC(setpgid(child1, current));
|
|
|
|
// Process groups: [current] = { current }, [child1] = { child1, child2 }
|
|
TEST_SUCC(setpgid(child1, child1));
|
|
}
|
|
END_TEST()
|
|
|
|
FN_TEST(setsid_group_leader)
|
|
{
|
|
// Process groups: [current] = { current }, [child1] = { child1, child2 }
|
|
|
|
TEST_ERRNO(setsid(), EPERM);
|
|
|
|
// Process groups: [current] = { child1 }, [child1] = { current, child2 }
|
|
TEST_SUCC(setpgid(child1, current));
|
|
TEST_SUCC(setpgid(current, child1));
|
|
|
|
TEST_ERRNO(setsid(), EPERM);
|
|
}
|
|
END_TEST()
|
|
|
|
FN_TEST(setsid)
|
|
{
|
|
// Process groups: [child1] = { current, child1, child2 }
|
|
TEST_SUCC(setpgid(child1, child1));
|
|
|
|
// Process groups (old session): [child1] = { child1, child2 }
|
|
// Process groups (new session): [current] = { current }
|
|
TEST_SUCC(setsid());
|
|
}
|
|
END_TEST()
|
|
|
|
// From now on, the current process and the child processes are in two sessions!
|
|
|
|
FN_TEST(setsid_session_leader)
|
|
{
|
|
// FIXME: We fail this test to work around a gVisor bug.
|
|
// See comments in `Process::to_new_session` for details.
|
|
//
|
|
// TEST_ERRNO(setsid(), EPERM);
|
|
}
|
|
END_TEST()
|
|
|
|
FN_TEST(setpgid_two_sessions)
|
|
{
|
|
// Setting process groups in another session should never succeed
|
|
|
|
TEST_ERRNO(setpgid(child1, child1), EPERM);
|
|
TEST_ERRNO(setpgid(child2, child2), EPERM);
|
|
|
|
TEST_ERRNO(setpgid(child1, current), EPERM);
|
|
TEST_ERRNO(setpgid(child2, current), EPERM);
|
|
|
|
TEST_ERRNO(setpgid(child2, child1), EPERM);
|
|
}
|
|
END_TEST()
|
|
|
|
FN_SETUP(kill_child)
|
|
{
|
|
CHECK(kill(child1, SIGKILL));
|
|
CHECK_WITH(wait(NULL), _ret == child1);
|
|
|
|
CHECK(kill(child2, SIGKILL));
|
|
CHECK_WITH(wait(NULL), _ret == child2);
|
|
}
|
|
END_SETUP()
|