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/. */
9 * Description: send a zero-length file with PR_SendFile and
13 #define ZERO_LEN_FILE_NAME "zerolen.tmp"
14 #define HEADER_STR "Header"
15 #define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */
16 #define TRAILER_STR "Trailer"
17 #define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */
25 static void ClientThread(void *arg
)
29 PRUint16 port
= (PRUint16
) arg
;
36 sock
= PR_NewTCPSocket();
38 fprintf(stderr
, "PR_NewTCPSocket failed\n");
41 if (PR_InitializeNetAddr(PR_IpAddrLoopback
, port
, &addr
) == PR_FAILURE
) {
42 fprintf(stderr
, "PR_InitializeNetAddr failed\n");
45 if (PR_Connect(sock
, &addr
, PR_INTERVAL_NO_TIMEOUT
) == PR_FAILURE
) {
46 fprintf(stderr
, "PR_Connect failed\n");
51 while ((nbytes
= PR_Read(sock
, bufPtr
, sizeof(buf
)-ntotal
)) > 0) {
56 fprintf(stderr
, "PR_Read failed\n");
59 nexpected
= HEADER_LEN
+TRAILER_LEN
+TRAILER_LEN
+HEADER_LEN
+HEADER_LEN
;
60 if (ntotal
!= nexpected
) {
61 fprintf(stderr
, "total bytes read should be %d but is %d\n",
65 if (memcmp(buf
, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR
,
67 fprintf(stderr
, "wrong data is received\n");
70 if (PR_Close(sock
) == PR_FAILURE
) {
71 fprintf(stderr
, "PR_Close failed\n");
76 static void ServerThread(void *arg
)
78 PRFileDesc
*listenSock
= (PRFileDesc
*) arg
;
79 PRFileDesc
*acceptSock
;
82 char header
[1024], trailer
[1024];
85 /* Create a zero-length file */
86 file
= PR_Open(ZERO_LEN_FILE_NAME
,
87 PR_CREATE_FILE
|PR_TRUNCATE
|PR_RDWR
, 0666);
89 fprintf(stderr
, "PR_Open failed\n");
95 memcpy(header
, HEADER_STR
, HEADER_LEN
);
96 memcpy(trailer
, TRAILER_STR
, TRAILER_LEN
);
98 sfd
.hlen
= HEADER_LEN
;
99 sfd
.trailer
= trailer
;
100 sfd
.tlen
= TRAILER_LEN
;
101 acceptSock
= PR_Accept(listenSock
, NULL
, PR_INTERVAL_NO_TIMEOUT
);
102 if (NULL
== acceptSock
) {
103 fprintf(stderr
, "PR_Accept failed\n");
106 /* Send both header and trailer */
107 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
108 PR_INTERVAL_NO_TIMEOUT
);
109 if (HEADER_LEN
+TRAILER_LEN
!= nbytes
) {
110 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
111 HEADER_LEN
+TRAILER_LEN
, nbytes
);
114 /* Trailer only, no header */
116 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
117 PR_INTERVAL_NO_TIMEOUT
);
118 if (TRAILER_LEN
!= nbytes
) {
119 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
120 TRAILER_LEN
, nbytes
);
123 /* Header only, no trailer */
124 sfd
.hlen
= HEADER_LEN
;
126 nbytes
= PR_SendFile(acceptSock
, &sfd
, PR_TRANSMITFILE_KEEP_OPEN
,
127 PR_INTERVAL_NO_TIMEOUT
);
128 if (HEADER_LEN
!= nbytes
) {
129 fprintf(stderr
, "PR_SendFile should return %d but returned %d\n",
133 /* Try PR_TransmitFile */
134 nbytes
= PR_TransmitFile(acceptSock
, file
, header
, HEADER_LEN
,
135 PR_TRANSMITFILE_KEEP_OPEN
, PR_INTERVAL_NO_TIMEOUT
);
136 if (HEADER_LEN
!= nbytes
) {
137 fprintf(stderr
, "PR_TransmitFile should return %d but returned %d\n",
141 if (PR_Close(acceptSock
) == PR_FAILURE
) {
142 fprintf(stderr
, "PR_Close failed\n");
145 if (PR_Close(file
) == PR_FAILURE
) {
146 fprintf(stderr
, "PR_Close failed\n");
149 if (PR_Delete(ZERO_LEN_FILE_NAME
) == PR_FAILURE
) {
150 fprintf(stderr
, "PR_Delete failed\n");
155 int main(int argc
, char **argv
)
157 PRFileDesc
*listenSock
;
158 PRThread
*clientThread
;
159 PRThread
*serverThread
;
161 PRThreadScope scope
= PR_GLOBAL_THREAD
;
163 listenSock
= PR_NewTCPSocket();
164 if (NULL
== listenSock
) {
165 fprintf(stderr
, "PR_NewTCPSocket failed\n");
168 if (PR_InitializeNetAddr(PR_IpAddrAny
, 0, &addr
) == PR_FAILURE
) {
169 fprintf(stderr
, "PR_InitializeNetAddr failed\n");
172 if (PR_Bind(listenSock
, &addr
) == PR_FAILURE
) {
173 fprintf(stderr
, "PR_Bind failed\n");
176 /* Find out what port number we are bound to. */
177 if (PR_GetSockName(listenSock
, &addr
) == PR_FAILURE
) {
178 fprintf(stderr
, "PR_GetSockName failed\n");
181 if (PR_Listen(listenSock
, 5) == PR_FAILURE
) {
182 fprintf(stderr
, "PR_Listen failed\n");
186 clientThread
= PR_CreateThread(PR_USER_THREAD
,
187 ClientThread
, (void *) PR_ntohs(PR_NetAddrInetPort(&addr
)),
188 PR_PRIORITY_NORMAL
, scope
, PR_JOINABLE_THREAD
, 0);
189 if (NULL
== clientThread
) {
190 fprintf(stderr
, "PR_CreateThread failed\n");
193 serverThread
= PR_CreateThread(PR_USER_THREAD
,
194 ServerThread
, listenSock
,
195 PR_PRIORITY_NORMAL
, scope
, PR_JOINABLE_THREAD
, 0);
196 if (NULL
== serverThread
) {
197 fprintf(stderr
, "PR_CreateThread failed\n");
200 if (PR_JoinThread(clientThread
) == PR_FAILURE
) {
201 fprintf(stderr
, "PR_JoinThread failed\n");
204 if (PR_JoinThread(serverThread
) == PR_FAILURE
) {
205 fprintf(stderr
, "PR_JoinThread failed\n");
208 if (PR_Close(listenSock
) == PR_FAILURE
) {
209 fprintf(stderr
, "PR_Close failed\n");