nsprpub/pr/src/io/prfile.c

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

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

mercurial