| 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') |
| 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() */ | |||||
| 19 | static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack); | |||||
| 20 | ||||||
| 21 | void 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 | */ | |||||
| 32 | static 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 | ||||||
| 72 | static 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 | ||||||
| 80 | static 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 | ||||||
| 89 | static 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 | ||||||
| 97 | static 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 | ||||||
| 105 | static 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 | ||||||
| 113 | static 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 | ||||||
| 122 | static 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 | ||||||
| 131 | static 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 | ||||||
| 139 | static 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 | ||||||
| 147 | static 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)); | |||||
| ||||||
| 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)); | |||||
| ||||||
| 152 | ||||||
| 153 | return (fd->lower->methods->writev)(fd->lower, iov, size, timeout); | |||||
| 154 | } | |||||
| 155 | ||||||
| 156 | static 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 | ||||||
| 165 | static 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 | ||||||
| 174 | static 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 | ||||||
| 216 | static 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 | ||||||
| 224 | static 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 | ||||||
| 232 | static 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 | ||||||
| 240 | static 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 | ||||||
| 251 | static 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 | ||||||
| 261 | static 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 | ||||||
| 272 | static 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 | ||||||
| 283 | static 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 | ||||||
| 292 | static 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 | ||||||
| 337 | static 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 | ||||||
| 348 | static 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 | ||||||
| 356 | static 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 | ||||||
| 364 | static 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 | ||||||
| 373 | static 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 | ||||||
| 382 | static 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. */ | |||||
| 394 | static 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 | ||||||
| 433 | PR_IMPLEMENT(const PRIOMethods*)__attribute__((visibility("default"))) const PRIOMethods* PR_GetDefaultIOMethods(void) | |||||
| 434 | { | |||||
| 435 | return &pl_methods; | |||||
| 436 | } /* PR_GetDefaultIOMethods */ | |||||
| 437 | ||||||
| 438 | PR_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 | ||||||
| 468 | PR_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 | ||||||
| 493 | static 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 | ||||||
| 503 | PR_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 | ||||||
| 548 | PR_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 | |||||
| 591 | typedef struct _PRIdentity_cache | |||||
| 592 | { | |||||
| 593 | PRLock *ml; | |||||
| 594 | char **name; | |||||
| 595 | PRIntn length; | |||||
| 596 | PRDescIdentity ident; | |||||
| 597 | } _PRIdentity_cache; | |||||
| 598 | ||||||
| 599 | static _PRIdentity_cache identity_cache; | |||||
| 600 | ||||||
| 601 | PR_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 */ | |||||
| 622 | retry: | |||||
| 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 | ||||||
| 684 | PR_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 | ||||||
| 694 | PR_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 | ||||||
| 704 | PR_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 | ||||||
| 726 | void _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 | ||||||
| 733 | void _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 */ |