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: pipeself.c
8  *
9  * Description:
10  * This test has two threads communicating with each other using
11  * two unidirectional pipes.  The primordial thread is the ping
12  * thread and the other thread is the pong thread.  The ping
13  * thread writes "ping" to the pong thread and the pong thread
14  * writes "pong" back.
15  */
16 
17 #include "prio.h"
18 #include "prerror.h"
19 #include "prthread.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #define NUM_ITERATIONS 10
26 
27 static PRFileDesc *ping_in, *ping_out;
28 static PRFileDesc *pong_in, *pong_out;
29 
PongThreadFunc(void * arg)30 static void PongThreadFunc(void *arg)
31 {
32     char buf[1024];
33     int idx;
34     PRInt32 nBytes;
35     PRStatus status;
36 
37     for (idx = 0; idx < NUM_ITERATIONS; idx++) {
38         memset(buf, 0, sizeof(buf));
39         nBytes = PR_Read(pong_in, buf, sizeof(buf));
40         if (nBytes == -1) {
41             fprintf(stderr, "PR_Read failed\n");
42             exit(1);
43         }
44         printf("pong thread: received \"%s\"\n", buf);
45         if (nBytes != 5) {
46             fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n",
47                     nBytes);
48             exit(1);
49         }
50         if (strcmp(buf, "ping") != 0) {
51             fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n",
52                     buf);
53             exit(1);
54         }
55         strcpy(buf, "pong");
56         printf("pong thread: sending \"%s\"\n", buf);
57         nBytes = PR_Write(pong_out, buf, 5);
58         if (nBytes == -1) {
59             fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
60                     PR_GetOSError());
61             exit(1);
62         }
63     }
64 
65     status = PR_Close(pong_in);
66     if (status == PR_FAILURE) {
67         fprintf(stderr, "PR_Close failed\n");
68         exit(1);
69     }
70     status = PR_Close(pong_out);
71     if (status == PR_FAILURE) {
72         fprintf(stderr, "PR_Close failed\n");
73         exit(1);
74     }
75 }
76 
main(int argc,char ** argv)77 int main(int argc, char **argv)
78 {
79     PRStatus status;
80     PRThread *pongThread;
81     char buf[1024];
82     PRInt32 nBytes;
83     int idx;
84 
85     status = PR_CreatePipe(&ping_in, &pong_out);
86     if (status == PR_FAILURE) {
87         fprintf(stderr, "PR_CreatePipe failed\n");
88         exit(1);
89     }
90     status = PR_CreatePipe(&pong_in, &ping_out);
91     if (status == PR_FAILURE) {
92         fprintf(stderr, "PR_CreatePipe failed\n");
93         exit(1);
94     }
95 
96     pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL,
97             PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
98     if (pongThread == NULL) {
99         fprintf(stderr, "PR_CreateThread failed\n");
100         exit(1);
101     }
102 
103     for (idx = 0; idx < NUM_ITERATIONS; idx++) {
104         strcpy(buf, "ping");
105         printf("ping thread: sending \"%s\"\n", buf);
106         nBytes = PR_Write(ping_out, buf, 5);
107         if (nBytes == -1) {
108             fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
109                     PR_GetOSError());
110             exit(1);
111         }
112         memset(buf, 0, sizeof(buf));
113         nBytes = PR_Read(ping_in, buf, sizeof(buf));
114         if (nBytes == -1) {
115             fprintf(stderr, "PR_Read failed\n");
116             exit(1);
117         }
118         printf("ping thread: received \"%s\"\n", buf);
119         if (nBytes != 5) {
120             fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n",
121                     nBytes);
122             exit(1);
123         }
124         if (strcmp(buf, "pong") != 0) {
125             fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n",
126                     buf);
127             exit(1);
128         }
129     }
130 
131     status = PR_Close(ping_in);
132     if (status == PR_FAILURE) {
133         fprintf(stderr, "PR_Close failed\n");
134         exit(1);
135     }
136     status = PR_Close(ping_out);
137     if (status == PR_FAILURE) {
138         fprintf(stderr, "PR_Close failed\n");
139         exit(1);
140     }
141     status = PR_JoinThread(pongThread);
142     if (status == PR_FAILURE) {
143         fprintf(stderr, "PR_JoinThread failed\n");
144         exit(1);
145     }
146 
147 #if defined(XP_UNIX) && !defined(SYMBIAN)
148 	/*
149 	 * Test PR_Available for pipes
150 	 */
151     status = PR_CreatePipe(&ping_in, &ping_out);
152     if (status == PR_FAILURE) {
153         fprintf(stderr, "PR_CreatePipe failed\n");
154         exit(1);
155     }
156 	nBytes = PR_Write(ping_out, buf, 250);
157 	if (nBytes == -1) {
158 		fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
159 				PR_GetOSError());
160 		exit(1);
161 	}
162 	nBytes = PR_Available(ping_in);
163 	if (nBytes < 0) {
164 		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
165 				PR_GetOSError());
166 		exit(1);
167 	} else if (nBytes != 250) {
168 		fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n",
169 				nBytes);
170 		exit(1);
171 	}
172 	printf("PR_Available: expected %d, got %d bytes\n",250, nBytes);
173 	/* read some data */
174 	nBytes = PR_Read(ping_in, buf, 7);
175 	if (nBytes == -1) {
176 		fprintf(stderr, "PR_Read failed\n");
177 		exit(1);
178 	}
179 	/* check available data */
180 	nBytes = PR_Available(ping_in);
181 	if (nBytes < 0) {
182 		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
183 				PR_GetOSError());
184 		exit(1);
185 	} else if (nBytes != (250 - 7)) {
186 		fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n",
187 				nBytes);
188 		exit(1);
189 	}
190 	printf("PR_Available: expected %d, got %d bytes\n",243, nBytes);
191 	/* read all data */
192 	nBytes = PR_Read(ping_in, buf, sizeof(buf));
193 	if (nBytes == -1) {
194 		fprintf(stderr, "PR_Read failed\n");
195 		exit(1);
196 	} else if (nBytes != 243) {
197 		fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n",
198 							243, nBytes);
199 		exit(1);
200 	}
201 	/* check available data */
202 	nBytes = PR_Available(ping_in);
203 	if (nBytes < 0) {
204 		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
205 				PR_GetOSError());
206 		exit(1);
207 	} else if (nBytes != 0) {
208 		fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n",
209 				nBytes);
210 		exit(1);
211 	}
212 	printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes);
213 
214     status = PR_Close(ping_in);
215     if (status == PR_FAILURE) {
216         fprintf(stderr, "PR_Close failed\n");
217         exit(1);
218     }
219     status = PR_Close(ping_out);
220     if (status == PR_FAILURE) {
221         fprintf(stderr, "PR_Close failed\n");
222         exit(1);
223     }
224 #endif /* XP_UNIX */
225 
226     printf("PASS\n");
227     return 0;
228 }
229