Backed out 2 changesets (bug 1943998) for causing wd failures @ phases.py CLOSED...
[gecko.git] / nsprpub / pr / src / io / prfile.c
blob1e1b0f037926aae8f5a228befd55ca54d62356c9
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/. */
6 #include "primpl.h"
8 #include <string.h>
9 #include <fcntl.h>
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 */
22 extern PRLock* _pr_flock_lock;
23 extern PRCondVar* _pr_flock_cv;
25 static PRInt32 PR_CALLBACK FileRead(PRFileDesc* fd, void* buf, PRInt32 amount) {
26 PRInt32 rv = 0;
27 PRThread* me = _PR_MD_CURRENT_THREAD();
29 if (_PR_PENDING_INTERRUPT(me)) {
30 me->flags &= ~_PR_INTERRUPT;
31 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
32 rv = -1;
34 if (_PR_IO_PENDING(me)) {
35 PR_SetError(PR_IO_PENDING_ERROR, 0);
36 rv = -1;
38 if (rv == -1) {
39 return rv;
42 rv = _PR_MD_READ(fd, buf, amount);
43 if (rv < 0) {
44 PR_ASSERT(rv == -1);
46 PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
47 return rv;
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();
56 if (_PR_PENDING_INTERRUPT(me)) {
57 me->flags &= ~_PR_INTERRUPT;
58 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
59 rv = -1;
61 if (_PR_IO_PENDING(me)) {
62 PR_SetError(PR_IO_PENDING_ERROR, 0);
63 rv = -1;
65 if (rv != 0) {
66 return rv;
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;
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;
83 count += temp;
84 if (fd->secret->nonblocking) {
85 break;
87 buf = (const void*)((const char*)buf + temp);
88 amount -= temp;
90 PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
91 return count;
94 static PROffset32 PR_CALLBACK FileSeek(PRFileDesc* fd, PROffset32 offset,
95 PRSeekWhence whence) {
96 PROffset32 result;
98 result = _PR_MD_LSEEK(fd, offset, whence);
99 return result;
102 static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc* fd, PROffset64 offset,
103 PRSeekWhence whence) {
104 PROffset64 result;
106 result = _PR_MD_LSEEK64(fd, offset, whence);
107 return result;
110 static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc* fd) {
111 PRInt32 result, cur, end;
113 cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
115 if (cur >= 0) {
116 end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
119 if ((cur < 0) || (end < 0)) {
120 return -1;
123 result = end - cur;
124 _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
126 return result;
129 static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc* fd) {
130 PRInt64 result, cur, end;
131 PRInt64 minus_one;
133 LL_I2L(minus_one, -1);
134 cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
136 if (LL_GE_ZERO(cur)) {
137 end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
140 if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) {
141 return minus_one;
144 LL_SUB(result, end, cur);
145 (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
147 return result;
150 static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc* fd) {
151 PRInt32 rv;
152 rv = _PR_MD_PIPEAVAILABLE(fd);
153 return rv;
156 static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc* fd) {
157 PRInt64 rv;
158 LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
159 return rv;
162 static PRStatus PR_CALLBACK PipeSync(PRFileDesc* fd) { return PR_SUCCESS; }
164 static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc* fd, PRFileInfo* info) {
165 PRInt32 rv;
167 rv = _PR_MD_GETOPENFILEINFO(fd, info);
168 if (rv < 0) {
169 return PR_FAILURE;
170 } else {
171 return PR_SUCCESS;
175 static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc* fd, PRFileInfo64* info) {
176 /* $$$$ NOT YET IMPLEMENTED */
177 PRInt32 rv;
179 rv = _PR_MD_GETOPENFILEINFO64(fd, info);
180 if (rv < 0) {
181 return PR_FAILURE;
182 } else {
183 return PR_SUCCESS;
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;
193 return PR_SUCCESS;
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;
204 if (fd->secret->state == _PR_FILEDESC_OPEN) {
205 if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) {
206 return PR_FAILURE;
208 fd->secret->state = _PR_FILEDESC_CLOSED;
210 PR_FreeFileDesc(fd);
211 return PR_SUCCESS;
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 */
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};
257 PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) {
258 return &_pr_fileMethods;
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};
298 PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) {
299 return &_pr_pipeMethods;
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
309 if (!_pr_initialized) {
310 _PR_ImplicitInitialization();
313 /* Map pr open flags and mode to os specific flags */
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);
327 return fd;
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
338 if (!_pr_initialized) {
339 _PR_ImplicitInitialization();
342 /* Map pr open flags and mode to os specific flags */
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);
356 return fd;
359 PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) {
360 #if defined(XP_UNIX) && !defined(AIX) && !defined(QNX)
361 struct rlimit rlim;
363 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
364 /* XXX need to call PR_SetError() */
365 return -1;
368 return rlim.rlim_max;
369 #elif defined(AIX) || defined(QNX)
370 return sysconf(_SC_OPEN_MAX);
371 #elif defined(WIN32)
373 * There is a systemwide limit of 65536 user handles.
375 return 16384;
376 #else
377 write me;
378 #endif
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();
386 if (tableMax < 0) {
387 return -1;
390 if (tableMax > FD_SETSIZE) {
391 tableMax = FD_SETSIZE;
394 rlim.rlim_max = tableMax;
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;
403 if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
404 /* XXX need to call PR_SetError() */
405 return -1;
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
417 PR_IMPLEMENT(PRStatus) PR_Delete(const char* name) {
418 PRInt32 rv;
420 rv = _PR_MD_DELETE(name);
421 if (rv < 0) {
422 return PR_FAILURE;
423 } else {
424 return PR_SUCCESS;
428 PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char* fn, PRFileInfo* info) {
429 PRInt32 rv;
431 rv = _PR_MD_GETFILEINFO(fn, info);
432 if (rv < 0) {
433 return PR_FAILURE;
434 } else {
435 return PR_SUCCESS;
439 PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char* fn, PRFileInfo64* info) {
440 PRInt32 rv;
442 if (!_pr_initialized) {
443 _PR_ImplicitInitialization();
445 rv = _PR_MD_GETFILEINFO64(fn, info);
446 if (rv < 0) {
447 return PR_FAILURE;
448 } else {
449 return PR_SUCCESS;
453 PR_IMPLEMENT(PRStatus) PR_Rename(const char* from, const char* to) {
454 PRInt32 rv;
456 rv = _PR_MD_RENAME(from, to);
457 if (rv < 0) {
458 return PR_FAILURE;
459 } else {
460 return PR_SUCCESS;
464 PR_IMPLEMENT(PRStatus) PR_Access(const char* name, PRAccessHow how) {
465 PRInt32 rv;
467 rv = _PR_MD_ACCESS(name, how);
468 if (rv < 0) {
469 return PR_FAILURE;
470 } else {
471 return PR_SUCCESS;
476 ** Import an existing OS file to NSPR
478 PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd) {
479 PRFileDesc* fd = NULL;
481 if (!_pr_initialized) {
482 _PR_ImplicitInitialization();
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);
492 return fd;
496 ** Import an existing OS pipe to NSPR
498 PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd) {
499 PRFileDesc* fd = NULL;
501 if (!_pr_initialized) {
502 _PR_ImplicitInitialization();
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
515 return fd;
518 #ifndef NO_NSPR_10_SUPPORT
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.
526 * If we need this function in nspr 2.0, it should be changed to
527 * return PRStatus, as follows:
529 * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf)
531 * PRInt32 rv;
533 * rv = _PR_MD_STAT(name, buf);
534 * if (rv < 0)
535 * return PR_FAILURE;
536 * else
537 * return PR_SUCCESS;
540 * -- wtc, 2/14/97.
542 PR_IMPLEMENT(PRInt32) PR_Stat(const char* name, struct stat* buf) {
543 PRInt32 rv;
545 rv = _PR_MD_STAT(name, buf);
546 return rv;
549 #endif /* ! NO_NSPR_10_SUPPORT */
551 PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc* fd) {
552 PRStatus status = PR_SUCCESS;
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;
561 #endif
563 PR_Lock(_pr_flock_lock);
564 while (fd->secret->lockCount == -1) {
565 PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
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++;
577 PR_Unlock(_pr_flock_lock);
579 return status;
582 PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc* fd) {
583 PRStatus status = PR_SUCCESS;
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;
592 #endif
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;
601 } else {
602 fd->secret->lockCount++;
604 PR_Unlock(_pr_flock_lock);
606 return status;
609 PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc* fd) {
610 PRStatus rv = PR_SUCCESS;
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;
618 } else {
619 fd->secret->lockCount--;
621 PR_Unlock(_pr_flock_lock);
623 return rv;
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;
632 if (!_pr_initialized) {
633 _PR_ImplicitInitialization();
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;
643 *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods);
644 if (NULL == *readPipe) {
645 CloseHandle(readEnd);
646 CloseHandle(writeEnd);
647 return PR_FAILURE;
649 *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods);
650 if (NULL == *writePipe) {
651 PR_Close(*readPipe);
652 CloseHandle(writeEnd);
653 return PR_FAILURE;
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];
665 if (!_pr_initialized) {
666 _PR_ImplicitInitialization();
669 if (pipe(pipefd) == -1) {
670 /* XXX map pipe error */
671 PR_SetError(PR_UNKNOWN_ERROR, errno);
672 return PR_FAILURE;
674 *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods);
675 if (NULL == *readPipe) {
676 close(pipefd[0]);
677 close(pipefd[1]);
678 return PR_FAILURE;
680 *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods);
681 if (NULL == *writePipe) {
682 PR_Close(*readPipe);
683 close(pipefd[1]);
684 return PR_FAILURE;
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
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
707 if (!_pr_initialized) {
708 _PR_ImplicitInitialization();
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);
724 return fd;
727 PR_IMPLEMENT(PRStatus)
728 PR_GetFileInfo64UTF16(const PRUnichar* fn, PRFileInfo64* info) {
729 PRInt32 rv;
731 if (!_pr_initialized) {
732 _PR_ImplicitInitialization();
734 rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
735 if (rv < 0) {
736 return PR_FAILURE;
737 } else {
738 return PR_SUCCESS;
742 /* ================ UTF16 Interfaces ================================ */
743 #endif /* MOZ_UNICODE */