Bug Summary

File:nsprpub/pr/src/io/prlayer.c
Location:line 151, column 5
Description:Access to field 'lower' results in a dereference of a null pointer (loaded from variable 'fd')

Annotated Source Code

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: prlayer.c
8** Description: Routines for handling pushable protocol modules on sockets.
9*/
10
11#include "primpl.h"
12#include "prerror.h"
13#include "prmem.h"
14#include "prlock.h"
15#include "prlog.h"
16#include "prio.h"
17
18#include <string.h> /* for memset() */
19static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack);
20
21void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
22{
23 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,23))
;
24 if (NULL((void*)0) != fd->lower) fd->lower->higher = fd->higher;
25 if (NULL((void*)0) != fd->higher) fd->higher->lower = fd->lower;
26 PR_DELETE(fd){ PR_Free(fd); (fd) = ((void*)0); };
27}
28
29/*
30** Default methods that just call down to the next fd.
31*/
32static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
33{
34 PRFileDesc *top, *lower;
35 PRStatus rv;
36
37 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,37))
;
38 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,38))
;
39 PR_ASSERT(fd->secret == NULL)((fd->secret == ((void*)0))?((void)0):PR_Assert("fd->secret == NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,39))
;
40 PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED)((fd->methods->file_type == PR_DESC_LAYERED)?((void)0):
PR_Assert("fd->methods->file_type == PR_DESC_LAYERED","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,40))
;
41
42 if (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == fd->identity) {
43 /*
44 * new style stack; close all the layers, before deleting the
45 * stack head
46 */
47 rv = fd->lower->methods->close(fd->lower);
48 _PR_DestroyIOLayer(fd);
49 return rv;
50 } else if ((fd->higher) && (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == fd->higher->identity)) {
51 /*
52 * lower layers of new style stack
53 */
54 lower = fd->lower;
55 /*
56 * pop and cleanup current layer
57 */
58 top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER(PRDescIdentity)-2);
59 top->dtor(top);
60 /*
61 * then call lower layer
62 */
63 return (lower->methods->close(lower));
64 } else {
65 /* old style stack */
66 top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER(PRDescIdentity)-2);
67 top->dtor(top);
68 return (fd->methods->close)(fd);
69 }
70}
71
72static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount)
73{
74 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,74))
;
75 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,75))
;
76
77 return (fd->lower->methods->read)(fd->lower, buf, amount);
78}
79
80static PRInt32 PR_CALLBACK pl_DefWrite (
81 PRFileDesc *fd, const void *buf, PRInt32 amount)
82{
83 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,83))
;
84 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,84))
;
85
86 return (fd->lower->methods->write)(fd->lower, buf, amount);
87}
88
89static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd)
90{
91 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,91))
;
92 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,92))
;
93
94 return (fd->lower->methods->available)(fd->lower);
95}
96
97static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd)
98{
99 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,99))
;
100 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,100))
;
101
102 return (fd->lower->methods->available64)(fd->lower);
103}
104
105static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd)
106{
107 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,107))
;
108 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,108))
;
109
110 return (fd->lower->methods->fsync)(fd->lower);
111}
112
113static PRInt32 PR_CALLBACK pl_DefSeek (
114 PRFileDesc *fd, PRInt32 offset, PRSeekWhence how)
115{
116 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,116))
;
117 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,117))
;
118
119 return (fd->lower->methods->seek)(fd->lower, offset, how);
120}
121
122static PRInt64 PR_CALLBACK pl_DefSeek64 (
123 PRFileDesc *fd, PRInt64 offset, PRSeekWhence how)
124{
125 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,125))
;
126 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,126))
;
127
128 return (fd->lower->methods->seek64)(fd->lower, offset, how);
129}
130
131static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info)
132{
133 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,133))
;
134 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,134))
;
135
136 return (fd->lower->methods->fileInfo)(fd->lower, info);
137}
138
139static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info)
140{
141 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,141))
;
142 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,142))
;
143
144 return (fd->lower->methods->fileInfo64)(fd->lower, info);
145}
146
147static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov,
148 PRInt32 size, PRIntervalTime timeout)
149{
150 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,150))
;
1
Within the expansion of the macro 'PR_ASSERT':
a
Assuming 'fd' is equal to null
151 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,151))
;
2
Within the expansion of the macro 'PR_ASSERT':
a
Access to field 'lower' results in a dereference of a null pointer (loaded from variable 'fd')
152
153 return (fd->lower->methods->writev)(fd->lower, iov, size, timeout);
154}
155
156static PRStatus PR_CALLBACK pl_DefConnect (
157 PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
158{
159 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,159))
;
160 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,160))
;
161
162 return (fd->lower->methods->connect)(fd->lower, addr, timeout);
163}
164
165static PRStatus PR_CALLBACK pl_DefConnectcontinue (
166 PRFileDesc *fd, PRInt16 out_flags)
167{
168 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,168))
;
169 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,169))
;
170
171 return (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
172}
173
174static PRFileDesc* PR_CALLBACK pl_TopAccept (
175 PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
176{
177 PRStatus rv;
178 PRFileDesc *newfd, *layer = fd;
179 PRFileDesc *newstack;
180 PRBool newstyle_stack = PR_FALSE0;
181
182 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,182))
;
183 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,183))
;
184
185 /* test for new style stack */
186 while (NULL((void*)0) != layer->higher)
187 layer = layer->higher;
188 newstyle_stack = (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == layer->identity) ? PR_TRUE1 : PR_FALSE0;
189 newstack = PR_NEW(PRFileDesc)((PRFileDesc *) (PR_Malloc((sizeof(PRFileDesc)))));
190 if (NULL((void*)0) == newstack)
191 {
192 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
193 return NULL((void*)0);
194 }
195 *newstack = *fd; /* make a copy of the accepting layer */
196
197 newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
198 if (NULL((void*)0) == newfd)
199 {
200 PR_DELETE(newstack){ PR_Free(newstack); (newstack) = ((void*)0); };
201 return NULL((void*)0);
202 }
203
204 if (newstyle_stack) {
205 newstack->lower = newfd;
206 newfd->higher = newstack;
207 return newstack;
208 } else {
209 /* this PR_PushIOLayer call cannot fail */
210 rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER(PRDescIdentity)-2, newstack);
211 PR_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):PR_Assert("PR_SUCCESS == rv","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,211))
;
212 return newfd; /* that's it */
213 }
214}
215
216static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
217{
218 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,218))
;
219 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,219))
;
220
221 return (fd->lower->methods->bind)(fd->lower, addr);
222}
223
224static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog)
225{
226 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,226))
;
227 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,227))
;
228
229 return (fd->lower->methods->listen)(fd->lower, backlog);
230}
231
232static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how)
233{
234 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,234))
;
235 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,235))
;
236
237 return (fd->lower->methods->shutdown)(fd->lower, how);
238}
239
240static PRInt32 PR_CALLBACK pl_DefRecv (
241 PRFileDesc *fd, void *buf, PRInt32 amount,
242 PRIntn flags, PRIntervalTime timeout)
243{
244 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,244))
;
245 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,245))
;
246
247 return (fd->lower->methods->recv)(
248 fd->lower, buf, amount, flags, timeout);
249}
250
251static PRInt32 PR_CALLBACK pl_DefSend (
252 PRFileDesc *fd, const void *buf,
253 PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
254{
255 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,255))
;
256 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,256))
;
257
258 return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout);
259}
260
261static PRInt32 PR_CALLBACK pl_DefRecvfrom (
262 PRFileDesc *fd, void *buf, PRInt32 amount,
263 PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
264{
265 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,265))
;
266 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,266))
;
267
268 return (fd->lower->methods->recvfrom)(
269 fd->lower, buf, amount, flags, addr, timeout);
270}
271
272static PRInt32 PR_CALLBACK pl_DefSendto (
273 PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
274 const PRNetAddr *addr, PRIntervalTime timeout)
275{
276 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,276))
;
277 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,277))
;
278
279 return (fd->lower->methods->sendto)(
280 fd->lower, buf, amount, flags, addr, timeout);
281}
282
283static PRInt16 PR_CALLBACK pl_DefPoll (
284 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
285{
286 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,286))
;
287 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,287))
;
288
289 return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
290}
291
292static PRInt32 PR_CALLBACK pl_DefAcceptread (
293 PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf,
294 PRInt32 amount, PRIntervalTime t)
295{
296 PRInt32 nbytes;
297 PRStatus rv;
298 PRFileDesc *newstack;
299 PRFileDesc *layer = sd;
300 PRBool newstyle_stack = PR_FALSE0;
301
302 PR_ASSERT(sd != NULL)((sd != ((void*)0))?((void)0):PR_Assert("sd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,302))
;
303 PR_ASSERT(sd->lower != NULL)((sd->lower != ((void*)0))?((void)0):PR_Assert("sd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,303))
;
304
305 /* test for new style stack */
306 while (NULL((void*)0) != layer->higher)
307 layer = layer->higher;
308 newstyle_stack = (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == layer->identity) ? PR_TRUE1 : PR_FALSE0;
309 newstack = PR_NEW(PRFileDesc)((PRFileDesc *) (PR_Malloc((sizeof(PRFileDesc)))));
310 if (NULL((void*)0) == newstack)
311 {
312 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
313 return -1;
314 }
315 *newstack = *sd; /* make a copy of the accepting layer */
316
317 nbytes = sd->lower->methods->acceptread(
318 sd->lower, nd, raddr, buf, amount, t);
319 if (-1 == nbytes)
320 {
321 PR_DELETE(newstack){ PR_Free(newstack); (newstack) = ((void*)0); };
322 return nbytes;
323 }
324 if (newstyle_stack) {
325 newstack->lower = *nd;
326 (*nd)->higher = newstack;
327 *nd = newstack;
328 return nbytes;
329 } else {
330 /* this PR_PushIOLayer call cannot fail */
331 rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER(PRDescIdentity)-2, newstack);
332 PR_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):PR_Assert("PR_SUCCESS == rv","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,332))
;
333 return nbytes;
334 }
335}
336
337static PRInt32 PR_CALLBACK pl_DefTransmitfile (
338 PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen,
339 PRTransmitFileFlags flags, PRIntervalTime t)
340{
341 PR_ASSERT(sd != NULL)((sd != ((void*)0))?((void)0):PR_Assert("sd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,341))
;
342 PR_ASSERT(sd->lower != NULL)((sd->lower != ((void*)0))?((void)0):PR_Assert("sd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,342))
;
343
344 return sd->lower->methods->transmitfile(
345 sd->lower, fd, headers, hlen, flags, t);
346}
347
348static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr)
349{
350 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,350))
;
351 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,351))
;
352
353 return (fd->lower->methods->getsockname)(fd->lower, addr);
354}
355
356static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
357{
358 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,358))
;
359 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,359))
;
360
361 return (fd->lower->methods->getpeername)(fd->lower, addr);
362}
363
364static PRStatus PR_CALLBACK pl_DefGetsocketoption (
365 PRFileDesc *fd, PRSocketOptionData *data)
366{
367 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,367))
;
368 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,368))
;
369
370 return (fd->lower->methods->getsocketoption)(fd->lower, data);
371}
372
373static PRStatus PR_CALLBACK pl_DefSetsocketoption (
374 PRFileDesc *fd, const PRSocketOptionData *data)
375{
376 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,376))
;
377 PR_ASSERT(fd->lower != NULL)((fd->lower != ((void*)0))?((void)0):PR_Assert("fd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,377))
;
378
379 return (fd->lower->methods->setsocketoption)(fd->lower, data);
380}
381
382static PRInt32 PR_CALLBACK pl_DefSendfile (
383 PRFileDesc *sd, PRSendFileData *sfd,
384 PRTransmitFileFlags flags, PRIntervalTime timeout)
385{
386 PR_ASSERT(sd != NULL)((sd != ((void*)0))?((void)0):PR_Assert("sd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,386))
;
387 PR_ASSERT(sd->lower != NULL)((sd->lower != ((void*)0))?((void)0):PR_Assert("sd->lower != NULL"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,387))
;
388
389 return sd->lower->methods->sendfile(
390 sd->lower, sfd, flags, timeout);
391}
392
393/* Methods for the top of the stack. Just call down to the next fd. */
394static PRIOMethods pl_methods = {
395 PR_DESC_LAYERED,
396 pl_TopClose,
397 pl_DefRead,
398 pl_DefWrite,
399 pl_DefAvailable,
400 pl_DefAvailable64,
401 pl_DefFsync,
402 pl_DefSeek,
403 pl_DefSeek64,
404 pl_DefFileInfo,
405 pl_DefFileInfo64,
406 pl_DefWritev,
407 pl_DefConnect,
408 pl_TopAccept,
409 pl_DefBind,
410 pl_DefListen,
411 pl_DefShutdown,
412 pl_DefRecv,
413 pl_DefSend,
414 pl_DefRecvfrom,
415 pl_DefSendto,
416 pl_DefPoll,
417 pl_DefAcceptread,
418 pl_DefTransmitfile,
419 pl_DefGetsockname,
420 pl_DefGetpeername,
421 (PRReservedFN)_PR_InvalidInt,
422 (PRReservedFN)_PR_InvalidInt,
423 pl_DefGetsocketoption,
424 pl_DefSetsocketoption,
425 pl_DefSendfile,
426 pl_DefConnectcontinue,
427 (PRReservedFN)_PR_InvalidInt,
428 (PRReservedFN)_PR_InvalidInt,
429 (PRReservedFN)_PR_InvalidInt,
430 (PRReservedFN)_PR_InvalidInt
431};
432
433PR_IMPLEMENT(const PRIOMethods*)__attribute__((visibility("default"))) const PRIOMethods* PR_GetDefaultIOMethods(void)
434{
435 return &pl_methods;
436} /* PR_GetDefaultIOMethods */
437
438PR_IMPLEMENT(PRFileDesc*)__attribute__((visibility("default"))) PRFileDesc* PR_CreateIOLayerStub(
439 PRDescIdentity ident, const PRIOMethods *methods)
440{
441 PRFileDesc *fd = NULL((void*)0);
442 PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident))((((PRDescIdentity)0 != ident) && ((PRDescIdentity)-2
!= ident))?((void)0):PR_Assert("(PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident)"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,442))
;
443 if ((PR_NSPR_IO_LAYER(PRDescIdentity)0 == ident) || (PR_TOP_IO_LAYER(PRDescIdentity)-2 == ident))
444 PR_SetError(PR_INVALID_ARGUMENT_ERROR(-5987L), 0);
445 else
446 {
447 fd = PR_NEWZAP(PRFileDesc)((PRFileDesc*)PR_Calloc(1, sizeof(PRFileDesc)));
448 if (NULL((void*)0) == fd)
449 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
450 else
451 {
452 fd->methods = methods;
453 fd->dtor = pl_FDDestructor;
454 fd->identity = ident;
455 }
456 }
457 return fd;
458} /* PR_CreateIOLayerStub */
459
460/*
461 * PR_CreateIOLayer
462 * Create a new style stack, where the stack top is a dummy header.
463 * Unlike the old style stacks, the contents of the stack head
464 * are not modified when a layer is pushed onto or popped from a new
465 * style stack.
466 */
467
468PR_IMPLEMENT(PRFileDesc*)__attribute__((visibility("default"))) PRFileDesc* PR_CreateIOLayer(PRFileDesc *top)
469{
470 PRFileDesc *fd = NULL((void*)0);
471
472 fd = PR_NEWZAP(PRFileDesc)((PRFileDesc*)PR_Calloc(1, sizeof(PRFileDesc)));
473 if (NULL((void*)0) == fd)
474 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
475 else
476 {
477 fd->methods = &pl_methods;
478 fd->dtor = pl_FDDestructor;
479 fd->identity = PR_IO_LAYER_HEAD(PRDescIdentity)-3;
480 fd->higher = NULL((void*)0);
481 fd->lower = top;
482 top->higher = fd;
483 top->lower = NULL((void*)0);
484 }
485 return fd;
486} /* PR_CreateIOLayer */
487
488/*
489 * _PR_DestroyIOLayer
490 * Delete the stack head of a new style stack.
491 */
492
493static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
494{
495 if (NULL((void*)0) == stack)
496 return PR_FAILURE;
497 else {
498 PR_DELETE(stack){ PR_Free(stack); (stack) = ((void*)0); };
499 return PR_SUCCESS;
500 }
501} /* _PR_DestroyIOLayer */
502
503PR_IMPLEMENT(PRStatus)__attribute__((visibility("default"))) PRStatus PR_PushIOLayer(
504 PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
505{
506 PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
507
508 PR_ASSERT(fd != NULL)((fd != ((void*)0))?((void)0):PR_Assert("fd != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,508))
;
509 PR_ASSERT(stack != NULL)((stack != ((void*)0))?((void)0):PR_Assert("stack != NULL","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,509))
;
510 PR_ASSERT(insert != NULL)((insert != ((void*)0))?((void)0):PR_Assert("insert != NULL",
"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,510))
;
511 PR_ASSERT(PR_IO_LAYER_HEAD != id)(((PRDescIdentity)-3 != id)?((void)0):PR_Assert("PR_IO_LAYER_HEAD != id"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,511))
;
512 if ((NULL((void*)0) == stack) || (NULL((void*)0) == fd) || (NULL((void*)0) == insert))
513 {
514 PR_SetError(PR_INVALID_ARGUMENT_ERROR(-5987L), 0);
515 return PR_FAILURE;
516 }
517
518 if (stack == insert)
519 {
520 /* going on top of the stack */
521 /* old-style stack */
522 PRFileDesc copy = *stack;
523 *stack = *fd;
524 *fd = copy;
525 fd->higher = stack;
526 if (fd->lower)
527 {
528 PR_ASSERT(fd->lower->higher == stack)((fd->lower->higher == stack)?((void)0):PR_Assert("fd->lower->higher == stack"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,528))
;
529 fd->lower->higher = fd;
530 }
531 stack->lower = fd;
532 stack->higher = NULL((void*)0);
533 } else {
534 /*
535 * going somewhere in the middle of the stack for both old and new
536 * style stacks, or going on top of stack for new style stack
537 */
538 fd->lower = insert;
539 fd->higher = insert->higher;
540
541 insert->higher->lower = fd;
542 insert->higher = fd;
543 }
544
545 return PR_SUCCESS;
546}
547
548PR_IMPLEMENT(PRFileDesc*)__attribute__((visibility("default"))) PRFileDesc* PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
549{
550 PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id);
551
552 PR_ASSERT(0 != id)((0 != id)?((void)0):PR_Assert("0 != id","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,552))
;
553 PR_ASSERT(NULL != stack)((((void*)0) != stack)?((void)0):PR_Assert("NULL != stack","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,553))
;
554 PR_ASSERT(NULL != extract)((((void*)0) != extract)?((void)0):PR_Assert("NULL != extract"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,554))
;
555 if ((NULL((void*)0) == stack) || (0 == id) || (NULL((void*)0) == extract))
556 {
557 PR_SetError(PR_INVALID_ARGUMENT_ERROR(-5987L), 0);
558 return NULL((void*)0);
559 }
560
561 if (extract == stack) {
562 /* popping top layer of the stack */
563 /* old style stack */
564 PRFileDesc copy = *stack;
565 extract = stack->lower;
566 *stack = *extract;
567 *extract = copy;
568 stack->higher = NULL((void*)0);
569 if (stack->lower) {
570 PR_ASSERT(stack->lower->higher == extract)((stack->lower->higher == extract)?((void)0):PR_Assert(
"stack->lower->higher == extract","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,570))
;
571 stack->lower->higher = stack;
572 }
573 } else if ((PR_IO_LAYER_HEAD(PRDescIdentity)-3 == stack->identity) &&
574 (extract == stack->lower) && (extract->lower == NULL((void*)0))) {
575 /*
576 * new style stack
577 * popping the only layer in the stack; delete the stack too
578 */
579 stack->lower = NULL((void*)0);
580 _PR_DestroyIOLayer(stack);
581 } else {
582 /* for both kinds of stacks */
583 extract->lower->higher = extract->higher;
584 extract->higher->lower = extract->lower;
585 }
586 extract->higher = extract->lower = NULL((void*)0);
587 return extract;
588} /* PR_PopIOLayer */
589
590#define ID_CACHE_INCREMENT16 16
591typedef struct _PRIdentity_cache
592{
593 PRLock *ml;
594 char **name;
595 PRIntn length;
596 PRDescIdentity ident;
597} _PRIdentity_cache;
598
599static _PRIdentity_cache identity_cache;
600
601PR_IMPLEMENT(PRDescIdentity)__attribute__((visibility("default"))) PRDescIdentity PR_GetUniqueIdentity(const char *layer_name)
602{
603 PRDescIdentity identity, length;
604 char **names = NULL((void*)0), *name = NULL((void*)0), **old = NULL((void*)0);
605
606 if (!_pr_initialized) _PR_ImplicitInitialization();
607
608 PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident)(((PRDescIdentity)0x7fff > identity_cache.ident)?((void)0)
:PR_Assert("(PRDescIdentity)0x7fff > identity_cache.ident"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,608))
;
609
610 if (NULL((void*)0) != layer_name)
611 {
612 name = (char*)PR_Malloc(strlen(layer_name) + 1);
613 if (NULL((void*)0) == name)
614 {
615 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
616 return PR_INVALID_IO_LAYER(PRDescIdentity)-1;
617 }
618 strcpy(name, layer_name);
619 }
620
621 /* this initial code runs unsafe */
622retry:
623 PR_ASSERT(NULL == names)((((void*)0) == names)?((void)0):PR_Assert("NULL == names","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,623))
;
624 /*
625 * In the initial round, both identity_cache.ident and
626 * identity_cache.length are 0, so (identity_cache.ident + 1) is greater
627 * than length. In later rounds, identity_cache.ident is always less
628 * than length, so (identity_cache.ident + 1) can be equal to but cannot
629 * be greater than length.
630 */
631 length = identity_cache.length;
632 if ((identity_cache.ident + 1) >= length)
633 {
634 length += ID_CACHE_INCREMENT16;
635 names = (char**)PR_CALLOC(length * sizeof(char*))(PR_Calloc(1, (length * sizeof(char*))));
636 if (NULL((void*)0) == names)
637 {
638 if (NULL((void*)0) != name) PR_DELETE(name){ PR_Free(name); (name) = ((void*)0); };
639 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
640 return PR_INVALID_IO_LAYER(PRDescIdentity)-1;
641 }
642 }
643
644 /* now we get serious about thread safety */
645 PR_Lock(identity_cache.ml);
646 PR_ASSERT(identity_cache.length == 0 ||((identity_cache.length == 0 || identity_cache.ident < identity_cache
.length)?((void)0):PR_Assert("identity_cache.length == 0 || identity_cache.ident < identity_cache.length"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,647))
647 identity_cache.ident < identity_cache.length)((identity_cache.length == 0 || identity_cache.ident < identity_cache
.length)?((void)0):PR_Assert("identity_cache.length == 0 || identity_cache.ident < identity_cache.length"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,647))
;
648 identity = identity_cache.ident + 1;
649 if (identity >= identity_cache.length) /* there's no room */
650 {
651 /* we have to do something - hopefully it's already done */
652 if ((NULL((void*)0) != names) && (identity < length))
653 {
654 /* what we did is still okay */
655 memcpy(
656 names, identity_cache.name,
657 identity_cache.length * sizeof(char*));
658 old = identity_cache.name;
659 identity_cache.name = names;
660 identity_cache.length = length;
661 names = NULL((void*)0);
662 }
663 else
664 {
665 PR_Unlock(identity_cache.ml);
666 if (NULL((void*)0) != names) PR_DELETE(names){ PR_Free(names); (names) = ((void*)0); };
667 goto retry;
668 }
669 }
670 if (NULL((void*)0) != name) /* there's a name to be stored */
671 {
672 identity_cache.name[identity] = name;
673 }
674 identity_cache.ident = identity;
675 PR_ASSERT(identity_cache.ident < identity_cache.length)((identity_cache.ident < identity_cache.length)?((void)0):
PR_Assert("identity_cache.ident < identity_cache.length","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,675))
;
676 PR_Unlock(identity_cache.ml);
677
678 if (NULL((void*)0) != old) PR_DELETE(old){ PR_Free(old); (old) = ((void*)0); };
679 if (NULL((void*)0) != names) PR_DELETE(names){ PR_Free(names); (names) = ((void*)0); };
680
681 return identity;
682} /* PR_GetUniqueIdentity */
683
684PR_IMPLEMENT(const char*)__attribute__((visibility("default"))) const char* PR_GetNameForIdentity(PRDescIdentity ident)
685{
686 if (!_pr_initialized) _PR_ImplicitInitialization();
687
688 if (PR_TOP_IO_LAYER(PRDescIdentity)-2 == ident) return NULL((void*)0);
689
690 PR_ASSERT(ident <= identity_cache.ident)((ident <= identity_cache.ident)?((void)0):PR_Assert("ident <= identity_cache.ident"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,690))
;
691 return (ident > identity_cache.ident) ? NULL((void*)0) : identity_cache.name[ident];
692} /* PR_GetNameForIdentity */
693
694PR_IMPLEMENT(PRDescIdentity)__attribute__((visibility("default"))) PRDescIdentity PR_GetLayersIdentity(PRFileDesc* fd)
695{
696 PR_ASSERT(NULL != fd)((((void*)0) != fd)?((void)0):PR_Assert("NULL != fd","/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,696))
;
697 if (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == fd->identity) {
698 PR_ASSERT(NULL != fd->lower)((((void*)0) != fd->lower)?((void)0):PR_Assert("NULL != fd->lower"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,698))
;
699 return fd->lower->identity;
700 } else
701 return fd->identity;
702} /* PR_GetLayersIdentity */
703
704PR_IMPLEMENT(PRFileDesc*)__attribute__((visibility("default"))) PRFileDesc* PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id)
705{
706 PRFileDesc *layer = fd;
707
708 if (PR_TOP_IO_LAYER(PRDescIdentity)-2 == id) {
709 if (PR_IO_LAYER_HEAD(PRDescIdentity)-3 == fd->identity)
710 return fd->lower;
711 else
712 return fd;
713 }
714
715 for (layer = fd; layer != NULL((void*)0); layer = layer->lower)
716 {
717 if (id == layer->identity) return layer;
718 }
719 for (layer = fd; layer != NULL((void*)0); layer = layer->higher)
720 {
721 if (id == layer->identity) return layer;
722 }
723 return NULL((void*)0);
724} /* PR_GetIdentitiesLayer */
725
726void _PR_InitLayerCache(void)
727{
728 memset(&identity_cache, 0, sizeof(identity_cache));
729 identity_cache.ml = PR_NewLock();
730 PR_ASSERT(NULL != identity_cache.ml)((((void*)0) != identity_cache.ml)?((void)0):PR_Assert("NULL != identity_cache.ml"
,"/home/sylvestre/dev/mozilla/ff/firefox.hg/nsprpub/pr/src/io/prlayer.c"
,730))
;
731} /* _PR_InitLayerCache */
732
733void _PR_CleanupLayerCache(void)
734{
735 if (identity_cache.ml)
736 {
737 PR_DestroyLock(identity_cache.ml);
738 identity_cache.ml = NULL((void*)0);
739 }
740
741 if (identity_cache.name)
742 {
743 PRDescIdentity ident;
744
745 for (ident = 0; ident <= identity_cache.ident; ident++)
746 PR_DELETE(identity_cache.name[ident]){ PR_Free(identity_cache.name[ident]); (identity_cache.name[ident
]) = ((void*)0); }
;
747
748 PR_DELETE(identity_cache.name){ PR_Free(identity_cache.name); (identity_cache.name) = ((void
*)0); }
;
749 }
750} /* _PR_CleanupLayerCache */
751
752/* prlayer.c */