nsprpub/pr/src/io/prfile.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "primpl.h"
michael@0 7
michael@0 8 #include <string.h>
michael@0 9 #include <fcntl.h>
michael@0 10
michael@0 11 #ifdef XP_UNIX
michael@0 12 #if defined(AIX) || defined(QNX)
michael@0 13 /* To pick up sysconf */
michael@0 14 #include <unistd.h>
michael@0 15 #else
michael@0 16 /* To pick up getrlimit, setrlimit */
michael@0 17 #include <sys/time.h>
michael@0 18 #include <sys/resource.h>
michael@0 19 #endif
michael@0 20 #endif /* XP_UNIX */
michael@0 21
michael@0 22 extern PRLock *_pr_flock_lock;
michael@0 23 extern PRCondVar *_pr_flock_cv;
michael@0 24
michael@0 25 static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount)
michael@0 26 {
michael@0 27 PRInt32 rv = 0;
michael@0 28 PRThread *me = _PR_MD_CURRENT_THREAD();
michael@0 29
michael@0 30 if (_PR_PENDING_INTERRUPT(me)) {
michael@0 31 me->flags &= ~_PR_INTERRUPT;
michael@0 32 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
michael@0 33 rv = -1;
michael@0 34 }
michael@0 35 if (_PR_IO_PENDING(me)) {
michael@0 36 PR_SetError(PR_IO_PENDING_ERROR, 0);
michael@0 37 rv = -1;
michael@0 38 }
michael@0 39 if (rv == -1)
michael@0 40 return rv;
michael@0 41
michael@0 42 rv = _PR_MD_READ(fd, buf, amount);
michael@0 43 if (rv < 0) {
michael@0 44 PR_ASSERT(rv == -1);
michael@0 45 }
michael@0 46 PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
michael@0 47 return rv;
michael@0 48 }
michael@0 49
michael@0 50 static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
michael@0 51 {
michael@0 52 PRInt32 rv = 0;
michael@0 53 PRInt32 temp, count;
michael@0 54 PRThread *me = _PR_MD_CURRENT_THREAD();
michael@0 55
michael@0 56 if (_PR_PENDING_INTERRUPT(me)) {
michael@0 57 me->flags &= ~_PR_INTERRUPT;
michael@0 58 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
michael@0 59 rv = -1;
michael@0 60 }
michael@0 61 if (_PR_IO_PENDING(me)) {
michael@0 62 PR_SetError(PR_IO_PENDING_ERROR, 0);
michael@0 63 rv = -1;
michael@0 64 }
michael@0 65 if (rv != 0)
michael@0 66 return rv;
michael@0 67
michael@0 68 count = 0;
michael@0 69 #if !defined(_PR_HAVE_O_APPEND) /* Bugzilla: 4090, 276330 */
michael@0 70 if (fd->secret->appendMode) {
michael@0 71 if (PR_Seek64(fd, 0, PR_SEEK_END) == -1) {
michael@0 72 return -1;
michael@0 73 }
michael@0 74 } /* if (fd->secret->appendMode...) */
michael@0 75 #endif /* _PR_HAVE_O_APPEND */
michael@0 76 while (amount > 0) {
michael@0 77 temp = _PR_MD_WRITE(fd, buf, amount);
michael@0 78 if (temp < 0) {
michael@0 79 count = -1;
michael@0 80 break;
michael@0 81 }
michael@0 82 count += temp;
michael@0 83 if (fd->secret->nonblocking) {
michael@0 84 break;
michael@0 85 }
michael@0 86 buf = (const void*) ((const char*)buf + temp);
michael@0 87 amount -= temp;
michael@0 88 }
michael@0 89 PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
michael@0 90 return count;
michael@0 91 }
michael@0 92
michael@0 93 static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
michael@0 94 {
michael@0 95 PROffset32 result;
michael@0 96
michael@0 97 result = _PR_MD_LSEEK(fd, offset, whence);
michael@0 98 return result;
michael@0 99 }
michael@0 100
michael@0 101 static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
michael@0 102 {
michael@0 103 PROffset64 result;
michael@0 104
michael@0 105 result = _PR_MD_LSEEK64(fd, offset, whence);
michael@0 106 return result;
michael@0 107 }
michael@0 108
michael@0 109 static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd)
michael@0 110 {
michael@0 111 PRInt32 result, cur, end;
michael@0 112
michael@0 113 cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
michael@0 114
michael@0 115 if (cur >= 0)
michael@0 116 end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
michael@0 117
michael@0 118 if ((cur < 0) || (end < 0)) {
michael@0 119 return -1;
michael@0 120 }
michael@0 121
michael@0 122 result = end - cur;
michael@0 123 _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
michael@0 124
michael@0 125 return result;
michael@0 126 }
michael@0 127
michael@0 128 static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
michael@0 129 {
michael@0 130 PRInt64 result, cur, end;
michael@0 131 PRInt64 minus_one;
michael@0 132
michael@0 133 LL_I2L(minus_one, -1);
michael@0 134 cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
michael@0 135
michael@0 136 if (LL_GE_ZERO(cur))
michael@0 137 end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
michael@0 138
michael@0 139 if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
michael@0 140
michael@0 141 LL_SUB(result, end, cur);
michael@0 142 (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
michael@0 143
michael@0 144 return result;
michael@0 145 }
michael@0 146
michael@0 147 static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
michael@0 148 {
michael@0 149 PRInt32 rv;
michael@0 150 rv = _PR_MD_PIPEAVAILABLE(fd);
michael@0 151 return rv;
michael@0 152 }
michael@0 153
michael@0 154 static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
michael@0 155 {
michael@0 156 PRInt64 rv;
michael@0 157 LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
michael@0 158 return rv;
michael@0 159 }
michael@0 160
michael@0 161 static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd)
michael@0 162 {
michael@0 163 return PR_SUCCESS;
michael@0 164 }
michael@0 165
michael@0 166 static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info)
michael@0 167 {
michael@0 168 PRInt32 rv;
michael@0 169
michael@0 170 rv = _PR_MD_GETOPENFILEINFO(fd, info);
michael@0 171 if (rv < 0) {
michael@0 172 return PR_FAILURE;
michael@0 173 } else
michael@0 174 return PR_SUCCESS;
michael@0 175 }
michael@0 176
michael@0 177 static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info)
michael@0 178 {
michael@0 179 /* $$$$ NOT YET IMPLEMENTED */
michael@0 180 PRInt32 rv;
michael@0 181
michael@0 182 rv = _PR_MD_GETOPENFILEINFO64(fd, info);
michael@0 183 if (rv < 0) return PR_FAILURE;
michael@0 184 else return PR_SUCCESS;
michael@0 185 }
michael@0 186
michael@0 187 static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
michael@0 188 {
michael@0 189 PRInt32 result;
michael@0 190 result = _PR_MD_FSYNC(fd);
michael@0 191 if (result < 0) {
michael@0 192 return PR_FAILURE;
michael@0 193 }
michael@0 194 return PR_SUCCESS;
michael@0 195 }
michael@0 196
michael@0 197 static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
michael@0 198 {
michael@0 199 if (!fd || !fd->secret
michael@0 200 || (fd->secret->state != _PR_FILEDESC_OPEN
michael@0 201 && fd->secret->state != _PR_FILEDESC_CLOSED)) {
michael@0 202 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
michael@0 203 return PR_FAILURE;
michael@0 204 }
michael@0 205
michael@0 206 if (fd->secret->state == _PR_FILEDESC_OPEN) {
michael@0 207 if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) {
michael@0 208 return PR_FAILURE;
michael@0 209 }
michael@0 210 fd->secret->state = _PR_FILEDESC_CLOSED;
michael@0 211 }
michael@0 212 PR_FreeFileDesc(fd);
michael@0 213 return PR_SUCCESS;
michael@0 214 }
michael@0 215
michael@0 216 static PRInt16 PR_CALLBACK FilePoll(
michael@0 217 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
michael@0 218 {
michael@0 219 *out_flags = 0;
michael@0 220 return in_flags;
michael@0 221 } /* FilePoll */
michael@0 222
michael@0 223 static PRIOMethods _pr_fileMethods = {
michael@0 224 PR_DESC_FILE,
michael@0 225 FileClose,
michael@0 226 FileRead,
michael@0 227 FileWrite,
michael@0 228 FileAvailable,
michael@0 229 FileAvailable64,
michael@0 230 FileSync,
michael@0 231 FileSeek,
michael@0 232 FileSeek64,
michael@0 233 FileGetInfo,
michael@0 234 FileGetInfo64,
michael@0 235 (PRWritevFN)_PR_InvalidInt,
michael@0 236 (PRConnectFN)_PR_InvalidStatus,
michael@0 237 (PRAcceptFN)_PR_InvalidDesc,
michael@0 238 (PRBindFN)_PR_InvalidStatus,
michael@0 239 (PRListenFN)_PR_InvalidStatus,
michael@0 240 (PRShutdownFN)_PR_InvalidStatus,
michael@0 241 (PRRecvFN)_PR_InvalidInt,
michael@0 242 (PRSendFN)_PR_InvalidInt,
michael@0 243 (PRRecvfromFN)_PR_InvalidInt,
michael@0 244 (PRSendtoFN)_PR_InvalidInt,
michael@0 245 FilePoll,
michael@0 246 (PRAcceptreadFN)_PR_InvalidInt,
michael@0 247 (PRTransmitfileFN)_PR_InvalidInt,
michael@0 248 (PRGetsocknameFN)_PR_InvalidStatus,
michael@0 249 (PRGetpeernameFN)_PR_InvalidStatus,
michael@0 250 (PRReservedFN)_PR_InvalidInt,
michael@0 251 (PRReservedFN)_PR_InvalidInt,
michael@0 252 (PRGetsocketoptionFN)_PR_InvalidStatus,
michael@0 253 (PRSetsocketoptionFN)_PR_InvalidStatus,
michael@0 254 (PRSendfileFN)_PR_InvalidInt,
michael@0 255 (PRConnectcontinueFN)_PR_InvalidStatus,
michael@0 256 (PRReservedFN)_PR_InvalidInt,
michael@0 257 (PRReservedFN)_PR_InvalidInt,
michael@0 258 (PRReservedFN)_PR_InvalidInt,
michael@0 259 (PRReservedFN)_PR_InvalidInt
michael@0 260 };
michael@0 261
michael@0 262 PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
michael@0 263 {
michael@0 264 return &_pr_fileMethods;
michael@0 265 }
michael@0 266
michael@0 267 static PRIOMethods _pr_pipeMethods = {
michael@0 268 PR_DESC_PIPE,
michael@0 269 FileClose,
michael@0 270 FileRead,
michael@0 271 FileWrite,
michael@0 272 PipeAvailable,
michael@0 273 PipeAvailable64,
michael@0 274 PipeSync,
michael@0 275 (PRSeekFN)_PR_InvalidInt,
michael@0 276 (PRSeek64FN)_PR_InvalidInt64,
michael@0 277 (PRFileInfoFN)_PR_InvalidStatus,
michael@0 278 (PRFileInfo64FN)_PR_InvalidStatus,
michael@0 279 (PRWritevFN)_PR_InvalidInt,
michael@0 280 (PRConnectFN)_PR_InvalidStatus,
michael@0 281 (PRAcceptFN)_PR_InvalidDesc,
michael@0 282 (PRBindFN)_PR_InvalidStatus,
michael@0 283 (PRListenFN)_PR_InvalidStatus,
michael@0 284 (PRShutdownFN)_PR_InvalidStatus,
michael@0 285 (PRRecvFN)_PR_InvalidInt,
michael@0 286 (PRSendFN)_PR_InvalidInt,
michael@0 287 (PRRecvfromFN)_PR_InvalidInt,
michael@0 288 (PRSendtoFN)_PR_InvalidInt,
michael@0 289 FilePoll,
michael@0 290 (PRAcceptreadFN)_PR_InvalidInt,
michael@0 291 (PRTransmitfileFN)_PR_InvalidInt,
michael@0 292 (PRGetsocknameFN)_PR_InvalidStatus,
michael@0 293 (PRGetpeernameFN)_PR_InvalidStatus,
michael@0 294 (PRReservedFN)_PR_InvalidInt,
michael@0 295 (PRReservedFN)_PR_InvalidInt,
michael@0 296 (PRGetsocketoptionFN)_PR_InvalidStatus,
michael@0 297 (PRSetsocketoptionFN)_PR_InvalidStatus,
michael@0 298 (PRSendfileFN)_PR_InvalidInt,
michael@0 299 (PRConnectcontinueFN)_PR_InvalidStatus,
michael@0 300 (PRReservedFN)_PR_InvalidInt,
michael@0 301 (PRReservedFN)_PR_InvalidInt,
michael@0 302 (PRReservedFN)_PR_InvalidInt,
michael@0 303 (PRReservedFN)_PR_InvalidInt
michael@0 304 };
michael@0 305
michael@0 306 PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
michael@0 307 {
michael@0 308 return &_pr_pipeMethods;
michael@0 309 }
michael@0 310
michael@0 311 PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
michael@0 312 {
michael@0 313 PROsfd osfd;
michael@0 314 PRFileDesc *fd = 0;
michael@0 315 #if !defined(_PR_HAVE_O_APPEND)
michael@0 316 PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
michael@0 317 #endif
michael@0 318
michael@0 319 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 320
michael@0 321 /* Map pr open flags and mode to os specific flags */
michael@0 322
michael@0 323 osfd = _PR_MD_OPEN(name, flags, mode);
michael@0 324 if (osfd != -1) {
michael@0 325 fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
michael@0 326 if (!fd) {
michael@0 327 (void) _PR_MD_CLOSE_FILE(osfd);
michael@0 328 } else {
michael@0 329 #if !defined(_PR_HAVE_O_APPEND)
michael@0 330 fd->secret->appendMode = appendMode;
michael@0 331 #endif
michael@0 332 _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
michael@0 333 }
michael@0 334 }
michael@0 335 return fd;
michael@0 336 }
michael@0 337
michael@0 338 PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
michael@0 339 const char *name, PRIntn flags, PRIntn mode)
michael@0 340 {
michael@0 341 PROsfd osfd;
michael@0 342 PRFileDesc *fd = 0;
michael@0 343 #if !defined(_PR_HAVE_O_APPEND)
michael@0 344 PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
michael@0 345 #endif
michael@0 346
michael@0 347 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 348
michael@0 349 /* Map pr open flags and mode to os specific flags */
michael@0 350
michael@0 351 osfd = _PR_MD_OPEN_FILE(name, flags, mode);
michael@0 352 if (osfd != -1) {
michael@0 353 fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
michael@0 354 if (!fd) {
michael@0 355 (void) _PR_MD_CLOSE_FILE(osfd);
michael@0 356 } else {
michael@0 357 #if !defined(_PR_HAVE_O_APPEND)
michael@0 358 fd->secret->appendMode = appendMode;
michael@0 359 #endif
michael@0 360 _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
michael@0 361 }
michael@0 362 }
michael@0 363 return fd;
michael@0 364 }
michael@0 365
michael@0 366 PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
michael@0 367 {
michael@0 368 #if defined(XP_UNIX) && !defined(AIX) && !defined(QNX)
michael@0 369 struct rlimit rlim;
michael@0 370
michael@0 371 if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
michael@0 372 /* XXX need to call PR_SetError() */
michael@0 373 return -1;
michael@0 374 }
michael@0 375
michael@0 376 return rlim.rlim_max;
michael@0 377 #elif defined(AIX) || defined(QNX)
michael@0 378 return sysconf(_SC_OPEN_MAX);
michael@0 379 #elif defined(WIN32)
michael@0 380 /*
michael@0 381 * There is a systemwide limit of 65536 user handles.
michael@0 382 */
michael@0 383 return 16384;
michael@0 384 #elif defined (WIN16)
michael@0 385 return FOPEN_MAX;
michael@0 386 #elif defined(XP_OS2)
michael@0 387 ULONG ulReqCount = 0;
michael@0 388 ULONG ulCurMaxFH = 0;
michael@0 389 DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH);
michael@0 390 return ulCurMaxFH;
michael@0 391 #elif defined(XP_BEOS)
michael@0 392 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 393 return -1;
michael@0 394 #else
michael@0 395 write me;
michael@0 396 #endif
michael@0 397 }
michael@0 398
michael@0 399 PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
michael@0 400 {
michael@0 401 #if defined(XP_UNIX) && !defined(AIX) && !defined(QNX)
michael@0 402 struct rlimit rlim;
michael@0 403 PRInt32 tableMax = PR_GetSysfdTableMax();
michael@0 404
michael@0 405 if (tableMax < 0)
michael@0 406 return -1;
michael@0 407
michael@0 408 if (tableMax > FD_SETSIZE)
michael@0 409 tableMax = FD_SETSIZE;
michael@0 410
michael@0 411 rlim.rlim_max = tableMax;
michael@0 412
michael@0 413 /* Grow as much as we can; even if too big */
michael@0 414 if ( rlim.rlim_max < table_size )
michael@0 415 rlim.rlim_cur = rlim.rlim_max;
michael@0 416 else
michael@0 417 rlim.rlim_cur = table_size;
michael@0 418
michael@0 419 if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
michael@0 420 /* XXX need to call PR_SetError() */
michael@0 421 return -1;
michael@0 422 }
michael@0 423
michael@0 424 return rlim.rlim_cur;
michael@0 425 #elif defined(XP_OS2)
michael@0 426 PRInt32 tableMax = PR_GetSysfdTableMax();
michael@0 427 if (table_size > tableMax) {
michael@0 428 APIRET rc = NO_ERROR;
michael@0 429 rc = DosSetMaxFH(table_size);
michael@0 430 if (rc == NO_ERROR)
michael@0 431 return table_size;
michael@0 432 else
michael@0 433 return -1;
michael@0 434 }
michael@0 435 return tableMax;
michael@0 436 #elif defined(AIX) || defined(QNX) \
michael@0 437 || defined(WIN32) || defined(WIN16) || defined(XP_BEOS)
michael@0 438 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 439 return -1;
michael@0 440 #else
michael@0 441 write me;
michael@0 442 #endif
michael@0 443 }
michael@0 444
michael@0 445 PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
michael@0 446 {
michael@0 447 PRInt32 rv;
michael@0 448
michael@0 449 rv = _PR_MD_DELETE(name);
michael@0 450 if (rv < 0) {
michael@0 451 return PR_FAILURE;
michael@0 452 } else
michael@0 453 return PR_SUCCESS;
michael@0 454 }
michael@0 455
michael@0 456 PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
michael@0 457 {
michael@0 458 PRInt32 rv;
michael@0 459
michael@0 460 rv = _PR_MD_GETFILEINFO(fn, info);
michael@0 461 if (rv < 0) {
michael@0 462 return PR_FAILURE;
michael@0 463 } else
michael@0 464 return PR_SUCCESS;
michael@0 465 }
michael@0 466
michael@0 467 PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
michael@0 468 {
michael@0 469 PRInt32 rv;
michael@0 470
michael@0 471 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 472 rv = _PR_MD_GETFILEINFO64(fn, info);
michael@0 473 if (rv < 0) {
michael@0 474 return PR_FAILURE;
michael@0 475 } else {
michael@0 476 return PR_SUCCESS;
michael@0 477 }
michael@0 478 }
michael@0 479
michael@0 480 PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
michael@0 481 {
michael@0 482 PRInt32 rv;
michael@0 483
michael@0 484 rv = _PR_MD_RENAME(from, to);
michael@0 485 if (rv < 0) {
michael@0 486 return PR_FAILURE;
michael@0 487 } else
michael@0 488 return PR_SUCCESS;
michael@0 489 }
michael@0 490
michael@0 491 PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
michael@0 492 {
michael@0 493 PRInt32 rv;
michael@0 494
michael@0 495 rv = _PR_MD_ACCESS(name, how);
michael@0 496 if (rv < 0) {
michael@0 497 return PR_FAILURE;
michael@0 498 } else
michael@0 499 return PR_SUCCESS;
michael@0 500 }
michael@0 501
michael@0 502 /*
michael@0 503 ** Import an existing OS file to NSPR
michael@0 504 */
michael@0 505 PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd)
michael@0 506 {
michael@0 507 PRFileDesc *fd = NULL;
michael@0 508
michael@0 509 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 510
michael@0 511 fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
michael@0 512 if( !fd ) {
michael@0 513 (void) _PR_MD_CLOSE_FILE(osfd);
michael@0 514 } else {
michael@0 515 _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
michael@0 516 }
michael@0 517
michael@0 518 return fd;
michael@0 519 }
michael@0 520
michael@0 521 /*
michael@0 522 ** Import an existing OS pipe to NSPR
michael@0 523 */
michael@0 524 PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd)
michael@0 525 {
michael@0 526 PRFileDesc *fd = NULL;
michael@0 527
michael@0 528 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 529
michael@0 530 fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods);
michael@0 531 if( !fd ) {
michael@0 532 (void) _PR_MD_CLOSE_FILE(osfd);
michael@0 533 } else {
michael@0 534 _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
michael@0 535 #ifdef WINNT
michael@0 536 fd->secret->md.sync_file_io = PR_TRUE;
michael@0 537 #endif
michael@0 538 }
michael@0 539
michael@0 540 return fd;
michael@0 541 }
michael@0 542
michael@0 543 #ifndef NO_NSPR_10_SUPPORT
michael@0 544 /*
michael@0 545 ** PR_Stat() for Win16 is defined in w16io.c
michael@0 546 ** it is a hack to circumvent problems in Gromit and Java
michael@0 547 ** See also: BugSplat: 98516.
michael@0 548 */
michael@0 549 #if !defined(WIN16)
michael@0 550 /*
michael@0 551 * This function is supposed to be for backward compatibility with
michael@0 552 * nspr 1.0. Therefore, it still uses the nspr 1.0 error-reporting
michael@0 553 * mechanism -- returns a PRInt32, which is the error code when the call
michael@0 554 * fails.
michael@0 555 *
michael@0 556 * If we need this function in nspr 2.0, it should be changed to
michael@0 557 * return PRStatus, as follows:
michael@0 558 *
michael@0 559 * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf)
michael@0 560 * {
michael@0 561 * PRInt32 rv;
michael@0 562 *
michael@0 563 * rv = _PR_MD_STAT(name, buf);
michael@0 564 * if (rv < 0)
michael@0 565 * return PR_FAILURE;
michael@0 566 * else
michael@0 567 * return PR_SUCCESS;
michael@0 568 * }
michael@0 569 *
michael@0 570 * -- wtc, 2/14/97.
michael@0 571 */
michael@0 572 PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
michael@0 573 {
michael@0 574 PRInt32 rv;
michael@0 575
michael@0 576 rv = _PR_MD_STAT(name, buf);
michael@0 577 return rv;
michael@0 578 }
michael@0 579
michael@0 580 #endif /* !defined(WIN16) */
michael@0 581 #endif /* ! NO_NSPR_10_SUPPORT */
michael@0 582
michael@0 583 PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
michael@0 584 {
michael@0 585 PRStatus status = PR_SUCCESS;
michael@0 586
michael@0 587 #ifdef WINNT
michael@0 588 if (!fd->secret->md.io_model_committed) {
michael@0 589 PRInt32 rv;
michael@0 590 rv = _md_Associate((HANDLE)fd->secret->md.osfd);
michael@0 591 PR_ASSERT(0 != rv);
michael@0 592 fd->secret->md.io_model_committed = PR_TRUE;
michael@0 593 }
michael@0 594 #endif
michael@0 595
michael@0 596 PR_Lock(_pr_flock_lock);
michael@0 597 while (fd->secret->lockCount == -1)
michael@0 598 PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
michael@0 599 if (fd->secret->lockCount == 0) {
michael@0 600 fd->secret->lockCount = -1;
michael@0 601 PR_Unlock(_pr_flock_lock);
michael@0 602 status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
michael@0 603 PR_Lock(_pr_flock_lock);
michael@0 604 fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0;
michael@0 605 PR_NotifyAllCondVar(_pr_flock_cv);
michael@0 606 } else {
michael@0 607 fd->secret->lockCount++;
michael@0 608 }
michael@0 609 PR_Unlock(_pr_flock_lock);
michael@0 610
michael@0 611 return status;
michael@0 612 }
michael@0 613
michael@0 614 PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
michael@0 615 {
michael@0 616 PRStatus status = PR_SUCCESS;
michael@0 617
michael@0 618 #ifdef WINNT
michael@0 619 if (!fd->secret->md.io_model_committed) {
michael@0 620 PRInt32 rv;
michael@0 621 rv = _md_Associate((HANDLE)fd->secret->md.osfd);
michael@0 622 PR_ASSERT(0 != rv);
michael@0 623 fd->secret->md.io_model_committed = PR_TRUE;
michael@0 624 }
michael@0 625 #endif
michael@0 626
michael@0 627 PR_Lock(_pr_flock_lock);
michael@0 628 if (fd->secret->lockCount == 0) {
michael@0 629 status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
michael@0 630 PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0);
michael@0 631 if (status == PR_SUCCESS)
michael@0 632 fd->secret->lockCount = 1;
michael@0 633 } else {
michael@0 634 fd->secret->lockCount++;
michael@0 635 }
michael@0 636 PR_Unlock(_pr_flock_lock);
michael@0 637
michael@0 638 return status;
michael@0 639 }
michael@0 640
michael@0 641 PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
michael@0 642 {
michael@0 643 PRStatus rv = PR_SUCCESS;
michael@0 644
michael@0 645 PR_Lock(_pr_flock_lock);
michael@0 646 if (fd->secret->lockCount == 1) {
michael@0 647 rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
michael@0 648 if (rv == PR_SUCCESS)
michael@0 649 fd->secret->lockCount = 0;
michael@0 650 } else {
michael@0 651 fd->secret->lockCount--;
michael@0 652 }
michael@0 653 PR_Unlock(_pr_flock_lock);
michael@0 654
michael@0 655 return rv;
michael@0 656 }
michael@0 657
michael@0 658 PR_IMPLEMENT(PRStatus) PR_CreatePipe(
michael@0 659 PRFileDesc **readPipe,
michael@0 660 PRFileDesc **writePipe
michael@0 661 )
michael@0 662 {
michael@0 663 #if defined(WIN32) && !defined(WINCE)
michael@0 664 HANDLE readEnd, writeEnd;
michael@0 665 SECURITY_ATTRIBUTES pipeAttributes;
michael@0 666
michael@0 667 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 668
michael@0 669 ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
michael@0 670 pipeAttributes.nLength = sizeof(pipeAttributes);
michael@0 671 pipeAttributes.bInheritHandle = TRUE;
michael@0 672 if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) {
michael@0 673 PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
michael@0 674 return PR_FAILURE;
michael@0 675 }
michael@0 676 *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods);
michael@0 677 if (NULL == *readPipe) {
michael@0 678 CloseHandle(readEnd);
michael@0 679 CloseHandle(writeEnd);
michael@0 680 return PR_FAILURE;
michael@0 681 }
michael@0 682 *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods);
michael@0 683 if (NULL == *writePipe) {
michael@0 684 PR_Close(*readPipe);
michael@0 685 CloseHandle(writeEnd);
michael@0 686 return PR_FAILURE;
michael@0 687 }
michael@0 688 #ifdef WINNT
michael@0 689 (*readPipe)->secret->md.sync_file_io = PR_TRUE;
michael@0 690 (*writePipe)->secret->md.sync_file_io = PR_TRUE;
michael@0 691 #endif
michael@0 692 (*readPipe)->secret->inheritable = _PR_TRI_TRUE;
michael@0 693 (*writePipe)->secret->inheritable = _PR_TRI_TRUE;
michael@0 694 return PR_SUCCESS;
michael@0 695 #elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
michael@0 696 #ifdef XP_OS2
michael@0 697 HFILE pipefd[2];
michael@0 698 #else
michael@0 699 int pipefd[2];
michael@0 700 #endif
michael@0 701
michael@0 702 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 703
michael@0 704 #ifdef XP_OS2
michael@0 705 if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
michael@0 706 #else
michael@0 707 if (pipe(pipefd) == -1) {
michael@0 708 #endif
michael@0 709 /* XXX map pipe error */
michael@0 710 PR_SetError(PR_UNKNOWN_ERROR, errno);
michael@0 711 return PR_FAILURE;
michael@0 712 }
michael@0 713 *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods);
michael@0 714 if (NULL == *readPipe) {
michael@0 715 close(pipefd[0]);
michael@0 716 close(pipefd[1]);
michael@0 717 return PR_FAILURE;
michael@0 718 }
michael@0 719 *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods);
michael@0 720 if (NULL == *writePipe) {
michael@0 721 PR_Close(*readPipe);
michael@0 722 close(pipefd[1]);
michael@0 723 return PR_FAILURE;
michael@0 724 }
michael@0 725 #ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
michael@0 726 _PR_MD_MAKE_NONBLOCK(*readPipe);
michael@0 727 #endif
michael@0 728 _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
michael@0 729 #ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
michael@0 730 _PR_MD_MAKE_NONBLOCK(*writePipe);
michael@0 731 #endif
michael@0 732 _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
michael@0 733 return PR_SUCCESS;
michael@0 734 #else
michael@0 735 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 736 return PR_FAILURE;
michael@0 737 #endif
michael@0 738 }
michael@0 739
michael@0 740 #ifdef MOZ_UNICODE
michael@0 741 /* ================ UTF16 Interfaces ================================ */
michael@0 742 PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
michael@0 743 const PRUnichar *name, PRIntn flags, PRIntn mode)
michael@0 744 {
michael@0 745 PROsfd osfd;
michael@0 746 PRFileDesc *fd = 0;
michael@0 747 #if !defined(_PR_HAVE_O_APPEND)
michael@0 748 PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
michael@0 749 #endif
michael@0 750
michael@0 751 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 752
michael@0 753 /* Map pr open flags and mode to os specific flags */
michael@0 754 osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
michael@0 755 if (osfd != -1) {
michael@0 756 fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
michael@0 757 if (!fd) {
michael@0 758 (void) _PR_MD_CLOSE_FILE(osfd);
michael@0 759 } else {
michael@0 760 #if !defined(_PR_HAVE_O_APPEND)
michael@0 761 fd->secret->appendMode = appendMode;
michael@0 762 #endif
michael@0 763 _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
michael@0 764 }
michael@0 765 }
michael@0 766 return fd;
michael@0 767 }
michael@0 768
michael@0 769 PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
michael@0 770 {
michael@0 771 PRInt32 rv;
michael@0 772
michael@0 773 if (!_pr_initialized) _PR_ImplicitInitialization();
michael@0 774 rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
michael@0 775 if (rv < 0) {
michael@0 776 return PR_FAILURE;
michael@0 777 } else {
michael@0 778 return PR_SUCCESS;
michael@0 779 }
michael@0 780 }
michael@0 781
michael@0 782 /* ================ UTF16 Interfaces ================================ */
michael@0 783 #endif /* MOZ_UNICODE */

mercurial