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: pipeping2.c 8 * 9 * Description: 10 * This test runs in conjunction with the pipepong2 test. 11 * This test creates two pipes and passes two pipe fd's 12 * to the pipepong2 test. Then this test writes "ping" to 13 * to the pipepong2 test and the pipepong2 test writes "pong" 14 * back. To run this pair of tests, just invoke pipeping2. 15 * 16 * Tested areas: process creation, pipes, file descriptor 17 * inheritance. 18 */ 19 20 #include "prerror.h" 21 #include "prio.h" 22 #include "prproces.h" 23 24 #include <stdio.h> 25 #include <string.h> 26 #include <stdlib.h> 27 28 #define NUM_ITERATIONS 10 29 30 static char *child_argv[] = { "pipepong2", NULL }; 31 32 int main(int argc, char **argv) 33 { 34 PRFileDesc *in_pipe[2]; 35 PRFileDesc *out_pipe[2]; 36 PRStatus status; main(int argc,char ** argv)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 status = PR_ProcessAttrSetInheritableFD(attr, out_pipe[0], "PIPE_READ"); 83 if (status == PR_FAILURE) { 84 fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); 85 exit(1); 86 } 87 status = PR_ProcessAttrSetInheritableFD(attr, in_pipe[1], "PIPE_WRITE"); 88 if (status == PR_FAILURE) { 89 fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); 90 exit(1); 91 } 92 93 process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); 94 if (process == NULL) { 95 fprintf(stderr, "PR_CreateProcess failed\n"); 96 exit(1); 97 } 98 PR_DestroyProcessAttr(attr); 99 status = PR_Close(out_pipe[0]); 100 if (status == PR_FAILURE) { 101 fprintf(stderr, "PR_Close failed\n"); 102 exit(1); 103 } 104 status = PR_Close(in_pipe[1]); 105 if (status == PR_FAILURE) { 106 fprintf(stderr, "PR_Close failed\n"); 107 exit(1); 108 } 109 110 for (idx = 0; idx < NUM_ITERATIONS; idx++) { 111 strcpy(buf, "ping"); 112 printf("ping process: sending \"%s\"\n", buf); 113 nBytes = PR_Write(out_pipe[1], buf, 5); 114 if (nBytes == -1) { 115 fprintf(stderr, "PR_Write failed: (%d, %d)\n", 116 PR_GetError(), PR_GetOSError()); 117 exit(1); 118 } 119 memset(buf, 0, sizeof(buf)); 120 nBytes = PR_Read(in_pipe[0], buf, sizeof(buf)); 121 if (nBytes == -1) { 122 fprintf(stderr, "PR_Read failed\n"); 123 exit(1); 124 } 125 printf("ping process: received \"%s\"\n", buf); 126 if (nBytes != 5) { 127 fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", 128 nBytes); 129 exit(1); 130 } 131 if (strcmp(buf, "pong") != 0) { 132 fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", 133 buf); 134 exit(1); 135 } 136 } 137 138 status = PR_Close(in_pipe[0]); 139 if (status == PR_FAILURE) { 140 fprintf(stderr, "PR_Close failed\n"); 141 exit(1); 142 } 143 status = PR_Close(out_pipe[1]); 144 if (status == PR_FAILURE) { 145 fprintf(stderr, "PR_Close failed\n"); 146 exit(1); 147 } 148 status = PR_WaitProcess(process, &exitCode); 149 if (status == PR_FAILURE) { 150 fprintf(stderr, "PR_WaitProcess failed\n"); 151 exit(1); 152 } 153 if (exitCode == 0) { 154 printf("PASS\n"); 155 return 0; 156 } else { 157 printf("FAIL\n"); 158 return 1; 159 } 160 } 161