#include #include #include #include #include #include #include #include #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"); }