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.

420 lines
7.7 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <errno.h>
  6. #include <sys/wait.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <sys/stat.h>
  10. #include "tsttmp.h" // defines DbgPrint as printf
  11. extern int errno;
  12. VOID npipe0(char *);
  13. VOID npipe1(char *);
  14. VOID npipe2(char *);
  15. VOID npipe3(char *);
  16. VOID npipe4(char *);
  17. VOID npipe5(VOID);
  18. //
  19. // 'tstnpipe named.pip'.
  20. //
  21. // The directory /psx/test is used as the base directory. The zero-length
  22. // file named 'named.pip must exist in that directory.
  23. //
  24. char
  25. nulltouch(char *f)
  26. {
  27. return 'a';
  28. }
  29. int
  30. main(int argc, char *argv[])
  31. {
  32. if (argc != 2) {
  33. DbgPrint("Usage: 'tstnpipe named.pip'\n");
  34. return 1;
  35. }
  36. ASSERT(strcmp(argv[1],"named.pip") == 0);
  37. npipe0(argv[1]);
  38. npipe1(argv[1]);
  39. npipe2(argv[1]);
  40. npipe3(argv[1]);
  41. npipe4(argv[1]);
  42. npipe5();
  43. return 1;
  44. }
  45. VOID
  46. npipe0(char *f)
  47. {
  48. int rc,wfd,rfd;
  49. char buf[512];
  50. DbgPrint("npipe0:++ %s\n",f);
  51. nulltouch(f);
  52. //
  53. // Open for read with NONBLOCK. Open should complete
  54. // without delay.
  55. //
  56. rfd = open(f, O_RDONLY | O_NONBLOCK);
  57. ASSERT(rfd != -1);
  58. //
  59. // Since there is no data in pipe, read should complete and
  60. // return 0 as the byte count.
  61. //
  62. rc = read(rfd,buf,512);
  63. ASSERT(rc == 0);
  64. //
  65. // Open for write with NONBLOCK. Should succeed
  66. //
  67. wfd = open(f,O_WRONLY | O_NONBLOCK);
  68. ASSERT(wfd != -1);
  69. rc = write(wfd,"Hello World\n",13);
  70. ASSERT(rc == 13);
  71. rc = read(rfd,buf,512);
  72. ASSERT(rc == 13 && (strcmp(buf,"Hello World\n") == 0 ));
  73. rc = close(rfd);
  74. ASSERT(rc != -1);
  75. rc = close(wfd);
  76. ASSERT(rc != -1);
  77. //
  78. // Open for write with NONBLOCK. Should fail since read handle was
  79. // closed.
  80. //
  81. wfd = open(f,O_WRONLY | O_NONBLOCK);
  82. ASSERT(wfd == -1 && errno == ENXIO);
  83. DbgPrint("npipe0:--\n");
  84. }
  85. VOID
  86. npipe1(char *f)
  87. {
  88. int rc,wfd,rfd,stat_loc;
  89. pid_t child;
  90. char buf[512];
  91. DbgPrint("npipe1:++ %s\n",f);
  92. wfd = open("foobar.bad",O_WRONLY);
  93. nulltouch(f);
  94. child = fork();
  95. nulltouch(f);
  96. //
  97. // Make sure that in the simple case,
  98. // the named pipe open protocol works
  99. //
  100. if ( child == 0 ) {
  101. rfd = open(f,O_RDONLY);
  102. ASSERT(rfd != -1);
  103. rc = read(rfd,buf,512);
  104. ASSERT(rc == 13 && (strcmp(buf,"Hello World\n") == 0 ));
  105. _exit(rc);
  106. }
  107. wfd = open(f,O_WRONLY);
  108. ASSERT(wfd != -1);
  109. rc = write(wfd,"Hello World\n",13);
  110. ASSERT(rc == 13);
  111. rc = waitpid(child,&stat_loc,0);
  112. ASSERT(rc == child && WIFEXITED(stat_loc) && WEXITSTATUS(stat_loc) == 13);
  113. rc = close(wfd);
  114. ASSERT(rc != -1);
  115. //
  116. // Open for write with NONBLOCK. Should fail since read handle was
  117. // closed by childs process exit.
  118. //
  119. wfd = open(f,O_WRONLY | O_NONBLOCK);
  120. ASSERT(wfd == -1 && errno == ENXIO);
  121. DbgPrint("npipe1:--\n");
  122. }
  123. VOID
  124. npipe2(char *f)
  125. {
  126. int rc,wfd,rfd,rfd2,stat_loc;
  127. pid_t child1,child2;
  128. char buf[512];
  129. DbgPrint("npipe2:++ %s\n",f);
  130. nulltouch(f);
  131. child1 = fork();
  132. nulltouch(f);
  133. //
  134. // Make sure that if we have a case where two readers open the
  135. // pipe, one writers open will catch them both
  136. //
  137. if ( child1 == 0 ) {
  138. nulltouch(f);
  139. child2 = fork();
  140. nulltouch(f);
  141. if ( child2 == 0 ) {
  142. rfd2 = open(f,O_RDONLY);
  143. ASSERT(rfd != -1);
  144. rc = read(rfd2,buf,512);
  145. ASSERT(rc == 13 && (strcmp(buf,"Hello World\n") == 0 ));
  146. _exit(rc);
  147. }
  148. rfd = open(f,O_RDONLY);
  149. ASSERT(rfd != -1);
  150. rc = waitpid(child2,&stat_loc,0);
  151. ASSERT(rc == child2 && WIFEXITED(stat_loc) && WEXITSTATUS(stat_loc) == 13);
  152. _exit(WEXITSTATUS(stat_loc));
  153. }
  154. sleep(30);
  155. wfd = open(f,O_WRONLY);
  156. ASSERT(wfd != -1);
  157. rc = write(wfd,"Hello World\n",13);
  158. ASSERT(rc == 13);
  159. rc = waitpid(child1,&stat_loc,0);
  160. ASSERT(rc == child1 && WIFEXITED(stat_loc) && WEXITSTATUS(stat_loc) == 13);
  161. rc = close(wfd);
  162. ASSERT(rc != -1);
  163. //
  164. // Open for write with NONBLOCK. Should fail since read handle was
  165. // closed by childs process exit.
  166. //
  167. wfd = open(f,O_WRONLY | O_NONBLOCK);
  168. ASSERT(wfd == -1 && errno == ENXIO);
  169. DbgPrint("npipe2:--\n");
  170. }
  171. void
  172. npipe3_handler(
  173. IN int sig
  174. )
  175. {
  176. int wfd;
  177. ASSERT(sig == SIGUSR1);
  178. wfd = open("named.pip",O_WRONLY | O_NONBLOCK);
  179. ASSERT(wfd == -1 && errno == ENXIO);
  180. }
  181. VOID
  182. npipe3(char *f)
  183. {
  184. int rc,wfd,rfd,stat_loc;
  185. pid_t child;
  186. struct sigaction act;
  187. DbgPrint("npipe3:++ %s\n",f);
  188. nulltouch(f);
  189. child = fork();
  190. nulltouch(f);
  191. //
  192. // While child is blocked in open, terminate him with a signal
  193. // and make sure everything is ok.
  194. //
  195. if ( child == 0 ) {
  196. rfd = open(f,O_RDONLY);
  197. ASSERT(FALSE);
  198. }
  199. sleep(20);
  200. rc = kill(child,SIGKILL);
  201. ASSERT(rc==0);
  202. rc = waitpid(child,&stat_loc,0);
  203. ASSERT(rc == child && WIFSIGNALED(stat_loc) && WTERMSIG(stat_loc) == SIGKILL);
  204. wfd = open(f,O_WRONLY | O_NONBLOCK);
  205. ASSERT(wfd == -1 && errno == ENXIO);
  206. //
  207. // Now Try again. This time send a signal that child catches. He should
  208. // come back from his open with EINTR and the pipe should not be left
  209. // open.
  210. //
  211. nulltouch(f);
  212. child = fork();
  213. nulltouch(f);
  214. //
  215. // While child is blocked in open, terminate him with a signal
  216. // and make sure everything is ok.
  217. //
  218. act.sa_flags = 0;
  219. sigfillset(&act.sa_mask);
  220. act.sa_handler = npipe3_handler;
  221. rc = sigaction(SIGUSR1, &act, NULL);
  222. ASSERT( rc == 0 );
  223. if ( child == 0 ) {
  224. rfd = open(f,O_RDONLY);
  225. ASSERT(rfd == -1 && errno == EINTR);
  226. wfd = open(f,O_WRONLY | O_NONBLOCK);
  227. ASSERT(wfd == -1 && errno == ENXIO);
  228. rc = kill(getpid(),SIGKILL);
  229. ASSERT(FALSE);
  230. }
  231. sleep(20);
  232. rc = kill(child,SIGUSR1);
  233. ASSERT(rc==0);
  234. rc = waitpid(child,&stat_loc,0);
  235. ASSERT(rc == child && WIFSIGNALED(stat_loc) && WTERMSIG(stat_loc) == SIGKILL);
  236. wfd = open(f,O_WRONLY | O_NONBLOCK);
  237. ASSERT(wfd == -1 && errno == ENXIO);
  238. DbgPrint("npipe3:--\n");
  239. }
  240. VOID
  241. npipe4(char *f)
  242. {
  243. int rc,rfd;
  244. int fildes[2];
  245. off_t off;
  246. DbgPrint("npipe4:++ %s\n",f);
  247. nulltouch(f);
  248. //
  249. // Open for read with NONBLOCK. Open should complete
  250. // without delay.
  251. //
  252. rfd = open(f,O_RDONLY | O_NONBLOCK);
  253. ASSERT(rfd != -1);
  254. //
  255. // lseek on named pipe should fail
  256. //
  257. off = (off_t) 1;
  258. errno = 0;
  259. off = lseek(rfd,off,SEEK_SET);
  260. ASSERT(off == -1 && errno == ESPIPE);
  261. rc = close(rfd);
  262. ASSERT(rc != -1);
  263. rc = pipe(fildes);
  264. ASSERT(rc == 0);
  265. //
  266. // lseek on regular pipe should fail
  267. //
  268. off = (off_t)11;
  269. errno = 0;
  270. off = lseek(fildes[0],off,SEEK_SET);
  271. ASSERT(off == -1 && errno == ESPIPE);
  272. off = 10;
  273. errno = 0;
  274. off = lseek(fildes[1],off,SEEK_SET);
  275. ASSERT(off == -1 && errno == ESPIPE);
  276. DbgPrint("npipe4:--\n");
  277. }
  278. VOID
  279. npipe5()
  280. {
  281. int rc,rfd;
  282. off_t off;
  283. DbgPrint("npipe5:++\n");
  284. rc = mkfifo("xpipe.pip",0);
  285. ASSERT(rc==0 || ( rc == -1 && errno == EEXIST ) );
  286. if ( rc == -1 ) {
  287. DbgPrint("npipe5: **** Warning Fifo Exists ****\n");
  288. }
  289. //
  290. // Open for read with NONBLOCK. Open should complete
  291. // without delay.
  292. //
  293. rfd = open("xpipe.pip",O_RDONLY | O_NONBLOCK);
  294. ASSERT(rfd != -1);
  295. //
  296. // lseek on named pipe should fail
  297. //
  298. off = 1;
  299. errno = 0;
  300. off = lseek(rfd,off,SEEK_SET);
  301. ASSERT(off == -1 && errno == ESPIPE);
  302. rc = close(rfd);
  303. ASSERT(rc != -1);
  304. DbgPrint("npipe5:--\n");
  305. }