1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is the Netscape Portable Runtime (NSPR).
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999-2000
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
41 * Description: send a zero-length file with PR_SendFile and
45 #define ZERO_LEN_FILE_NAME "zerolen.tmp"
46 #define HEADER_STR "Header"
47 #define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */
48 #define TRAILER_STR "Trailer"
49 #define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */
57 static void ClientThread(void *arg
)
61 PRUint16 port
= (PRUint16
) arg
;
68 sock
= PR_NewTCPSocket();
70 fprintf(stderr
, "PR_NewTCPSocket failed\n");
73 if (PR_InitializeNetAddr(PR_IpAddrLoopback
, port
, &addr
) == PR_FAILURE
) {
74 fprintf(stderr
, "PR_InitializeNetAddr failed\n");
77 if (PR_Connect(sock
, &addr
, PR_INTERVAL_NO_TIMEOUT
) == PR_FAILURE
) {
78 fprintf(stderr
, "PR_Connect failed\n");
83 while ((nbytes
= PR_Read(sock
, bufPtr
, sizeof(buf
)-ntotal
)) > 0) {
88 fprintf(stderr
, "PR_Read failed\n");
91 nexpected
= HEADER_LEN
+TRAILER_LEN
+TRAILER_LEN
+HEADER_LEN
+HEADER_LEN
;
92 if (ntotal
!= nexpected
) {
93 fprintf(stderr
, "total bytes read should be %d but is %d\n",
97 if (memcmp(buf
, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR
,
99 fprintf(stderr
, "wrong data is received\n");
102 if (PR_Close(sock
) == PR_FAILURE
) {
103 fprintf(stderr
, "PR_Close failed\n");
108 static void ServerThread(void *arg
)
110 PRFileDesc
*listenSock
= (PRFileDesc
*) arg
;
111 PRFileDesc
*acceptSock
;
114 char header
[1024], trailer
[1024];
117 /* Create a zero-length file */
118 file
= PR_Open(ZERO_LEN_FILE_NAME
,
119 PR_CREATE_FILE
|PR_TRUNCATE
|PR_RDWR
, 0666);
121 fprintf(stderr
, "PR_Open failed\n");
127 memcpy(header
, HEADER_STR
, HEADER_LEN
);
128 memcpy(trailer
, TRAILER_STR
, TRAILER_LEN
);
130 sfd
.hlen
= HEADER_LEN
;
131 sfd
.trailer
= trailer
;
132 sfd
.tlen
= TRAILER_LEN
;
133 acceptSock
= PR_Accept(listenSock
, NULL
, PR_INTERVAL_NO_TIMEOUT
);
134 if (NULL
== acceptSock
) {
135 fprintf(stderr
, "PR_Accept failed\n");
138 /* Send both header and trailer */
139 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
140 PR_INTERVAL_NO_TIMEOUT
);
141 if (HEADER_LEN
+TRAILER_LEN
!= nbytes
) {
142 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
143 HEADER_LEN
+TRAILER_LEN
, nbytes
);
146 /* Trailer only, no header */
148 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
149 PR_INTERVAL_NO_TIMEOUT
);
150 if (TRAILER_LEN
!= nbytes
) {
151 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
152 TRAILER_LEN
, nbytes
);
155 /* Header only, no trailer */
156 sfd
.hlen
= HEADER_LEN
;
158 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
159 PR_INTERVAL_NO_TIMEOUT
);
160 if (HEADER_LEN
!= nbytes
) {
161 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
165 /* Try PR_TransmitFile */
166 nbytes
= PR_TransmitFile(acceptSock
, file
, header
, HEADER_LEN
,
167 PR_TRANSMITFILE_KEEP_OPEN
, PR_INTERVAL_NO_TIMEOUT
);
168 if (HEADER_LEN
!= nbytes
) {
169 fprintf(stderr
, "PR_TransmitFile should return %d but returned %d\n",
173 if (PR_Close(acceptSock
) == PR_FAILURE
) {
174 fprintf(stderr
, "PR_Close failed\n");
177 if (PR_Close(file
) == PR_FAILURE
) {
178 fprintf(stderr
, "PR_Close failed\n");
181 if (PR_Delete(ZERO_LEN_FILE_NAME
) == PR_FAILURE
) {
182 fprintf(stderr
, "PR_Delete failed\n");
189 PRFileDesc
*listenSock
;
190 PRThread
*clientThread
;
191 PRThread
*serverThread
;
193 PRThreadScope scope
= PR_GLOBAL_THREAD
;
195 listenSock
= PR_NewTCPSocket();
196 if (NULL
== listenSock
) {
197 fprintf(stderr
, "PR_NewTCPSocket failed\n");
200 if (PR_InitializeNetAddr(PR_IpAddrAny
, 0, &addr
) == PR_FAILURE
) {
201 fprintf(stderr
, "PR_InitializeNetAddr failed\n");
204 if (PR_Bind(listenSock
, &addr
) == PR_FAILURE
) {
205 fprintf(stderr
, "PR_Bind failed\n");
208 /* Find out what port number we are bound to. */
209 if (PR_GetSockName(listenSock
, &addr
) == PR_FAILURE
) {
210 fprintf(stderr
, "PR_GetSockName failed\n");
213 if (PR_Listen(listenSock
, 5) == PR_FAILURE
) {
214 fprintf(stderr
, "PR_Listen failed\n");
218 clientThread
= PR_CreateThread(PR_USER_THREAD
,
219 ClientThread
, (void *) PR_ntohs(PR_NetAddrInetPort(&addr
)),
220 PR_PRIORITY_NORMAL
, scope
, PR_JOINABLE_THREAD
, 0);
221 if (NULL
== clientThread
) {
222 fprintf(stderr
, "PR_CreateThread failed\n");
225 serverThread
= PR_CreateThread(PR_USER_THREAD
,
226 ServerThread
, listenSock
,
227 PR_PRIORITY_NORMAL
, scope
, PR_JOINABLE_THREAD
, 0);
228 if (NULL
== serverThread
) {
229 fprintf(stderr
, "PR_CreateThread failed\n");
232 if (PR_JoinThread(clientThread
) == PR_FAILURE
) {
233 fprintf(stderr
, "PR_JoinThread failed\n");
236 if (PR_JoinThread(serverThread
) == PR_FAILURE
) {
237 fprintf(stderr
, "PR_JoinThread failed\n");
240 if (PR_Close(listenSock
) == PR_FAILURE
) {
241 fprintf(stderr
, "PR_Close failed\n");