mirror of https://github.com/MariaDB/server
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							394 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							394 lines
						
					
					
						
							12 KiB
						
					
					
				| /* Copyright (C) Yuri Dario & 2000 MySQL AB | |
|    All the above parties has a full, independent copyright to | |
|    the following code, including the right to use the code in | |
|    any manner without any demands from the other parties. | |
|  | |
|    This library is free software; you can redistribute it and/or | |
|    modify it under the terms of the GNU Library General Public | |
|    License as published by the Free Software Foundation; version 2 | |
|    of the License. | |
|  | |
|    This library is distributed in the hope that it will be useful, | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | |
|    Library General Public License for more details. | |
|  | |
|    You should have received a copy of the GNU Library General Public | |
|    License along with this library; if not, write to the Free | |
|    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
|    MA 02111-1307, USA */ | |
| 
 | |
| void	    _OS2errno( APIRET rc); | |
| longlong    _lseek64( int fd, longlong offset, int seektype); | |
| int	    _lock64( int fd, int locktype, my_off_t start, | |
| 		     my_off_t length, myf MyFlags); | |
| int	    _sopen64( const char *name, int oflag, int shflag, int mask); | |
| 
 | |
| /* | |
|   This class is used to define a global c++ variable, that | |
|   is initialized before main() gets called. | |
| */ | |
| 
 | |
| class File64bit | |
| { | |
|    public: | |
|       File64bit();  /* default constructor */ | |
| } initFile64bit; | |
| 
 | |
| static	APIRET (* APIENTRY _DosOpenL)(PCSZ  pszFileName, | |
| 			    PHFILE phf, | |
| 			    PULONG pulAction, | |
| 			    LONGLONG cbFile, | |
| 			    ULONG ulAttribute, | |
| 			    ULONG fsOpenFlags, | |
| 			    ULONG fsOpenMode, | |
| 			    PEAOP2 peaop2); | |
| static	APIRET (* APIENTRY _DosSetFilePtrL)(HFILE hFile, | |
| 				   LONGLONG ib, | |
| 				   ULONG method, | |
| 				   PLONGLONG ibActual); | |
| static	APIRET (* APIENTRY _DosSetFileLocksL)(HFILE hFile, | |
| 				    PFILELOCKL pflUnlock, | |
| 				    PFILELOCKL pflLock, | |
| 				    ULONG timeout, | |
| 				    ULONG flags); | |
| 
 | |
| #define  EIO	  EINVAL | |
| #define  ESPIPE   EBADSEEK | |
|  | |
| 
 | |
| static unsigned char const errno_tab[] = | |
| { | |
|   0	, EINVAL, ENOENT, ENOENT, EMFILE,  /* 0..4 */ | |
|   EACCES, EBADF,  EIO,	  ENOMEM, EIO,	   /* 5..9 */ | |
|   EINVAL, ENOEXEC,EINVAL, EINVAL, EINVAL,  /* 10..14 */ | |
|   ENOENT, EBUSY,  EXDEV,  ENOENT, EROFS,   /* 15..19 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 20..24 */ | |
|   EIO,	  EIO,	  EIO,	  ENOSPC, EIO,	   /* 25..29 */ | |
|   EIO,	  EIO,	  EACCES, EACCES, EIO,	   /* 30..34 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  ENOSPC,  /* 35..39 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 40..44 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 45..49 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EBUSY,   /* 50..54 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 55..59 */ | |
|   EIO,	  ENOSPC, ENOSPC, EIO,	  EIO,	   /* 60..64 */ | |
|   EACCES, EIO,	  EIO,	  EIO,	  EIO,	   /* 65..69 */ | |
|   EIO,	  EIO,	  EIO,	  EROFS,  EIO,	   /* 70..74 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 75..79 */ | |
|   EEXIST, EIO,	  ENOENT, EIO,	  EIO,	   /* 80..84 */ | |
|   EIO,	  EIO,	  EINVAL, EIO,	  EAGAIN,  /* 85..89 */ | |
|   EIO,	  EIO,	  EIO,	  EIO,	  EIO,	   /* 90..94 */ | |
|   EINTR,  EIO,	  EIO,	  EIO,	  EACCES,  /* 95..99 */ | |
|   ENOMEM, EINVAL, EINVAL, ENOMEM, EINVAL,  /* 100..104 */ | |
|   EINVAL, ENOMEM, EIO,	  EACCES, EPIPE,   /* 105..109 */ | |
|   ENOENT, E2BIG,  ENOSPC, ENOMEM, EBADF,   /* 110..114 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 115..119 */ | |
|   EINVAL, EINVAL, EINVAL, ENOENT, EINVAL,  /* 120..124 */ | |
|   ENOENT, ENOENT, ENOENT, ECHILD, ECHILD,  /* 125..129 */ | |
|   EACCES, EINVAL, ESPIPE, EINVAL, EINVAL,  /* 130..134 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 135..139 */ | |
|   EINVAL, EINVAL, EBUSY,  EINVAL, EINVAL,  /* 140..144 */ | |
|   EINVAL, EINVAL, EINVAL, EBUSY,  EINVAL,  /* 145..149 */ | |
|   EINVAL, EINVAL, ENOMEM, EINVAL, EINVAL,  /* 150..154 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 155..159 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EAGAIN,  /* 160..164 */ | |
|   EINVAL, EINVAL, EACCES, EINVAL, EINVAL,  /* 165..169 */ | |
|   EBUSY,  EINVAL, EINVAL, EINVAL, EINVAL,  /* 170..174 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 175..179 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, ECHILD,  /* 180..184 */ | |
|   EINVAL, EINVAL, ENOENT, EINVAL, EINVAL,  /* 185..189 */ | |
|   ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC, /* 190..194 */ | |
|   ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC, /* 195..199 */ | |
|   ENOEXEC,ENOEXEC,ENOEXEC,ENOENT, EINVAL,  /* 200..204 */ | |
|   EINVAL, ENAMETOOLONG, EINVAL, EINVAL, EINVAL,  /* 205..209 */ | |
|   EINVAL, EINVAL, EACCES, ENOEXEC,ENOEXEC, /* 210..214 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 215..219 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 220..224 */ | |
|   EINVAL, EINVAL, EINVAL, ECHILD, EINVAL,  /* 225..229 */ | |
|   EINVAL, EBUSY,  EAGAIN, ENOTCONN, EINVAL, /* 230..234 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 235..239 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 240..244 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 245..249 */ | |
|   EACCES, EACCES, EINVAL, ENOENT, EINVAL,  /* 250..254 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 255..259 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 260..264 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 265..269 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 270..274 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 275..279 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EEXIST,  /* 280..284 */ | |
|   EEXIST, EINVAL, EINVAL, EINVAL, EINVAL,  /* 285..289 */ | |
|   ENOMEM, EMFILE, EINVAL, EINVAL, EINVAL,  /* 290..294 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EINVAL,  /* 295..299 */ | |
|   EINVAL, EBUSY,  EINVAL, ESRCH,  EINVAL,  /* 300..304 */ | |
|   ESRCH,  EINVAL, EINVAL, EINVAL, ESRCH,   /* 305..309 */ | |
|   EINVAL, ENOMEM, EINVAL, EINVAL, EINVAL,  /* 310..314 */ | |
|   EINVAL, E2BIG,  ENOENT, EIO,	  EIO,	   /* 315..319 */ | |
|   EINVAL, EINVAL, EINVAL, EINVAL, EAGAIN,  /* 320..324 */ | |
|   EINVAL, EINVAL, EINVAL, EIO,	  ENOENT,  /* 325..329 */ | |
|   EACCES, EACCES, EACCES, ENOENT, ENOMEM   /* 330..334 */ | |
| }; | |
| 
 | |
| /* | |
|  * Initialize 64bit file access: dynamic load of WSeB API | |
| */ | |
| 	    File64bit :: File64bit() | |
| { | |
|    HMODULE hDoscalls; | |
| 
 | |
|    if (DosQueryModuleHandle("DOSCALLS", &hDoscalls) != NO_ERROR) | |
|       return; | |
| 
 | |
|    if (DosQueryProcAddr(hDoscalls, 981, NULL, (PFN *)&_DosOpenL) != NO_ERROR) | |
|       return; | |
| 
 | |
|    if (DosQueryProcAddr(hDoscalls, 988, NULL, (PFN *)&_DosSetFilePtrL) != NO_ERROR) { | |
|       _DosOpenL = NULL; | |
|       return; | |
|    } | |
| 
 | |
|    if (DosQueryProcAddr(hDoscalls, 986, NULL, (PFN *)&_DosSetFileLocksL) != NO_ERROR) { | |
|       _DosOpenL = NULL; | |
|       _DosSetFilePtrL = NULL; | |
|       return; | |
|    } | |
|    /* notify success */ | |
| #ifdef MYSQL_SERVER | |
|    printf( "WSeB 64bit file API loaded.\n"); | |
| #endif | |
| } | |
| 
 | |
| void	    _OS2errno( APIRET rc) | |
| { | |
|   if (rc >= sizeof (errno_tab)) | |
|     errno = EINVAL; | |
|   else | |
|     errno = errno_tab[rc]; | |
| } | |
| 
 | |
| 
 | |
| longlong _lseek64( int fd, longlong offset, int seektype) | |
| { | |
|   APIRET   rc; | |
|   longlong actual; | |
| 
 | |
|   if (_DosSetFilePtrL) | |
|     rc = _DosSetFilePtrL( fd, offset, seektype, &actual); | |
|   else | |
|   { | |
|     ULONG ulActual; | |
|     rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual); | |
|     actual = ulActual; | |
|   } | |
| 
 | |
|   if (!rc) | |
|     return( actual);				/* NO_ERROR */ | |
| 
 | |
|   _OS2errno( rc);				/* set errno */ | |
|   return(-1);					/* seek failed */ | |
| } | |
| 
 | |
| 
 | |
| inline APIRET _SetFileLocksL(HFILE hFile, | |
| 			     PFILELOCKL pflUnlock, | |
| 			     PFILELOCKL pflLock, | |
| 			     ULONG timeout, | |
| 			     ULONG flags) | |
| { | |
|   if (_DosSetFileLocksL) | |
|   { | |
|     APIRET rc; | |
|     rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags); | |
| 
 | |
|     /* | |
|       on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that | |
|       only JFS can handle >2GB ranges. | |
|     */ | |
|     if (rc != 87) | |
|       return rc; | |
|     /* got INVALID_PARAMETER, fallback to standard call */ | |
|   } | |
| 
 | |
|   FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange }; | |
|   FILELOCK flLock = { pflLock->lOffset, pflLock->lRange }; | |
|   return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags); | |
| } | |
| 
 | |
| 
 | |
| int  _lock64( int fd, int locktype, my_off_t start, | |
| 	      my_off_t length, myf MyFlags) | |
| { | |
|   FILELOCKL LockArea = {0,0}, UnlockArea = {0,0}; | |
|   ULONG     readonly = 0; | |
|   APIRET    rc = -1; | |
| 
 | |
|   switch (locktype) { | |
|   case F_UNLCK: | |
|     UnlockArea.lOffset = start; | |
|     UnlockArea.lRange = length ? length : LONGLONG_MAX; | |
|     break; | |
| 
 | |
|   case F_RDLCK: | |
|   case F_WRLCK: | |
|     LockArea.lOffset = start; | |
|     LockArea.lRange = length ? length : LONGLONG_MAX; | |
|     readonly = (locktype == F_RDLCK ? 1 : 0); | |
|     break; | |
| 
 | |
|   default: | |
|     errno = EINVAL; | |
|     rc = -1; | |
|     break; | |
|   } | |
| 
 | |
|   if (MyFlags & MY_DONT_WAIT) | |
|   { | |
|     rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly); | |
|     /* printf("fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc); */ | |
|     if (rc == 33) {  /* Lock Violation */ | |
| 
 | |
|       DBUG_PRINT("info",("Was locked, trying with timeout")); | |
|       rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly); | |
|       /* printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc); */ | |
|     } | |
|   } | |
|   else | |
|   { | |
|     while (rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) && | |
| 	   (rc == 33)) | |
|     { | |
|       printf("."); | |
|       DosSleep(1 * 1000); | |
|     } | |
|     /* printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc); */ | |
|   } | |
|   if (!rc) | |
|     return(0);				/* NO_ERROR */ | |
|   _OS2errno( rc);				/* set errno */ | |
|   return(-1);					/* lock failed */ | |
| } | |
| 
 | |
| 
 | |
| int sopen(const char *name, int oflag, int shflag, int mask) | |
| { | |
|   int	    fail_errno; | |
|   APIRET   rc = 0; | |
|   HFILE    hf = 0; | |
|   ULONG    ulAction = 0; | |
|   LONGLONG cbFile = 0; | |
|   ULONG    ulAttribute = FILE_NORMAL; | |
|   ULONG    fsOpenFlags = 0; | |
|   ULONG    fsOpenMode = 0; | |
| 
 | |
|   /* Extract the access mode and sharing mode bits. */ | |
|   fsOpenMode = (shflag & 0xFF) | (oflag & 0x03); | |
| 
 | |
|   /* | |
|     Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see | |
|     below). | |
|   */ | |
|   fail_errno = ENOENT; | |
| 
 | |
|   /* | |
|     Compute `open_flag' depending on `flags'.  Note that _SO_CREAT is | |
|     set for O_CREAT. | |
|   */ | |
| 
 | |
|   if (oflag & O_CREAT) | |
|   { | |
|     if (oflag & O_EXCL) | |
|     { | |
|       fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; | |
|       fail_errno = EEXIST; | |
|     } | |
|     else if (oflag & O_TRUNC) | |
|       fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; | |
|     else | |
|       fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; | |
| 
 | |
|     if (mask & S_IWRITE) | |
|       ulAttribute = FILE_NORMAL; | |
|     else | |
|       ulAttribute = FILE_READONLY; | |
| 
 | |
|   } | |
|   else if (oflag & O_TRUNC) | |
|     fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; | |
|   else | |
|     fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; | |
| 
 | |
|   /* Try to open the file and handle errors. */ | |
|   if (_DosOpenL) | |
|     rc = _DosOpenL( name, &hf, &ulAction, cbFile, | |
| 		    ulAttribute, fsOpenFlags, fsOpenMode, NULL); | |
|   else | |
|     rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile, | |
| 		  ulAttribute, fsOpenFlags, fsOpenMode, NULL); | |
| 
 | |
|   if (rc == ERROR_OPEN_FAILED) | |
|   { | |
|     errno = fail_errno; | |
|     return -1; | |
|   } | |
|   if (rc != 0) | |
|   { | |
|     _OS2errno( rc);      /* set errno */ | |
|     return -1; | |
|   } | |
|   if (oflag & O_APPEND) | |
|     _lseek64( hf, 0L, SEEK_END); | |
|   return hf; | |
| } | |
| 
 | |
| 
 | |
| int read(int fd, void *buffer, unsigned int count) | |
| { | |
|   APIRET   rc; | |
|   ULONG    actual; | |
| 
 | |
|   rc= DosRead( fd, (PVOID) buffer, count, &actual); | |
| 
 | |
|   if (!rc) | |
|     return( actual);				/* NO_ERROR */ | |
|   _OS2errno( rc);				/* set errno */ | |
|   return(-1);					/* read failed */ | |
| } | |
| 
 | |
| 
 | |
| int write(int fd, const void *buffer, unsigned int count) | |
| { | |
|   APIRET   rc; | |
|   ULONG    actual; | |
| 
 | |
|   rc = DosWrite( fd, (PVOID) buffer, count, &actual); | |
| 
 | |
|   if (!rc) | |
|     return( actual);				/* NO_ERROR */ | |
|   _OS2errno( rc);				/* set errno */ | |
|   return(-1);					/* write failed */ | |
| } | |
| 
 | |
| 
 | |
| int close( int fd) | |
| { | |
|   APIRET   rc; | |
|   ULONG    actual; | |
| 
 | |
|   rc = DosClose( fd); | |
| 
 | |
|   if (!rc) | |
|     return( 0);					/* NO_ERROR */ | |
|   _OS2errno( rc);				/* set errno */ | |
|   return(-1);					/* close failed */ | |
| } | |
| 
 | |
| 
 | |
| int open( const char *name, int oflag) | |
| { | |
|    return sopen( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE); | |
| } | |
| 
 | |
| 
 | |
| int open( const char *name, int oflag, int mask) | |
| { | |
|    return sopen( name, oflag, OPEN_SHARE_DENYNONE, mask); | |
| }
 |