1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/io/prfile.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,783 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "primpl.h" 1.10 + 1.11 +#include <string.h> 1.12 +#include <fcntl.h> 1.13 + 1.14 +#ifdef XP_UNIX 1.15 +#if defined(AIX) || defined(QNX) 1.16 +/* To pick up sysconf */ 1.17 +#include <unistd.h> 1.18 +#else 1.19 +/* To pick up getrlimit, setrlimit */ 1.20 +#include <sys/time.h> 1.21 +#include <sys/resource.h> 1.22 +#endif 1.23 +#endif /* XP_UNIX */ 1.24 + 1.25 +extern PRLock *_pr_flock_lock; 1.26 +extern PRCondVar *_pr_flock_cv; 1.27 + 1.28 +static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount) 1.29 +{ 1.30 + PRInt32 rv = 0; 1.31 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.32 + 1.33 + if (_PR_PENDING_INTERRUPT(me)) { 1.34 + me->flags &= ~_PR_INTERRUPT; 1.35 + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); 1.36 + rv = -1; 1.37 + } 1.38 + if (_PR_IO_PENDING(me)) { 1.39 + PR_SetError(PR_IO_PENDING_ERROR, 0); 1.40 + rv = -1; 1.41 + } 1.42 + if (rv == -1) 1.43 + return rv; 1.44 + 1.45 + rv = _PR_MD_READ(fd, buf, amount); 1.46 + if (rv < 0) { 1.47 + PR_ASSERT(rv == -1); 1.48 + } 1.49 + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv)); 1.50 + return rv; 1.51 +} 1.52 + 1.53 +static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) 1.54 +{ 1.55 + PRInt32 rv = 0; 1.56 + PRInt32 temp, count; 1.57 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.58 + 1.59 + if (_PR_PENDING_INTERRUPT(me)) { 1.60 + me->flags &= ~_PR_INTERRUPT; 1.61 + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); 1.62 + rv = -1; 1.63 + } 1.64 + if (_PR_IO_PENDING(me)) { 1.65 + PR_SetError(PR_IO_PENDING_ERROR, 0); 1.66 + rv = -1; 1.67 + } 1.68 + if (rv != 0) 1.69 + return rv; 1.70 + 1.71 + count = 0; 1.72 +#if !defined(_PR_HAVE_O_APPEND) /* Bugzilla: 4090, 276330 */ 1.73 + if (fd->secret->appendMode) { 1.74 + if (PR_Seek64(fd, 0, PR_SEEK_END) == -1) { 1.75 + return -1; 1.76 + } 1.77 + } /* if (fd->secret->appendMode...) */ 1.78 +#endif /* _PR_HAVE_O_APPEND */ 1.79 + while (amount > 0) { 1.80 + temp = _PR_MD_WRITE(fd, buf, amount); 1.81 + if (temp < 0) { 1.82 + count = -1; 1.83 + break; 1.84 + } 1.85 + count += temp; 1.86 + if (fd->secret->nonblocking) { 1.87 + break; 1.88 + } 1.89 + buf = (const void*) ((const char*)buf + temp); 1.90 + amount -= temp; 1.91 + } 1.92 + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count)); 1.93 + return count; 1.94 +} 1.95 + 1.96 +static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) 1.97 +{ 1.98 + PROffset32 result; 1.99 + 1.100 + result = _PR_MD_LSEEK(fd, offset, whence); 1.101 + return result; 1.102 +} 1.103 + 1.104 +static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) 1.105 +{ 1.106 + PROffset64 result; 1.107 + 1.108 + result = _PR_MD_LSEEK64(fd, offset, whence); 1.109 + return result; 1.110 +} 1.111 + 1.112 +static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd) 1.113 +{ 1.114 + PRInt32 result, cur, end; 1.115 + 1.116 + cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR); 1.117 + 1.118 + if (cur >= 0) 1.119 + end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END); 1.120 + 1.121 + if ((cur < 0) || (end < 0)) { 1.122 + return -1; 1.123 + } 1.124 + 1.125 + result = end - cur; 1.126 + _PR_MD_LSEEK(fd, cur, PR_SEEK_SET); 1.127 + 1.128 + return result; 1.129 +} 1.130 + 1.131 +static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd) 1.132 +{ 1.133 + PRInt64 result, cur, end; 1.134 + PRInt64 minus_one; 1.135 + 1.136 + LL_I2L(minus_one, -1); 1.137 + cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR); 1.138 + 1.139 + if (LL_GE_ZERO(cur)) 1.140 + end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END); 1.141 + 1.142 + if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one; 1.143 + 1.144 + LL_SUB(result, end, cur); 1.145 + (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET); 1.146 + 1.147 + return result; 1.148 +} 1.149 + 1.150 +static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd) 1.151 +{ 1.152 + PRInt32 rv; 1.153 + rv = _PR_MD_PIPEAVAILABLE(fd); 1.154 + return rv; 1.155 +} 1.156 + 1.157 +static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd) 1.158 +{ 1.159 + PRInt64 rv; 1.160 + LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd)); 1.161 + return rv; 1.162 +} 1.163 + 1.164 +static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd) 1.165 +{ 1.166 + return PR_SUCCESS; 1.167 +} 1.168 + 1.169 +static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info) 1.170 +{ 1.171 + PRInt32 rv; 1.172 + 1.173 + rv = _PR_MD_GETOPENFILEINFO(fd, info); 1.174 + if (rv < 0) { 1.175 + return PR_FAILURE; 1.176 + } else 1.177 + return PR_SUCCESS; 1.178 +} 1.179 + 1.180 +static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info) 1.181 +{ 1.182 + /* $$$$ NOT YET IMPLEMENTED */ 1.183 + PRInt32 rv; 1.184 + 1.185 + rv = _PR_MD_GETOPENFILEINFO64(fd, info); 1.186 + if (rv < 0) return PR_FAILURE; 1.187 + else return PR_SUCCESS; 1.188 +} 1.189 + 1.190 +static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd) 1.191 +{ 1.192 + PRInt32 result; 1.193 + result = _PR_MD_FSYNC(fd); 1.194 + if (result < 0) { 1.195 + return PR_FAILURE; 1.196 + } 1.197 + return PR_SUCCESS; 1.198 +} 1.199 + 1.200 +static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd) 1.201 +{ 1.202 + if (!fd || !fd->secret 1.203 + || (fd->secret->state != _PR_FILEDESC_OPEN 1.204 + && fd->secret->state != _PR_FILEDESC_CLOSED)) { 1.205 + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); 1.206 + return PR_FAILURE; 1.207 + } 1.208 + 1.209 + if (fd->secret->state == _PR_FILEDESC_OPEN) { 1.210 + if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) { 1.211 + return PR_FAILURE; 1.212 + } 1.213 + fd->secret->state = _PR_FILEDESC_CLOSED; 1.214 + } 1.215 + PR_FreeFileDesc(fd); 1.216 + return PR_SUCCESS; 1.217 +} 1.218 + 1.219 +static PRInt16 PR_CALLBACK FilePoll( 1.220 + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) 1.221 +{ 1.222 + *out_flags = 0; 1.223 + return in_flags; 1.224 +} /* FilePoll */ 1.225 + 1.226 +static PRIOMethods _pr_fileMethods = { 1.227 + PR_DESC_FILE, 1.228 + FileClose, 1.229 + FileRead, 1.230 + FileWrite, 1.231 + FileAvailable, 1.232 + FileAvailable64, 1.233 + FileSync, 1.234 + FileSeek, 1.235 + FileSeek64, 1.236 + FileGetInfo, 1.237 + FileGetInfo64, 1.238 + (PRWritevFN)_PR_InvalidInt, 1.239 + (PRConnectFN)_PR_InvalidStatus, 1.240 + (PRAcceptFN)_PR_InvalidDesc, 1.241 + (PRBindFN)_PR_InvalidStatus, 1.242 + (PRListenFN)_PR_InvalidStatus, 1.243 + (PRShutdownFN)_PR_InvalidStatus, 1.244 + (PRRecvFN)_PR_InvalidInt, 1.245 + (PRSendFN)_PR_InvalidInt, 1.246 + (PRRecvfromFN)_PR_InvalidInt, 1.247 + (PRSendtoFN)_PR_InvalidInt, 1.248 + FilePoll, 1.249 + (PRAcceptreadFN)_PR_InvalidInt, 1.250 + (PRTransmitfileFN)_PR_InvalidInt, 1.251 + (PRGetsocknameFN)_PR_InvalidStatus, 1.252 + (PRGetpeernameFN)_PR_InvalidStatus, 1.253 + (PRReservedFN)_PR_InvalidInt, 1.254 + (PRReservedFN)_PR_InvalidInt, 1.255 + (PRGetsocketoptionFN)_PR_InvalidStatus, 1.256 + (PRSetsocketoptionFN)_PR_InvalidStatus, 1.257 + (PRSendfileFN)_PR_InvalidInt, 1.258 + (PRConnectcontinueFN)_PR_InvalidStatus, 1.259 + (PRReservedFN)_PR_InvalidInt, 1.260 + (PRReservedFN)_PR_InvalidInt, 1.261 + (PRReservedFN)_PR_InvalidInt, 1.262 + (PRReservedFN)_PR_InvalidInt 1.263 +}; 1.264 + 1.265 +PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) 1.266 +{ 1.267 + return &_pr_fileMethods; 1.268 +} 1.269 + 1.270 +static PRIOMethods _pr_pipeMethods = { 1.271 + PR_DESC_PIPE, 1.272 + FileClose, 1.273 + FileRead, 1.274 + FileWrite, 1.275 + PipeAvailable, 1.276 + PipeAvailable64, 1.277 + PipeSync, 1.278 + (PRSeekFN)_PR_InvalidInt, 1.279 + (PRSeek64FN)_PR_InvalidInt64, 1.280 + (PRFileInfoFN)_PR_InvalidStatus, 1.281 + (PRFileInfo64FN)_PR_InvalidStatus, 1.282 + (PRWritevFN)_PR_InvalidInt, 1.283 + (PRConnectFN)_PR_InvalidStatus, 1.284 + (PRAcceptFN)_PR_InvalidDesc, 1.285 + (PRBindFN)_PR_InvalidStatus, 1.286 + (PRListenFN)_PR_InvalidStatus, 1.287 + (PRShutdownFN)_PR_InvalidStatus, 1.288 + (PRRecvFN)_PR_InvalidInt, 1.289 + (PRSendFN)_PR_InvalidInt, 1.290 + (PRRecvfromFN)_PR_InvalidInt, 1.291 + (PRSendtoFN)_PR_InvalidInt, 1.292 + FilePoll, 1.293 + (PRAcceptreadFN)_PR_InvalidInt, 1.294 + (PRTransmitfileFN)_PR_InvalidInt, 1.295 + (PRGetsocknameFN)_PR_InvalidStatus, 1.296 + (PRGetpeernameFN)_PR_InvalidStatus, 1.297 + (PRReservedFN)_PR_InvalidInt, 1.298 + (PRReservedFN)_PR_InvalidInt, 1.299 + (PRGetsocketoptionFN)_PR_InvalidStatus, 1.300 + (PRSetsocketoptionFN)_PR_InvalidStatus, 1.301 + (PRSendfileFN)_PR_InvalidInt, 1.302 + (PRConnectcontinueFN)_PR_InvalidStatus, 1.303 + (PRReservedFN)_PR_InvalidInt, 1.304 + (PRReservedFN)_PR_InvalidInt, 1.305 + (PRReservedFN)_PR_InvalidInt, 1.306 + (PRReservedFN)_PR_InvalidInt 1.307 +}; 1.308 + 1.309 +PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) 1.310 +{ 1.311 + return &_pr_pipeMethods; 1.312 +} 1.313 + 1.314 +PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) 1.315 +{ 1.316 + PROsfd osfd; 1.317 + PRFileDesc *fd = 0; 1.318 +#if !defined(_PR_HAVE_O_APPEND) 1.319 + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; 1.320 +#endif 1.321 + 1.322 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.323 + 1.324 + /* Map pr open flags and mode to os specific flags */ 1.325 + 1.326 + osfd = _PR_MD_OPEN(name, flags, mode); 1.327 + if (osfd != -1) { 1.328 + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); 1.329 + if (!fd) { 1.330 + (void) _PR_MD_CLOSE_FILE(osfd); 1.331 + } else { 1.332 +#if !defined(_PR_HAVE_O_APPEND) 1.333 + fd->secret->appendMode = appendMode; 1.334 +#endif 1.335 + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); 1.336 + } 1.337 + } 1.338 + return fd; 1.339 +} 1.340 + 1.341 +PR_IMPLEMENT(PRFileDesc*) PR_OpenFile( 1.342 + const char *name, PRIntn flags, PRIntn mode) 1.343 +{ 1.344 + PROsfd osfd; 1.345 + PRFileDesc *fd = 0; 1.346 +#if !defined(_PR_HAVE_O_APPEND) 1.347 + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; 1.348 +#endif 1.349 + 1.350 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.351 + 1.352 + /* Map pr open flags and mode to os specific flags */ 1.353 + 1.354 + osfd = _PR_MD_OPEN_FILE(name, flags, mode); 1.355 + if (osfd != -1) { 1.356 + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); 1.357 + if (!fd) { 1.358 + (void) _PR_MD_CLOSE_FILE(osfd); 1.359 + } else { 1.360 +#if !defined(_PR_HAVE_O_APPEND) 1.361 + fd->secret->appendMode = appendMode; 1.362 +#endif 1.363 + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); 1.364 + } 1.365 + } 1.366 + return fd; 1.367 +} 1.368 + 1.369 +PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) 1.370 +{ 1.371 +#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) 1.372 + struct rlimit rlim; 1.373 + 1.374 + if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) { 1.375 + /* XXX need to call PR_SetError() */ 1.376 + return -1; 1.377 + } 1.378 + 1.379 + return rlim.rlim_max; 1.380 +#elif defined(AIX) || defined(QNX) 1.381 + return sysconf(_SC_OPEN_MAX); 1.382 +#elif defined(WIN32) 1.383 + /* 1.384 + * There is a systemwide limit of 65536 user handles. 1.385 + */ 1.386 + return 16384; 1.387 +#elif defined (WIN16) 1.388 + return FOPEN_MAX; 1.389 +#elif defined(XP_OS2) 1.390 + ULONG ulReqCount = 0; 1.391 + ULONG ulCurMaxFH = 0; 1.392 + DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH); 1.393 + return ulCurMaxFH; 1.394 +#elif defined(XP_BEOS) 1.395 + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); 1.396 + return -1; 1.397 +#else 1.398 + write me; 1.399 +#endif 1.400 +} 1.401 + 1.402 +PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size) 1.403 +{ 1.404 +#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) 1.405 + struct rlimit rlim; 1.406 + PRInt32 tableMax = PR_GetSysfdTableMax(); 1.407 + 1.408 + if (tableMax < 0) 1.409 + return -1; 1.410 + 1.411 + if (tableMax > FD_SETSIZE) 1.412 + tableMax = FD_SETSIZE; 1.413 + 1.414 + rlim.rlim_max = tableMax; 1.415 + 1.416 + /* Grow as much as we can; even if too big */ 1.417 + if ( rlim.rlim_max < table_size ) 1.418 + rlim.rlim_cur = rlim.rlim_max; 1.419 + else 1.420 + rlim.rlim_cur = table_size; 1.421 + 1.422 + if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) { 1.423 + /* XXX need to call PR_SetError() */ 1.424 + return -1; 1.425 + } 1.426 + 1.427 + return rlim.rlim_cur; 1.428 +#elif defined(XP_OS2) 1.429 + PRInt32 tableMax = PR_GetSysfdTableMax(); 1.430 + if (table_size > tableMax) { 1.431 + APIRET rc = NO_ERROR; 1.432 + rc = DosSetMaxFH(table_size); 1.433 + if (rc == NO_ERROR) 1.434 + return table_size; 1.435 + else 1.436 + return -1; 1.437 + } 1.438 + return tableMax; 1.439 +#elif defined(AIX) || defined(QNX) \ 1.440 + || defined(WIN32) || defined(WIN16) || defined(XP_BEOS) 1.441 + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); 1.442 + return -1; 1.443 +#else 1.444 + write me; 1.445 +#endif 1.446 +} 1.447 + 1.448 +PR_IMPLEMENT(PRStatus) PR_Delete(const char *name) 1.449 +{ 1.450 + PRInt32 rv; 1.451 + 1.452 + rv = _PR_MD_DELETE(name); 1.453 + if (rv < 0) { 1.454 + return PR_FAILURE; 1.455 + } else 1.456 + return PR_SUCCESS; 1.457 +} 1.458 + 1.459 +PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info) 1.460 +{ 1.461 + PRInt32 rv; 1.462 + 1.463 + rv = _PR_MD_GETFILEINFO(fn, info); 1.464 + if (rv < 0) { 1.465 + return PR_FAILURE; 1.466 + } else 1.467 + return PR_SUCCESS; 1.468 +} 1.469 + 1.470 +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info) 1.471 +{ 1.472 + PRInt32 rv; 1.473 + 1.474 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.475 + rv = _PR_MD_GETFILEINFO64(fn, info); 1.476 + if (rv < 0) { 1.477 + return PR_FAILURE; 1.478 + } else { 1.479 + return PR_SUCCESS; 1.480 + } 1.481 +} 1.482 + 1.483 +PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to) 1.484 +{ 1.485 + PRInt32 rv; 1.486 + 1.487 + rv = _PR_MD_RENAME(from, to); 1.488 + if (rv < 0) { 1.489 + return PR_FAILURE; 1.490 + } else 1.491 + return PR_SUCCESS; 1.492 +} 1.493 + 1.494 +PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) 1.495 +{ 1.496 +PRInt32 rv; 1.497 + 1.498 + rv = _PR_MD_ACCESS(name, how); 1.499 + if (rv < 0) { 1.500 + return PR_FAILURE; 1.501 + } else 1.502 + return PR_SUCCESS; 1.503 +} 1.504 + 1.505 +/* 1.506 +** Import an existing OS file to NSPR 1.507 +*/ 1.508 +PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd) 1.509 +{ 1.510 + PRFileDesc *fd = NULL; 1.511 + 1.512 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.513 + 1.514 + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); 1.515 + if( !fd ) { 1.516 + (void) _PR_MD_CLOSE_FILE(osfd); 1.517 + } else { 1.518 + _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); 1.519 + } 1.520 + 1.521 + return fd; 1.522 +} 1.523 + 1.524 +/* 1.525 +** Import an existing OS pipe to NSPR 1.526 +*/ 1.527 +PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd) 1.528 +{ 1.529 + PRFileDesc *fd = NULL; 1.530 + 1.531 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.532 + 1.533 + fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods); 1.534 + if( !fd ) { 1.535 + (void) _PR_MD_CLOSE_FILE(osfd); 1.536 + } else { 1.537 + _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); 1.538 +#ifdef WINNT 1.539 + fd->secret->md.sync_file_io = PR_TRUE; 1.540 +#endif 1.541 + } 1.542 + 1.543 + return fd; 1.544 +} 1.545 + 1.546 +#ifndef NO_NSPR_10_SUPPORT 1.547 +/* 1.548 +** PR_Stat() for Win16 is defined in w16io.c 1.549 +** it is a hack to circumvent problems in Gromit and Java 1.550 +** See also: BugSplat: 98516. 1.551 +*/ 1.552 +#if !defined(WIN16) 1.553 +/* 1.554 + * This function is supposed to be for backward compatibility with 1.555 + * nspr 1.0. Therefore, it still uses the nspr 1.0 error-reporting 1.556 + * mechanism -- returns a PRInt32, which is the error code when the call 1.557 + * fails. 1.558 + * 1.559 + * If we need this function in nspr 2.0, it should be changed to 1.560 + * return PRStatus, as follows: 1.561 + * 1.562 + * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf) 1.563 + * { 1.564 + * PRInt32 rv; 1.565 + * 1.566 + * rv = _PR_MD_STAT(name, buf); 1.567 + * if (rv < 0) 1.568 + * return PR_FAILURE; 1.569 + * else 1.570 + * return PR_SUCCESS; 1.571 + * } 1.572 + * 1.573 + * -- wtc, 2/14/97. 1.574 + */ 1.575 +PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) 1.576 +{ 1.577 + PRInt32 rv; 1.578 + 1.579 + rv = _PR_MD_STAT(name, buf); 1.580 + return rv; 1.581 +} 1.582 + 1.583 +#endif /* !defined(WIN16) */ 1.584 +#endif /* ! NO_NSPR_10_SUPPORT */ 1.585 + 1.586 +PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) 1.587 +{ 1.588 + PRStatus status = PR_SUCCESS; 1.589 + 1.590 +#ifdef WINNT 1.591 + if (!fd->secret->md.io_model_committed) { 1.592 + PRInt32 rv; 1.593 + rv = _md_Associate((HANDLE)fd->secret->md.osfd); 1.594 + PR_ASSERT(0 != rv); 1.595 + fd->secret->md.io_model_committed = PR_TRUE; 1.596 + } 1.597 +#endif 1.598 + 1.599 + PR_Lock(_pr_flock_lock); 1.600 + while (fd->secret->lockCount == -1) 1.601 + PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT); 1.602 + if (fd->secret->lockCount == 0) { 1.603 + fd->secret->lockCount = -1; 1.604 + PR_Unlock(_pr_flock_lock); 1.605 + status = _PR_MD_LOCKFILE(fd->secret->md.osfd); 1.606 + PR_Lock(_pr_flock_lock); 1.607 + fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0; 1.608 + PR_NotifyAllCondVar(_pr_flock_cv); 1.609 + } else { 1.610 + fd->secret->lockCount++; 1.611 + } 1.612 + PR_Unlock(_pr_flock_lock); 1.613 + 1.614 + return status; 1.615 +} 1.616 + 1.617 +PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) 1.618 +{ 1.619 + PRStatus status = PR_SUCCESS; 1.620 + 1.621 +#ifdef WINNT 1.622 + if (!fd->secret->md.io_model_committed) { 1.623 + PRInt32 rv; 1.624 + rv = _md_Associate((HANDLE)fd->secret->md.osfd); 1.625 + PR_ASSERT(0 != rv); 1.626 + fd->secret->md.io_model_committed = PR_TRUE; 1.627 + } 1.628 +#endif 1.629 + 1.630 + PR_Lock(_pr_flock_lock); 1.631 + if (fd->secret->lockCount == 0) { 1.632 + status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); 1.633 + PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0); 1.634 + if (status == PR_SUCCESS) 1.635 + fd->secret->lockCount = 1; 1.636 + } else { 1.637 + fd->secret->lockCount++; 1.638 + } 1.639 + PR_Unlock(_pr_flock_lock); 1.640 + 1.641 + return status; 1.642 +} 1.643 + 1.644 +PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) 1.645 +{ 1.646 + PRStatus rv = PR_SUCCESS; 1.647 + 1.648 + PR_Lock(_pr_flock_lock); 1.649 + if (fd->secret->lockCount == 1) { 1.650 + rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd); 1.651 + if (rv == PR_SUCCESS) 1.652 + fd->secret->lockCount = 0; 1.653 + } else { 1.654 + fd->secret->lockCount--; 1.655 + } 1.656 + PR_Unlock(_pr_flock_lock); 1.657 + 1.658 + return rv; 1.659 +} 1.660 + 1.661 +PR_IMPLEMENT(PRStatus) PR_CreatePipe( 1.662 + PRFileDesc **readPipe, 1.663 + PRFileDesc **writePipe 1.664 +) 1.665 +{ 1.666 +#if defined(WIN32) && !defined(WINCE) 1.667 + HANDLE readEnd, writeEnd; 1.668 + SECURITY_ATTRIBUTES pipeAttributes; 1.669 + 1.670 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.671 + 1.672 + ZeroMemory(&pipeAttributes, sizeof(pipeAttributes)); 1.673 + pipeAttributes.nLength = sizeof(pipeAttributes); 1.674 + pipeAttributes.bInheritHandle = TRUE; 1.675 + if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) { 1.676 + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); 1.677 + return PR_FAILURE; 1.678 + } 1.679 + *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods); 1.680 + if (NULL == *readPipe) { 1.681 + CloseHandle(readEnd); 1.682 + CloseHandle(writeEnd); 1.683 + return PR_FAILURE; 1.684 + } 1.685 + *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods); 1.686 + if (NULL == *writePipe) { 1.687 + PR_Close(*readPipe); 1.688 + CloseHandle(writeEnd); 1.689 + return PR_FAILURE; 1.690 + } 1.691 +#ifdef WINNT 1.692 + (*readPipe)->secret->md.sync_file_io = PR_TRUE; 1.693 + (*writePipe)->secret->md.sync_file_io = PR_TRUE; 1.694 +#endif 1.695 + (*readPipe)->secret->inheritable = _PR_TRI_TRUE; 1.696 + (*writePipe)->secret->inheritable = _PR_TRI_TRUE; 1.697 + return PR_SUCCESS; 1.698 +#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) 1.699 +#ifdef XP_OS2 1.700 + HFILE pipefd[2]; 1.701 +#else 1.702 + int pipefd[2]; 1.703 +#endif 1.704 + 1.705 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.706 + 1.707 +#ifdef XP_OS2 1.708 + if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) { 1.709 +#else 1.710 + if (pipe(pipefd) == -1) { 1.711 +#endif 1.712 + /* XXX map pipe error */ 1.713 + PR_SetError(PR_UNKNOWN_ERROR, errno); 1.714 + return PR_FAILURE; 1.715 + } 1.716 + *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods); 1.717 + if (NULL == *readPipe) { 1.718 + close(pipefd[0]); 1.719 + close(pipefd[1]); 1.720 + return PR_FAILURE; 1.721 + } 1.722 + *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods); 1.723 + if (NULL == *writePipe) { 1.724 + PR_Close(*readPipe); 1.725 + close(pipefd[1]); 1.726 + return PR_FAILURE; 1.727 + } 1.728 +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ 1.729 + _PR_MD_MAKE_NONBLOCK(*readPipe); 1.730 +#endif 1.731 + _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE); 1.732 +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ 1.733 + _PR_MD_MAKE_NONBLOCK(*writePipe); 1.734 +#endif 1.735 + _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE); 1.736 + return PR_SUCCESS; 1.737 +#else 1.738 + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); 1.739 + return PR_FAILURE; 1.740 +#endif 1.741 +} 1.742 + 1.743 +#ifdef MOZ_UNICODE 1.744 +/* ================ UTF16 Interfaces ================================ */ 1.745 +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( 1.746 + const PRUnichar *name, PRIntn flags, PRIntn mode) 1.747 +{ 1.748 + PROsfd osfd; 1.749 + PRFileDesc *fd = 0; 1.750 +#if !defined(_PR_HAVE_O_APPEND) 1.751 + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; 1.752 +#endif 1.753 + 1.754 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.755 + 1.756 + /* Map pr open flags and mode to os specific flags */ 1.757 + osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode); 1.758 + if (osfd != -1) { 1.759 + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); 1.760 + if (!fd) { 1.761 + (void) _PR_MD_CLOSE_FILE(osfd); 1.762 + } else { 1.763 +#if !defined(_PR_HAVE_O_APPEND) 1.764 + fd->secret->appendMode = appendMode; 1.765 +#endif 1.766 + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); 1.767 + } 1.768 + } 1.769 + return fd; 1.770 +} 1.771 + 1.772 +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) 1.773 +{ 1.774 + PRInt32 rv; 1.775 + 1.776 + if (!_pr_initialized) _PR_ImplicitInitialization(); 1.777 + rv = _PR_MD_GETFILEINFO64_UTF16(fn, info); 1.778 + if (rv < 0) { 1.779 + return PR_FAILURE; 1.780 + } else { 1.781 + return PR_SUCCESS; 1.782 + } 1.783 +} 1.784 + 1.785 +/* ================ UTF16 Interfaces ================================ */ 1.786 +#endif /* MOZ_UNICODE */