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