nsprpub/pr/src/md/os2/os2io.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.

     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 /* OS2 IO module
     7  *
     8  * Assumes synchronous I/O.
     9  *
    10  */
    12 #include "primpl.h"
    13 #include "prio.h"
    14 #include <ctype.h>
    15 #include <string.h>
    16 #include <limits.h>
    17 #include <dirent.h>
    18 #include <fcntl.h>
    19 #include <io.h>
    21 struct _MDLock               _pr_ioq_lock;
    23 static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */
    25 typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction,
    26                             LONGLONG cbFile, ULONG ulAttribute,
    27                             ULONG fsOpenFlags, ULONG fsOpenMode,
    28                             PEAOP2 peaop2);
    30 typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock,
    31                                     PFILELOCKL pflLock, ULONG timeout,
    32                                     ULONG flags);
    34 typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method,
    35                                   PLONGLONG ibActual);
    37 DosOpenLType myDosOpenL;
    38 DosSetFileLocksLType myDosSetFileLocksL;
    39 DosSetFilePtrLType myDosSetFilePtrL;
    41 void
    42 _PR_MD_INIT_IO()
    43 {
    44     APIRET rc;
    45     HMODULE module;
    47     sock_init();
    49     rc = DosLoadModule(NULL, 0, "DOSCALL1", &module);
    50     if (rc != NO_ERROR)
    51     {
    52         return;
    53     }
    54     rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL);
    55     if (rc != NO_ERROR)
    56     {
    57         return;
    58     }
    59     rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL);
    60     if (rc != NO_ERROR)
    61     {
    62         return;
    63     }
    64     rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL);
    65     if (rc != NO_ERROR)
    66     {
    67         return;
    68     }
    69     isWSEB = PR_TRUE;
    70 }
    72 PRStatus
    73 _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    74 {
    75     PRInt32 rv;
    76     ULONG count;
    78     PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
    79         SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
    80     rv = DosWaitEventSem(thread->md.blocked_sema, msecs);
    81     DosResetEventSem(thread->md.blocked_sema, &count); 
    82     switch(rv) 
    83     {
    84         case NO_ERROR:
    85             return PR_SUCCESS;
    86             break;
    87         case ERROR_TIMEOUT:
    88             _PR_THREAD_LOCK(thread);
    89             if (thread->state == _PR_IO_WAIT) {
    90 			  ;
    91             } else {
    92                 if (thread->wait.cvar != NULL) {
    93                     thread->wait.cvar = NULL;
    94                     _PR_THREAD_UNLOCK(thread);
    95                 } else {
    96                     /* The CVAR was notified just as the timeout
    97                      * occurred.  This led to us being notified twice.
    98                      * call SemRequest() to clear the semaphore.
    99                      */
   100                     _PR_THREAD_UNLOCK(thread);
   101                     rv = DosWaitEventSem(thread->md.blocked_sema, 0);
   102                     DosResetEventSem(thread->md.blocked_sema, &count); 
   103                     PR_ASSERT(rv == NO_ERROR);
   104                 }
   105             }
   106             return PR_SUCCESS;
   107             break;
   108         default:
   109             break;
   110     }
   111     return PR_FAILURE;
   112 }
   113 PRStatus
   114 _PR_MD_WAKEUP_WAITER(PRThread *thread)
   115 {
   116     if ( _PR_IS_NATIVE_THREAD(thread) ) 
   117     {
   118         if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR)
   119             return PR_FAILURE;
   120         else
   121 			return PR_SUCCESS;
   122 	}
   123 }
   126 /* --- FILE IO ----------------------------------------------------------- */
   127 /*
   128  *  _PR_MD_OPEN() -- Open a file
   129  *
   130  *  returns: a fileHandle
   131  *
   132  *  The NSPR open flags (osflags) are translated into flags for OS/2
   133  *
   134  *  Mode seems to be passed in as a unix style file permissions argument
   135  *  as in 0666, in the case of opening the logFile. 
   136  *
   137  */
   138 PRInt32
   139 _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
   140 {
   141     HFILE file;
   142     PRInt32 access = OPEN_SHARE_DENYNONE;
   143     PRInt32 flags = 0L;
   144     APIRET rc = 0;
   145     PRUword actionTaken;
   147 #ifdef MOZ_OS2_HIGH_MEMORY
   148     /*
   149      * All the pointer arguments (&file, &actionTaken and name) have to be in
   150      * low memory for DosOpen to use them.
   151      * The following moves name to low memory.
   152      */ 
   153     if ((ULONG)name >= 0x20000000)
   154     {
   155         size_t len = strlen(name) + 1;
   156         char *copy = (char *)alloca(len);
   157         memcpy(copy, name, len);
   158         name = copy;
   159     }
   160 #endif
   162     if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH;
   164     if (osflags & PR_RDONLY)
   165         access |= OPEN_ACCESS_READONLY;
   166     else if (osflags & PR_WRONLY)
   167         access |= OPEN_ACCESS_WRITEONLY;
   168     else if(osflags & PR_RDWR)
   169         access |= OPEN_ACCESS_READWRITE;
   171     if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
   172     {
   173         flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
   174     }
   175     else if (osflags & PR_CREATE_FILE)
   176     {
   177         if (osflags & PR_TRUNCATE)
   178             flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
   179         else
   180             flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
   181     } 
   182     else
   183     {
   184         if (osflags & PR_TRUNCATE)
   185             flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
   186         else
   187             flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
   188     }
   190     do {
   191         if (isWSEB)
   192         {
   193                 rc = myDosOpenL((char*)name,
   194                      &file,            /* file handle if successful */
   195                      &actionTaken,     /* reason for failure        */
   196                      0,                /* initial size of new file  */
   197                      FILE_NORMAL,      /* file system attributes    */
   198                      flags,            /* Open flags                */
   199                      access,           /* Open mode and rights      */
   200                      0);               /* OS/2 Extended Attributes  */
   201         }
   202         else
   203         {
   204                 rc = DosOpen((char*)name,
   205                      &file,            /* file handle if successful */
   206                      &actionTaken,     /* reason for failure        */
   207                      0,                /* initial size of new file  */
   208                      FILE_NORMAL,      /* file system attributes    */
   209                      flags,            /* Open flags                */
   210                      access,           /* Open mode and rights      */
   211                      0);               /* OS/2 Extended Attributes  */
   212         };
   213         if (rc == ERROR_TOO_MANY_OPEN_FILES) {
   214             ULONG CurMaxFH = 0;
   215             LONG ReqCount = 20;
   216             APIRET rc2;
   217             rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
   218             if (rc2 != NO_ERROR) {
   219                 break;
   220             }
   221         }
   222     } while (rc == ERROR_TOO_MANY_OPEN_FILES);
   224     if (rc != NO_ERROR) {
   225         _PR_MD_MAP_OPEN_ERROR(rc);
   226         return -1; 
   227     }
   229     return (PRInt32)file;
   230 }
   232 PRInt32
   233 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
   234 {
   235     ULONG bytes;
   236     int rv;
   238     rv = DosRead((HFILE)fd->secret->md.osfd,
   239                  (PVOID)buf,
   240                  len,
   241                  &bytes);
   243     if (rv != NO_ERROR) 
   244     {
   245         /* ERROR_HANDLE_EOF can only be returned by async io */
   246         PR_ASSERT(rv != ERROR_HANDLE_EOF);
   247         if (rv == ERROR_BROKEN_PIPE)
   248             return 0;
   249 		else {
   250 			_PR_MD_MAP_READ_ERROR(rv);
   251         return -1;
   252     }
   253     }
   254     return (PRInt32)bytes;
   255 }
   257 PRInt32
   258 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
   259 {
   260     PRInt32 bytes;
   261     int rv; 
   263     rv = DosWrite((HFILE)fd->secret->md.osfd,
   264                   (PVOID)buf,
   265                   len,
   266                   (PULONG)&bytes);
   268     if (rv != NO_ERROR) 
   269     {
   270         _PR_MD_MAP_WRITE_ERROR(rv);
   271         return -1;
   272     }
   274     if (len != bytes) {
   275         rv = ERROR_DISK_FULL;
   276         _PR_MD_MAP_WRITE_ERROR(rv);
   277         return -1;
   278     }
   280     return bytes;
   281 } /* --- end _PR_MD_WRITE() --- */
   283 PRInt32
   284 _PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
   285 {
   286     PRInt32 rv;
   287     PRUword newLocation;
   289     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation);
   291 	if (rv != NO_ERROR) {
   292 		_PR_MD_MAP_LSEEK_ERROR(rv);
   293 		return -1;
   294 	} else
   295 		return newLocation;
   296 }
   298 PRInt64
   299 _PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
   300 {
   301 #ifdef NO_LONG_LONG
   302     PRInt64 result;
   303     PRInt32 rv, low = offset.lo, hi = offset.hi;
   304     PRUword newLocation;
   306     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation);
   307     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation);
   309   	if (rv != NO_ERROR) {
   310 		_PR_MD_MAP_LSEEK_ERROR(rv);
   311 		hi = newLocation = -1;
   312    }
   314     result.lo = newLocation;
   315     result.hi = hi;
   316 	return result;
   318 #else
   319     PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32);
   320     PRUint64 rv;
   321     PRUint32 newLocation, uhi;
   322     PRUint64 newLocationL;
   324     switch (whence)
   325       {
   326       case PR_SEEK_SET:
   327         where = FILE_BEGIN;
   328         break;
   329       case PR_SEEK_CUR:
   330         where = FILE_CURRENT;
   331         break;
   332       case PR_SEEK_END:
   333         where = FILE_END;
   334         break;
   335       default:
   336         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
   337         return -1;
   338     }
   339     if (isWSEB)
   340     {
   341         rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL);
   342     }
   343     else
   344     {
   345         rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation);
   346     }
   348     if (rc != NO_ERROR) {
   349       _PR_MD_MAP_LSEEK_ERROR(rc);
   350       return -1;
   351     }
   353     if (isWSEB)
   354     {
   355         return newLocationL;
   356     }
   358     uhi = (PRUint32)hi;
   359     PR_ASSERT((PRInt32)uhi >= 0);
   360     rv = uhi;
   361     PR_ASSERT((PRInt64)rv >= 0);
   362     rv = (rv << 32);
   363     PR_ASSERT((PRInt64)rv >= 0);
   364     rv += newLocation;
   365     PR_ASSERT((PRInt64)rv >= 0);
   366     return (PRInt64)rv;
   367 #endif
   368 }
   370 PRInt32
   371 _PR_MD_FSYNC(PRFileDesc *fd)
   372 {
   373     PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd);
   375     if (rc != NO_ERROR) {
   376    	if (rc != ERROR_ACCESS_DENIED) {	
   377    			_PR_MD_MAP_FSYNC_ERROR(rc);
   378    	    return -1;
   379    	}
   380     }
   381     return 0;
   382 }
   384 PRInt32
   385 _MD_CloseFile(PRInt32 osfd)
   386 {
   387     PRInt32 rv;
   389     rv = DosClose((HFILE)osfd);
   390  	if (rv != NO_ERROR)
   391 		_PR_MD_MAP_CLOSE_ERROR(rv);
   392     return rv;
   393 }
   396 /* --- DIR IO ------------------------------------------------------------ */
   397 #define GetFileFromDIR(d)       (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName)
   398 #define GetFileAttr(d)          (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile)
   400 void FlipSlashes(char *cp, int len)
   401 {
   402     while (--len >= 0) {
   403     if (cp[0] == '/') {
   404         cp[0] = PR_DIRECTORY_SEPARATOR;
   405     }
   406     cp++;
   407     }
   408 }
   410 /*
   411 **
   412 ** Local implementations of standard Unix RTL functions which are not provided
   413 ** by the VAC RTL.
   414 **
   415 */
   417 PRInt32
   418 _PR_MD_CLOSE_DIR(_MDDir *d)
   419 {
   420    PRInt32 rc;
   422     if ( d ) {
   423       rc = DosFindClose(d->d_hdl);
   424       if(rc == NO_ERROR){
   425         d->magic = (PRUint32)-1;
   426         return PR_SUCCESS;
   427 		} else {
   428 			_PR_MD_MAP_CLOSEDIR_ERROR(rc);
   429         	return PR_FAILURE;
   430 		}
   431     }
   432     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
   433     return PR_FAILURE;
   434 }
   437 PRStatus
   438 _PR_MD_OPEN_DIR(_MDDir *d, const char *name)
   439 {
   440     char filename[ CCHMAXPATH ];
   441     PRUword numEntries, rc;
   443     numEntries = 1;
   445     PR_snprintf(filename, CCHMAXPATH, "%s%s%s",
   446                 name, PR_DIRECTORY_SEPARATOR_STR, "*.*");
   447     FlipSlashes( filename, strlen(filename) );
   449     d->d_hdl = HDIR_CREATE;
   451     if (isWSEB)
   452     {
   453         rc = DosFindFirst( filename,
   454                            &d->d_hdl,
   455                            FILE_DIRECTORY | FILE_HIDDEN,
   456                            &(d->d_entry.large),
   457                            sizeof(d->d_entry.large),
   458                            &numEntries,
   459                            FIL_STANDARDL);
   460     }
   461     else
   462     {
   463         rc = DosFindFirst( filename,
   464                            &d->d_hdl,
   465                            FILE_DIRECTORY | FILE_HIDDEN,
   466                            &(d->d_entry.small),
   467                            sizeof(d->d_entry.small),
   468                            &numEntries,
   469                            FIL_STANDARD);
   470     }
   471     if ( rc != NO_ERROR ) {
   472 		_PR_MD_MAP_OPENDIR_ERROR(rc);
   473         return PR_FAILURE;
   474     }
   475     d->firstEntry = PR_TRUE;
   476     d->magic = _MD_MAGIC_DIR;
   477     return PR_SUCCESS;
   478 }
   480 char *
   481 _PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
   482 {
   483     PRUword numFiles = 1;
   484     BOOL rv;
   485     char *fileName;
   486     USHORT fileAttr;
   488     if ( d ) {
   489        while (1) {
   490            if (d->firstEntry) {
   491                d->firstEntry = PR_FALSE;
   492                rv = NO_ERROR;
   493            } else {
   494                rv = DosFindNext(d->d_hdl,
   495                                 &(d->d_entry),
   496                                 sizeof(d->d_entry),
   497                                 &numFiles);
   498            }
   499            if (rv != NO_ERROR) {
   500                break;
   501            }
   502            fileName = GetFileFromDIR(d);
   503            fileAttr = GetFileAttr(d);
   504            if ( (flags & PR_SKIP_DOT) &&
   505                 (fileName[0] == '.') && (fileName[1] == '\0'))
   506                 continue;
   507            if ( (flags & PR_SKIP_DOT_DOT) &&
   508                 (fileName[0] == '.') && (fileName[1] == '.') &&
   509                 (fileName[2] == '\0'))
   510                 continue;
   511 			/*
   512 			 * XXX
   513 			 * Is this the correct definition of a hidden file on OS/2?
   514 			 */
   515            if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN))
   516                 return fileName;
   517            else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN))
   518                 continue;
   519            return fileName;
   520         }
   521         PR_ASSERT(NO_ERROR != rv);
   522 			_PR_MD_MAP_READDIR_ERROR(rv);
   523         return NULL;
   524 		}
   525     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
   526     return NULL;
   527 }
   529 PRInt32
   530 _PR_MD_DELETE(const char *name)
   531 {
   532     PRInt32 rc = DosDelete((char*)name);
   533     if(rc == NO_ERROR) {
   534         return 0;
   535     } else {
   536 		_PR_MD_MAP_DELETE_ERROR(rc);
   537         return -1;
   538     }
   539 }
   541 PRInt32
   542 _PR_MD_STAT(const char *fn, struct stat *info)
   543 {
   544     PRInt32 rv;
   545     char filename[CCHMAXPATH];
   547     PR_snprintf(filename, CCHMAXPATH, "%s", fn);
   548     FlipSlashes(filename, strlen(filename));
   550     rv = _stat((char*)filename, info);
   551     if (-1 == rv) {
   552         /*
   553          * Check for MSVC runtime library _stat() bug.
   554          * (It's really a bug in FindFirstFile().)
   555          * If a pathname ends in a backslash or slash,
   556          * e.g., c:\temp\ or c:/temp/, _stat() will fail.
   557          * Note: a pathname ending in a slash (e.g., c:/temp/)
   558          * can be handled by _stat() on NT but not on Win95.
   559          *
   560          * We remove the backslash or slash at the end and
   561          * try again.  
   562          *
   563          * Not sure if this happens on OS/2 or not,
   564          * but it doesn't hurt to be careful.
   565          */
   567         int len = strlen(fn);
   568         if (len > 0 && len <= _MAX_PATH
   569                 && (fn[len - 1] == '\\' || fn[len - 1] == '/')) {
   570             char newfn[_MAX_PATH + 1];
   572             strcpy(newfn, fn);
   573             newfn[len - 1] = '\0';
   574             rv = _stat(newfn, info);
   575         }
   576     }
   578     if (-1 == rv) {
   579         _PR_MD_MAP_STAT_ERROR(errno);
   580     }
   581     return rv;
   582 }
   584 PRInt32
   585 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
   586 {
   587     struct stat sb;
   588     PRInt32 rv;
   589     PRInt64 s, s2us;
   591     if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) {
   592         if (info) {
   593             if (S_IFREG & sb.st_mode)
   594                 info->type = PR_FILE_FILE ;
   595             else if (S_IFDIR & sb.st_mode)
   596                 info->type = PR_FILE_DIRECTORY;
   597             else
   598                 info->type = PR_FILE_OTHER;
   599             info->size = sb.st_size;
   600             LL_I2L(s2us, PR_USEC_PER_SEC);
   601             LL_I2L(s, sb.st_mtime);
   602             LL_MUL(s, s, s2us);
   603             info->modifyTime = s;
   604             LL_I2L(s, sb.st_ctime);
   605             LL_MUL(s, s, s2us);
   606             info->creationTime = s;
   607         }
   608     }
   609     return rv;
   610 }
   612 PRInt32
   613 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
   614 {
   615     PRFileInfo info32;
   616     PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
   617     if (rv != 0)
   618     {
   619         return rv;
   620     }
   621     info->type = info32.type;
   622     LL_UI2L(info->size,info32.size);
   623     info->modifyTime = info32.modifyTime;
   624     info->creationTime = info32.creationTime;
   626     if (isWSEB)
   627     {
   628         APIRET rc ;
   629         FILESTATUS3L fstatus;
   631         rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus));
   633         if (NO_ERROR != rc)
   634         {
   635             _PR_MD_MAP_OPEN_ERROR(rc);
   636             return -1;
   637         }
   639         if (! (fstatus.attrFile & FILE_DIRECTORY))
   640         {
   641             info->size = fstatus.cbFile;
   642         }
   643     }
   645     return rv;
   646 }
   648 PRInt32
   649 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
   650 {
   651    /* For once, the VAC compiler/library did a nice thing.
   652     * The file handle used by the C runtime is the same one
   653     * returned by the OS when you call DosOpen().  This means
   654     * that you can take an OS HFILE and use it with C file
   655     * functions.  The only caveat is that you have to call
   656     * _setmode() first to initialize some junk.  This is
   657     * immensely useful because I did not have a clue how to
   658     * implement this function otherwise.  The windows folks
   659     * took the source from the Microsoft C library source, but
   660     * IBM wasn't kind enough to ship the source with VAC.
   661     * On second thought, the needed function could probably
   662     * be gotten from the OS/2 GNU library source, but the
   663     * point is now moot.
   664     */
   665    struct stat hinfo;
   666     PRInt64 s, s2us;
   668     _setmode(fd->secret->md.osfd, O_BINARY);
   669     if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) {
   670 		_PR_MD_MAP_FSTAT_ERROR(errno);
   671         return -1;
   672 	}
   674     if (hinfo.st_mode & S_IFDIR)
   675         info->type = PR_FILE_DIRECTORY;
   676     else
   677         info->type = PR_FILE_FILE;
   679     info->size = hinfo.st_size;
   680     LL_I2L(s2us, PR_USEC_PER_SEC);
   681     LL_I2L(s, hinfo.st_mtime);
   682     LL_MUL(s, s, s2us);
   683     info->modifyTime = s;
   684     LL_I2L(s, hinfo.st_ctime);
   685     LL_MUL(s, s, s2us);
   686     info->creationTime = s;
   688     return 0;
   689 }
   691 PRInt32
   692 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
   693 {
   694     PRFileInfo info32;
   695     PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
   696     if (0 == rv)
   697     {
   698        info->type = info32.type;
   699        LL_UI2L(info->size,info32.size);
   701        info->modifyTime = info32.modifyTime;
   702        info->creationTime = info32.creationTime;
   703     }
   705     if (isWSEB)
   706     {
   707         APIRET rc ;
   708         FILESTATUS3L fstatus;
   710         rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus));
   712         if (NO_ERROR != rc)
   713         {
   714             _PR_MD_MAP_OPEN_ERROR(rc);
   715             return -1;
   716         }
   718         if (! (fstatus.attrFile & FILE_DIRECTORY))
   719         {
   720             info->size = fstatus.cbFile;
   721         }
   722     }
   724     return rv;
   725 }
   728 PRInt32
   729 _PR_MD_RENAME(const char *from, const char *to)
   730 {
   731    PRInt32 rc;
   732     /* Does this work with dot-relative pathnames? */
   733     if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) {
   734         return 0;
   735     } else {
   736 		_PR_MD_MAP_RENAME_ERROR(rc);
   737         return -1;
   738     }
   739 }
   741 PRInt32
   742 _PR_MD_ACCESS(const char *name, PRAccessHow how)
   743 {
   744   PRInt32 rv;
   745     switch (how) {
   746       case PR_ACCESS_WRITE_OK:
   747         rv = access(name, 02);
   748 		break;
   749       case PR_ACCESS_READ_OK:
   750         rv = access(name, 04);
   751 		break;
   752       case PR_ACCESS_EXISTS:
   753         return access(name, 00);
   754 	  	break;
   755       default:
   756 		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
   757 		return -1;
   758     }
   759 	if (rv < 0)
   760 		_PR_MD_MAP_ACCESS_ERROR(errno);
   761     return rv;
   762 }
   764 PRInt32
   765 _PR_MD_MKDIR(const char *name, PRIntn mode)
   766 {
   767    PRInt32 rc;
   768     /* XXXMB - how to translate the "mode"??? */
   769     if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
   770         return 0;
   771     } else {
   772 		_PR_MD_MAP_MKDIR_ERROR(rc);
   773         return -1;
   774     }
   775 }
   777 PRInt32
   778 _PR_MD_RMDIR(const char *name)
   779 {
   780    PRInt32 rc;
   781     if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) {
   782         return 0;
   783     } else {
   784 		_PR_MD_MAP_RMDIR_ERROR(rc);
   785         return -1;
   786     }
   787 }
   789 PRStatus
   790 _PR_MD_LOCKFILE(PRInt32 f)
   791 {
   792     PRInt32   rv;
   793     FILELOCK lock, unlock;
   794     FILELOCKL lockL, unlockL;
   796     lock.lOffset = 0;
   797     lockL.lOffset = 0;
   798     lock.lRange = 0xffffffff;
   799     lockL.lRange =  0xffffffffffffffff;
   800     unlock.lOffset = 0;
   801     unlock.lRange = 0;
   802     unlockL.lOffset = 0;
   803     unlockL.lRange = 0;
   805     /*
   806      * loop trying to DosSetFileLocks(),
   807      * pause for a few miliseconds when can't get the lock
   808      * and try again
   809      */
   810     for( rv = FALSE; rv == FALSE; /* do nothing */ )
   811     {
   812         if (isWSEB)
   813         {
   814 	    rv = myDosSetFileLocksL( (HFILE) f,
   815 			                    &unlockL, &lockL,
   816 			                    0, 0);
   817         }
   818         else
   819         {
   820 	    rv = DosSetFileLocks( (HFILE) f,
   821 			                    &unlock, &lock,
   822 			                    0, 0);
   823         }
   824 		if ( rv != NO_ERROR )
   825         {
   826             DosSleep( 50 );  /* Sleep() a few milisecs and try again. */
   827         }            
   828     } /* end for() */
   829     return PR_SUCCESS;
   830 } /* end _PR_MD_LOCKFILE() */
   832 PRStatus
   833 _PR_MD_TLOCKFILE(PRInt32 f)
   834 {
   835     return _PR_MD_LOCKFILE(f);
   836 } /* end _PR_MD_TLOCKFILE() */
   839 PRStatus
   840 _PR_MD_UNLOCKFILE(PRInt32 f)
   841 {
   842     PRInt32   rv;
   843     FILELOCK lock, unlock;
   844     FILELOCKL lockL, unlockL;
   846     lock.lOffset = 0;
   847     lockL.lOffset = 0;
   848     lock.lRange = 0;
   849     lockL.lRange = 0;
   850     unlock.lOffset = 0;
   851     unlockL.lOffset = 0;
   852     unlock.lRange = 0xffffffff;
   853     unlockL.lRange = 0xffffffffffffffff;
   855     if (isWSEB)
   856     {
   857         rv = myDosSetFileLocksL( (HFILE) f,
   858                                         &unlockL, &lockL,
   859                                         0, 0);
   860     }
   861     else
   862     {
   863         rv = DosSetFileLocks( (HFILE) f,
   864                                     &unlock, &lock,
   865                                     0, 0);
   866     }
   868     if ( rv != NO_ERROR )
   869     {
   870         return PR_SUCCESS;
   871     }
   872     else
   873     {
   874         return PR_FAILURE;
   875     }
   876 } /* end _PR_MD_UNLOCKFILE() */
   878 PRStatus
   879 _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
   880 {
   881     APIRET rc = 0;
   882     ULONG flags;
   883     switch (fd->methods->file_type)
   884     {
   885         case PR_DESC_PIPE:
   886         case PR_DESC_FILE:
   887             rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
   888             if (rc != NO_ERROR) {
   889                 PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
   890                 return PR_FAILURE;
   891             }
   893             if (inheritable)
   894               flags &= ~OPEN_FLAGS_NOINHERIT;
   895             else
   896               flags |= OPEN_FLAGS_NOINHERIT;
   898             /* Mask off flags DosSetFHState don't want. */
   899             flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
   900             rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
   901             if (rc != NO_ERROR) {
   902                 PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
   903                 return PR_FAILURE;
   904             }
   905             break;
   907         case PR_DESC_LAYERED:
   908             /* what to do here? */
   909             PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
   910             return PR_FAILURE;
   912         case PR_DESC_SOCKET_TCP:
   913         case PR_DESC_SOCKET_UDP:
   914             /* These are global on OS/2. */
   915             break;
   916     }
   918     return PR_SUCCESS;
   919 }
   921 void
   922 _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
   923 {
   924     /* XXX this function needs to be implemented */
   925     fd->secret->inheritable = _PR_TRI_UNKNOWN;
   926 }
   928 void
   929 _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
   930 {
   931     /* XXX this function needs to be reviewed */
   932     ULONG flags;
   934     PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
   935     if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) {
   936         if (flags & OPEN_FLAGS_NOINHERIT) {
   937             fd->secret->inheritable = _PR_TRI_FALSE;
   938         } else {
   939             fd->secret->inheritable = _PR_TRI_TRUE;
   940         }
   941     }
   942 }

mercurial