pipeping.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. * File: pipeping.c
  7. *
  8. * Description:
  9. * This test runs in conjunction with the pipepong test.
  10. * This test creates two pipes and redirects the stdin and
  11. * stdout of the pipepong test to the pipes. Then this
  12. * test writes "ping" to the pipepong test and the pipepong
  13. * test writes "pong" back. To run this pair of tests,
  14. * just invoke pipeping.
  15. *
  16. * Tested areas: process creation, pipes, file descriptor
  17. * inheritance, standard I/O redirection.
  18. */
  19. #include "prerror.h"
  20. #include "prio.h"
  21. #include "prproces.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #ifdef XP_OS2
  26. static char *child_argv[] = { "pipepong.exe", NULL };
  27. #else
  28. static char *child_argv[] = { "pipepong", NULL };
  29. #endif
  30. #define NUM_ITERATIONS 10
  31. int main(int argc, char **argv)
  32. {
  33. PRFileDesc *in_pipe[2];
  34. PRFileDesc *out_pipe[2];
  35. PRStatus status;
  36. PRProcess *process;
  37. PRProcessAttr *attr;
  38. char buf[1024];
  39. PRInt32 nBytes;
  40. PRInt32 exitCode;
  41. int idx;
  42. status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
  43. if (status == PR_FAILURE) {
  44. fprintf(stderr, "PR_CreatePipe failed\n");
  45. exit(1);
  46. }
  47. status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
  48. if (status == PR_FAILURE) {
  49. fprintf(stderr, "PR_CreatePipe failed\n");
  50. exit(1);
  51. }
  52. status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
  53. if (status == PR_FAILURE) {
  54. fprintf(stderr, "PR_SetFDInheritable failed\n");
  55. exit(1);
  56. }
  57. status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
  58. if (status == PR_FAILURE) {
  59. fprintf(stderr, "PR_SetFDInheritable failed\n");
  60. exit(1);
  61. }
  62. status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
  63. if (status == PR_FAILURE) {
  64. fprintf(stderr, "PR_SetFDInheritable failed\n");
  65. exit(1);
  66. }
  67. status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
  68. if (status == PR_FAILURE) {
  69. fprintf(stderr, "PR_SetFDInheritable failed\n");
  70. exit(1);
  71. }
  72. attr = PR_NewProcessAttr();
  73. if (attr == NULL) {
  74. fprintf(stderr, "PR_NewProcessAttr failed\n");
  75. exit(1);
  76. }
  77. PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]);
  78. PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]);
  79. process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
  80. if (process == NULL) {
  81. fprintf(stderr, "PR_CreateProcess failed\n");
  82. exit(1);
  83. }
  84. PR_DestroyProcessAttr(attr);
  85. status = PR_Close(out_pipe[0]);
  86. if (status == PR_FAILURE) {
  87. fprintf(stderr, "PR_Close failed\n");
  88. exit(1);
  89. }
  90. status = PR_Close(in_pipe[1]);
  91. if (status == PR_FAILURE) {
  92. fprintf(stderr, "PR_Close failed\n");
  93. exit(1);
  94. }
  95. for (idx = 0; idx < NUM_ITERATIONS; idx++) {
  96. strcpy(buf, "ping");
  97. printf("ping process: sending \"%s\"\n", buf);
  98. nBytes = PR_Write(out_pipe[1], buf, 5);
  99. if (nBytes == -1) {
  100. fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
  101. PR_GetOSError());
  102. exit(1);
  103. }
  104. memset(buf, 0, sizeof(buf));
  105. nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
  106. if (nBytes == -1) {
  107. fprintf(stderr, "PR_Read failed: (%d, %d)\n",
  108. PR_GetError(), PR_GetOSError());
  109. exit(1);
  110. }
  111. printf("ping process: received \"%s\"\n", buf);
  112. if (nBytes != 5) {
  113. fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
  114. nBytes);
  115. exit(1);
  116. }
  117. if (strcmp(buf, "pong") != 0) {
  118. fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
  119. buf);
  120. exit(1);
  121. }
  122. }
  123. status = PR_Close(in_pipe[0]);
  124. if (status == PR_FAILURE) {
  125. fprintf(stderr, "PR_Close failed\n");
  126. exit(1);
  127. }
  128. status = PR_Close(out_pipe[1]);
  129. if (status == PR_FAILURE) {
  130. fprintf(stderr, "PR_Close failed\n");
  131. exit(1);
  132. }
  133. status = PR_WaitProcess(process, &exitCode);
  134. if (status == PR_FAILURE) {
  135. fprintf(stderr, "PR_WaitProcess failed\n");
  136. exit(1);
  137. }
  138. if (exitCode == 0) {
  139. printf("PASS\n");
  140. return 0;
  141. } else {
  142. printf("FAIL\n");
  143. return 1;
  144. }
  145. }