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