Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
4.4 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <signal.h>
  4. #include <errno.h>
  5. #include <sys/wait.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <stdio.h>
  9. #include "tsttmp.h" // defines DbgPrint as printf
  10. extern int errno;
  11. VOID setsid0(VOID);
  12. VOID setpgid0(VOID);
  13. VOID kill0(VOID);
  14. VOID waitpid0(VOID);
  15. int __cdecl main(int argc, char *argv[])
  16. {
  17. pid_t self;
  18. PCH p,t;
  19. PTEB ThreadInfo;
  20. ThreadInfo = NtCurrentTeb();
  21. self = getpid();
  22. DbgPrint("setsidt: My pid is %lx Argc = %lx\n",self,argc);
  23. DbgPrint("setsidt: StackBase %lx\n",ThreadInfo->NtTib.StackBase);
  24. DbgPrint("setsidt: StackLimit %lx\n",ThreadInfo->NtTib.StackLimit);
  25. DbgPrint("setsidt: ClientId %lx.%lx\n",ThreadInfo->ClientId.UniqueProcess,ThreadInfo->ClientId.UniqueThread);
  26. while(argc--){
  27. p = *argv++;
  28. t = p;
  29. while(*t++);
  30. DbgPrint("Argv --> %s\n",p);
  31. }
  32. setsid0();
  33. setpgid0();
  34. kill0();
  35. waitpid0();
  36. return 1;
  37. }
  38. VOID
  39. setsid0()
  40. {
  41. pid_t pid, OrigGroup, NewGroup;
  42. DbgPrint("setsid0:++\n");
  43. OrigGroup = getpgrp();
  44. //
  45. // Should be process group leader
  46. //
  47. ASSERT(getpid() == OrigGroup);
  48. NewGroup = setsid();
  49. ASSERT(NewGroup == -1 && errno == EPERM);
  50. //
  51. // Fork. Child then creates a new session id
  52. //
  53. if ( !fork() ) {
  54. pid = getpid();
  55. ASSERT(getpgrp() == OrigGroup);
  56. ASSERT(pid != OrigGroup);
  57. NewGroup = setsid();
  58. ASSERT(NewGroup == pid);
  59. ASSERT(getpgrp() == pid);
  60. _exit(1);
  61. }
  62. wait(NULL);
  63. DbgPrint("setsid0:--\n");
  64. }
  65. VOID
  66. setpgid0()
  67. {
  68. pid_t OrigGroup, child;
  69. int rc;
  70. DbgPrint("setpgid0:++\n");
  71. OrigGroup = getpgrp();
  72. //
  73. // Bad pid gives EINVAL
  74. //
  75. rc = setpgid(-1,0);
  76. ASSERT(rc == -1 && errno == EINVAL);
  77. //
  78. // Bogus pid gives ESRCH
  79. //
  80. rc = setpgid(1,0);
  81. ASSERT(rc == -1 && errno == ESRCH);
  82. //
  83. // Self (at this level gives EPERM because I am a session leader)
  84. //
  85. rc = setpgid(0,0);
  86. ASSERT(rc == -1 && errno == EPERM);
  87. child = fork();
  88. if ( !child) {
  89. child = fork();
  90. if ( !child ) {
  91. pause();
  92. }
  93. //
  94. // Make sure child is not in same session as caller. Then try to
  95. // set it's group id.
  96. //
  97. setsid();
  98. rc = setpgid(child,0);
  99. ASSERT(rc == -1 && errno == EPERM);
  100. kill(child,SIGKILL);
  101. wait(NULL);
  102. _exit(2);
  103. }
  104. wait(NULL);
  105. DbgPrint("setpgid0:--\n");
  106. }
  107. VOID
  108. kill0()
  109. {
  110. pid_t parent, parentgroup, OrigGroup, child;
  111. int rc;
  112. DbgPrint("kill0:++\n");
  113. OrigGroup = getpgrp();
  114. child = fork();
  115. if ( !child) {
  116. //
  117. // Change to a new process group
  118. //
  119. rc = setpgid(0,0);
  120. ASSERT(rc == 0);
  121. child = fork();
  122. if ( !child ) {
  123. struct sigaction act;
  124. act.sa_handler = SIG_IGN;
  125. rc = sigaction(SIGHUP, &act, NULL);
  126. ASSERT( rc == 0 );
  127. parentgroup = getpgrp();
  128. //
  129. // Change to a new process group
  130. //
  131. rc = setpgid(0,0);
  132. ASSERT(rc == 0);
  133. //
  134. // Kill Parent by process group
  135. //
  136. parent = getppid();
  137. rc = kill(-1 * parentgroup,SIGKILL);
  138. ASSERT(rc == 0 && getppid() != parent );
  139. _exit(1);
  140. }
  141. DbgPrint("kill0: Pid to die %lx Child (that will killed) %lx\n",getpid(),child);
  142. pause();
  143. }
  144. DbgPrint("kill0: Pid %lx Child (to be killed) %lx\n",getpid(),child);
  145. wait(NULL);
  146. sleep(4);
  147. DbgPrint("kill0:--\n");
  148. }
  149. VOID
  150. waitpid0()
  151. {
  152. pid_t child;
  153. int rc;
  154. DbgPrint("waitpid0:++\n");
  155. //
  156. // Test for existing group with no children
  157. //
  158. rc = waitpid(0,NULL,0);
  159. ASSERT(rc == -1 && errno == ECHILD);
  160. //
  161. // Test for non-existing group with no children
  162. //
  163. rc = waitpid(0x12345678,NULL,0);
  164. ASSERT(rc == -1 && errno == ECHILD);
  165. //
  166. // Test for bad options
  167. //
  168. rc = waitpid(0,NULL,0x12345678);
  169. ASSERT(rc == -1 && errno == EINVAL);
  170. child = fork();
  171. if ( !child) {
  172. _exit(1);
  173. }
  174. sleep(5);
  175. //
  176. // test for specific pid
  177. //
  178. DbgPrint("waiting on %lx\n",child);
  179. rc = waitpid(child,NULL,0);
  180. ASSERT(rc == child);
  181. DbgPrint("waitpid0:--\n");
  182. }