windows-nt/Source/XPSP1/NT/base/subsys/posix/client/tst/tstsid.c
2020-09-26 16:20:57 +08:00

285 lines
4.4 KiB
C

#include <nt.h>
#include <ntrtl.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include "tsttmp.h" // defines DbgPrint as printf
extern int errno;
VOID setsid0(VOID);
VOID setpgid0(VOID);
VOID kill0(VOID);
VOID waitpid0(VOID);
int __cdecl main(int argc, char *argv[])
{
pid_t self;
PCH p,t;
PTEB ThreadInfo;
ThreadInfo = NtCurrentTeb();
self = getpid();
DbgPrint("setsidt: My pid is %lx Argc = %lx\n",self,argc);
DbgPrint("setsidt: StackBase %lx\n",ThreadInfo->NtTib.StackBase);
DbgPrint("setsidt: StackLimit %lx\n",ThreadInfo->NtTib.StackLimit);
DbgPrint("setsidt: ClientId %lx.%lx\n",ThreadInfo->ClientId.UniqueProcess,ThreadInfo->ClientId.UniqueThread);
while(argc--){
p = *argv++;
t = p;
while(*t++);
DbgPrint("Argv --> %s\n",p);
}
setsid0();
setpgid0();
kill0();
waitpid0();
return 1;
}
VOID
setsid0()
{
pid_t pid, OrigGroup, NewGroup;
DbgPrint("setsid0:++\n");
OrigGroup = getpgrp();
//
// Should be process group leader
//
ASSERT(getpid() == OrigGroup);
NewGroup = setsid();
ASSERT(NewGroup == -1 && errno == EPERM);
//
// Fork. Child then creates a new session id
//
if ( !fork() ) {
pid = getpid();
ASSERT(getpgrp() == OrigGroup);
ASSERT(pid != OrigGroup);
NewGroup = setsid();
ASSERT(NewGroup == pid);
ASSERT(getpgrp() == pid);
_exit(1);
}
wait(NULL);
DbgPrint("setsid0:--\n");
}
VOID
setpgid0()
{
pid_t OrigGroup, child;
int rc;
DbgPrint("setpgid0:++\n");
OrigGroup = getpgrp();
//
// Bad pid gives EINVAL
//
rc = setpgid(-1,0);
ASSERT(rc == -1 && errno == EINVAL);
//
// Bogus pid gives ESRCH
//
rc = setpgid(1,0);
ASSERT(rc == -1 && errno == ESRCH);
//
// Self (at this level gives EPERM because I am a session leader)
//
rc = setpgid(0,0);
ASSERT(rc == -1 && errno == EPERM);
child = fork();
if ( !child) {
child = fork();
if ( !child ) {
pause();
}
//
// Make sure child is not in same session as caller. Then try to
// set it's group id.
//
setsid();
rc = setpgid(child,0);
ASSERT(rc == -1 && errno == EPERM);
kill(child,SIGKILL);
wait(NULL);
_exit(2);
}
wait(NULL);
DbgPrint("setpgid0:--\n");
}
VOID
kill0()
{
pid_t parent, parentgroup, OrigGroup, child;
int rc;
DbgPrint("kill0:++\n");
OrigGroup = getpgrp();
child = fork();
if ( !child) {
//
// Change to a new process group
//
rc = setpgid(0,0);
ASSERT(rc == 0);
child = fork();
if ( !child ) {
struct sigaction act;
act.sa_handler = SIG_IGN;
rc = sigaction(SIGHUP, &act, NULL);
ASSERT( rc == 0 );
parentgroup = getpgrp();
//
// Change to a new process group
//
rc = setpgid(0,0);
ASSERT(rc == 0);
//
// Kill Parent by process group
//
parent = getppid();
rc = kill(-1 * parentgroup,SIGKILL);
ASSERT(rc == 0 && getppid() != parent );
_exit(1);
}
DbgPrint("kill0: Pid to die %lx Child (that will killed) %lx\n",getpid(),child);
pause();
}
DbgPrint("kill0: Pid %lx Child (to be killed) %lx\n",getpid(),child);
wait(NULL);
sleep(4);
DbgPrint("kill0:--\n");
}
VOID
waitpid0()
{
pid_t child;
int rc;
DbgPrint("waitpid0:++\n");
//
// Test for existing group with no children
//
rc = waitpid(0,NULL,0);
ASSERT(rc == -1 && errno == ECHILD);
//
// Test for non-existing group with no children
//
rc = waitpid(0x12345678,NULL,0);
ASSERT(rc == -1 && errno == ECHILD);
//
// Test for bad options
//
rc = waitpid(0,NULL,0x12345678);
ASSERT(rc == -1 && errno == EINVAL);
child = fork();
if ( !child) {
_exit(1);
}
sleep(5);
//
// test for specific pid
//
DbgPrint("waiting on %lx\n",child);
rc = waitpid(child,NULL,0);
ASSERT(rc == child);
DbgPrint("waitpid0:--\n");
}