sockping.c (3500B)
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: sockping.c 8 * 9 * Description: 10 * This test runs in conjunction with the sockpong test. 11 * This test creates a socket pair and passes one socket 12 * to the sockpong test. Then this test writes "ping" to 13 * to the sockpong test and the sockpong test writes "pong" 14 * back. To run this pair of tests, just invoke sockping. 15 * 16 * Tested areas: process creation, socket pairs, file 17 * descriptor 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[] = {"sockpong", NULL}; 31 32 int main(int argc, char** argv) { 33 PRFileDesc* sock[2]; 34 PRStatus status; 35 PRProcess* process; 36 PRProcessAttr* attr; 37 char buf[1024]; 38 PRInt32 nBytes; 39 PRInt32 exitCode; 40 int idx; 41 42 status = PR_NewTCPSocketPair(sock); 43 if (status == PR_FAILURE) { 44 fprintf(stderr, "PR_NewTCPSocketPair failed\n"); 45 exit(1); 46 } 47 48 status = PR_SetFDInheritable(sock[0], PR_FALSE); 49 if (status == PR_FAILURE) { 50 fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", PR_GetError(), 51 PR_GetOSError()); 52 exit(1); 53 } 54 status = PR_SetFDInheritable(sock[1], PR_TRUE); 55 if (status == PR_FAILURE) { 56 fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", PR_GetError(), 57 PR_GetOSError()); 58 exit(1); 59 } 60 61 attr = PR_NewProcessAttr(); 62 if (attr == NULL) { 63 fprintf(stderr, "PR_NewProcessAttr failed\n"); 64 exit(1); 65 } 66 67 status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET"); 68 if (status == PR_FAILURE) { 69 fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); 70 exit(1); 71 } 72 73 process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); 74 if (process == NULL) { 75 fprintf(stderr, "PR_CreateProcess failed\n"); 76 exit(1); 77 } 78 PR_DestroyProcessAttr(attr); 79 status = PR_Close(sock[1]); 80 if (status == PR_FAILURE) { 81 fprintf(stderr, "PR_Close failed\n"); 82 exit(1); 83 } 84 85 for (idx = 0; idx < NUM_ITERATIONS; idx++) { 86 strcpy(buf, "ping"); 87 printf("ping process: sending \"%s\"\n", buf); 88 nBytes = PR_Write(sock[0], buf, 5); 89 if (nBytes == -1) { 90 fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), 91 PR_GetOSError()); 92 exit(1); 93 } 94 memset(buf, 0, sizeof(buf)); 95 nBytes = PR_Read(sock[0], buf, sizeof(buf)); 96 if (nBytes == -1) { 97 fprintf(stderr, "PR_Read failed: (%d, %d)\n", PR_GetError(), 98 PR_GetOSError()); 99 exit(1); 100 } 101 printf("ping process: received \"%s\"\n", buf); 102 if (nBytes != 5) { 103 fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", 104 nBytes); 105 exit(1); 106 } 107 if (strcmp(buf, "pong") != 0) { 108 fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", buf); 109 exit(1); 110 } 111 } 112 113 status = PR_Close(sock[0]); 114 if (status == PR_FAILURE) { 115 fprintf(stderr, "PR_Close failed\n"); 116 exit(1); 117 } 118 status = PR_WaitProcess(process, &exitCode); 119 if (status == PR_FAILURE) { 120 fprintf(stderr, "PR_WaitProcess failed\n"); 121 exit(1); 122 } 123 if (exitCode == 0) { 124 printf("PASS\n"); 125 return 0; 126 } else { 127 printf("FAIL\n"); 128 return 1; 129 } 130 }