diff options
Diffstat (limited to 'mysql/mysys/my_winfile.c')
-rw-r--r-- | mysql/mysys/my_winfile.c | 682 |
1 files changed, 0 insertions, 682 deletions
diff --git a/mysql/mysys/my_winfile.c b/mysql/mysys/my_winfile.c deleted file mode 100644 index a5c13a3..0000000 --- a/mysql/mysys/my_winfile.c +++ /dev/null @@ -1,682 +0,0 @@ -/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/* - The purpose of this file is to provide implementation of file IO routines on - Windows that can be thought as drop-in replacement for corresponding C runtime - functionality. - - Compared to Windows CRT, this one - - does not have the same file descriptor - limitation (default is 16384 and can be increased further, whereas CRT poses - a hard limit of 2048 file descriptors) - - the file operations are not serialized - - positional IO pread/pwrite is ported here. - - no text mode for files, all IO is "binary" - - Naming convention: - All routines are prefixed with my_win_, e.g Posix open() is implemented with - my_win_open() - - Implemented are - - POSIX routines(e.g open, read, lseek ...) - - Some ANSI C stream routines (fopen, fdopen, fileno, fclose) - - Windows CRT equvalients (my_get_osfhandle, open_osfhandle) - - Worth to note: - - File descriptors used here are located in a range that is not compatible - with CRT on purpose. Attempt to use a file descriptor from Windows CRT library - range in my_win_* function will be punished with DBUG_ASSERT() - - - File streams (FILE *) are actually from the C runtime. The routines provided - here are useful only in scernarios that use low-level IO with my_win_fileno() -*/ - -#ifdef _WIN32 - -#include "mysys_priv.h" -#include "my_thread_local.h" -#include <share.h> -#include <sys/stat.h> - -/* Associates a file descriptor with an existing operating-system file handle.*/ -File my_open_osfhandle(HANDLE handle, int oflag) -{ - int offset= -1; - uint i; - DBUG_ENTER("my_open_osfhandle"); - - mysql_mutex_lock(&THR_LOCK_open); - for(i= MY_FILE_MIN; i < my_file_limit;i++) - { - if(my_file_info[i].fhandle == 0) - { - struct st_my_file_info *finfo= &(my_file_info[i]); - finfo->type= FILE_BY_OPEN; - finfo->fhandle= handle; - finfo->oflag= oflag; - offset= i; - break; - } - } - mysql_mutex_unlock(&THR_LOCK_open); - if(offset == -1) - errno= EMFILE; /* to many file handles open */ - DBUG_RETURN(offset); -} - - -static void invalidate_fd(File fd) -{ - DBUG_ENTER("invalidate_fd"); - DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); - my_file_info[fd].fhandle= 0; - DBUG_VOID_RETURN; -} - - -/* Get Windows handle for a file descriptor */ -HANDLE my_get_osfhandle(File fd) -{ - DBUG_ENTER("my_get_osfhandle"); - DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); - DBUG_RETURN(my_file_info[fd].fhandle); -} - - -static int my_get_open_flags(File fd) -{ - DBUG_ENTER("my_get_open_flags"); - DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); - DBUG_RETURN(my_file_info[fd].oflag); -} - - -/* - Open a file with sharing. Similar to _sopen() from libc, but allows managing - share delete on win32 - - SYNOPSIS - my_win_sopen() - path file name - oflag operation flags - shflag share flag - pmode permission flags - - RETURN VALUE - File descriptor of opened file if success - -1 and sets errno if fails. -*/ - -File my_win_sopen(const char *path, int oflag, int shflag, int pmode) -{ - int fh; /* handle of opened file */ - int mask; - HANDLE osfh; /* OS handle of opened file */ - DWORD fileaccess; /* OS file access (requested) */ - DWORD fileshare; /* OS file sharing mode */ - DWORD filecreate; /* OS method of opening/creating */ - DWORD fileattrib; /* OS file attribute flags */ - SECURITY_ATTRIBUTES SecurityAttributes; - - DBUG_ENTER("my_win_sopen"); - - if (check_if_legal_filename(path)) - { - errno= EACCES; - DBUG_RETURN(-1); - } - SecurityAttributes.nLength= sizeof(SecurityAttributes); - SecurityAttributes.lpSecurityDescriptor= NULL; - SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT); - - /* decode the access flags */ - switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_RDONLY: /* read access */ - fileaccess= GENERIC_READ; - break; - case _O_WRONLY: /* write access */ - fileaccess= GENERIC_WRITE; - break; - case _O_RDWR: /* read and write access */ - fileaccess= GENERIC_READ | GENERIC_WRITE; - break; - default: /* error, bad oflag */ - errno= EINVAL; - DBUG_RETURN(-1); - } - - /* decode sharing flags */ - switch (shflag) { - case _SH_DENYRW: /* exclusive access except delete */ - fileshare= FILE_SHARE_DELETE; - break; - case _SH_DENYWR: /* share read and delete access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE; - break; - case _SH_DENYRD: /* share write and delete access */ - fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE; - break; - case _SH_DENYNO: /* share read, write and delete access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - break; - case _SH_DENYRWD: /* exclusive access */ - fileshare= 0L; - break; - case _SH_DENYWRD: /* share read access */ - fileshare= FILE_SHARE_READ; - break; - case _SH_DENYRDD: /* share write access */ - fileshare= FILE_SHARE_WRITE; - break; - case _SH_DENYDEL: /* share read and write access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE; - break; - default: /* error, bad shflag */ - errno= EINVAL; - DBUG_RETURN(-1); - } - - /* decode open/create method flags */ - switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) { - case 0: - case _O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate= OPEN_EXISTING; - break; - - case _O_CREAT: - filecreate= OPEN_ALWAYS; - break; - - case _O_CREAT | _O_EXCL: - case _O_CREAT | _O_TRUNC | _O_EXCL: - filecreate= CREATE_NEW; - break; - - case _O_TRUNC: - case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate= TRUNCATE_EXISTING; - break; - - case _O_CREAT | _O_TRUNC: - filecreate= CREATE_ALWAYS; - break; - - default: - /* this can't happen ... all cases are covered */ - errno= EINVAL; - DBUG_RETURN(-1); - } - - /* decode file attribute flags if _O_CREAT was specified */ - fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */ - if (oflag & _O_CREAT) - { - _umask((mask= _umask(0))); - - if (!((pmode & ~mask) & _S_IWRITE)) - fileattrib= FILE_ATTRIBUTE_READONLY; - } - - /* Set temporary file (delete-on-close) attribute if requested. */ - if (oflag & _O_TEMPORARY) - { - fileattrib|= FILE_FLAG_DELETE_ON_CLOSE; - fileaccess|= DELETE; - } - - /* Set temporary file (delay-flush-to-disk) attribute if requested.*/ - if (oflag & _O_SHORT_LIVED) - fileattrib|= FILE_ATTRIBUTE_TEMPORARY; - - /* Set sequential or random access attribute if requested. */ - if (oflag & _O_SEQUENTIAL) - fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN; - else if (oflag & _O_RANDOM) - fileattrib|= FILE_FLAG_RANDOM_ACCESS; - - /* try to open/create the file */ - if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, - filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) - { - /* - OS call to open/create file failed! map the error, release - the lock, and return -1. note that it's not necessary to - call _free_osfhnd (it hasn't been used yet). - */ - my_osmaperr(GetLastError()); /* map error */ - DBUG_RETURN(-1); /* return error to caller */ - } - - if ((fh= my_open_osfhandle(osfh, - oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1) - { - CloseHandle(osfh); - } - - DBUG_RETURN(fh); /* return handle */ -} - - -File my_win_open(const char *path, int flags) -{ - DBUG_ENTER("my_win_open"); - DBUG_RETURN(my_win_sopen((char *) path, flags | _O_BINARY, _SH_DENYNO, - _S_IREAD | S_IWRITE)); -} - - -int my_win_close(File fd) -{ - DBUG_ENTER("my_win_close"); - if(CloseHandle(my_get_osfhandle(fd))) - { - invalidate_fd(fd); - DBUG_RETURN(0); - } - my_osmaperr(GetLastError()); - DBUG_RETURN(-1); -} - - -size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset) -{ - DWORD nBytesRead; - HANDLE hFile; - OVERLAPPED ov= {0}; - LARGE_INTEGER li; - - DBUG_ENTER("my_win_pread"); - - if(!Count) - DBUG_RETURN(0); -#ifdef _WIN64 - if(Count > UINT_MAX) - Count= UINT_MAX; -#endif - - hFile= (HANDLE)my_get_osfhandle(Filedes); - li.QuadPart= offset; - ov.Offset= li.LowPart; - ov.OffsetHigh= li.HighPart; - - if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov)) - { - DWORD lastError= GetLastError(); - /* - ERROR_BROKEN_PIPE is returned when no more data coming - through e.g. a command pipe in windows : see MSDN on ReadFile. - */ - if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) - DBUG_RETURN(0); /*return 0 at EOF*/ - my_osmaperr(lastError); - DBUG_RETURN((size_t)-1); - } - DBUG_RETURN(nBytesRead); -} - - -size_t my_win_read(File Filedes, uchar *Buffer, size_t Count) -{ - DWORD nBytesRead; - HANDLE hFile; - - DBUG_ENTER("my_win_read"); - if(!Count) - DBUG_RETURN(0); -#ifdef _WIN64 - if(Count > UINT_MAX) - Count= UINT_MAX; -#endif - - hFile= (HANDLE)my_get_osfhandle(Filedes); - - if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, NULL)) - { - DWORD lastError= GetLastError(); - /* - ERROR_BROKEN_PIPE is returned when no more data coming - through e.g. a command pipe in windows : see MSDN on ReadFile. - */ - if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) - DBUG_RETURN(0); /*return 0 at EOF*/ - my_osmaperr(lastError); - DBUG_RETURN((size_t)-1); - } - DBUG_RETURN(nBytesRead); -} - - -size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count, - my_off_t offset) -{ - DWORD nBytesWritten; - HANDLE hFile; - OVERLAPPED ov= {0}; - LARGE_INTEGER li; - - DBUG_ENTER("my_win_pwrite"); - DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %llu, offset: %llu", - Filedes, Buffer, (ulonglong)Count, (ulonglong)offset)); - - if(!Count) - DBUG_RETURN(0); - -#ifdef _WIN64 - if(Count > UINT_MAX) - Count= UINT_MAX; -#endif - - hFile= (HANDLE)my_get_osfhandle(Filedes); - li.QuadPart= offset; - ov.Offset= li.LowPart; - ov.OffsetHigh= li.HighPart; - - if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov)) - { - my_osmaperr(GetLastError()); - DBUG_RETURN((size_t)-1); - } - else - DBUG_RETURN(nBytesWritten); -} - - -my_off_t my_win_lseek(File fd, my_off_t pos, int whence) -{ - LARGE_INTEGER offset; - LARGE_INTEGER newpos; - - DBUG_ENTER("my_win_lseek"); - - /* Check compatibility of Windows and Posix seek constants */ - compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR - && FILE_END == SEEK_END); - - offset.QuadPart= pos; - if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence)) - { - my_osmaperr(GetLastError()); - newpos.QuadPart= -1; - } - DBUG_RETURN(newpos.QuadPart); -} - - -#ifndef FILE_WRITE_TO_END_OF_FILE -#define FILE_WRITE_TO_END_OF_FILE 0xffffffff -#endif -size_t my_win_write(File fd, const uchar *Buffer, size_t Count) -{ - DWORD nWritten; - OVERLAPPED ov; - OVERLAPPED *pov= NULL; - HANDLE hFile; - - DBUG_ENTER("my_win_write"); - DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer, - (ulonglong)Count)); - - if(!Count) - DBUG_RETURN(0); - -#ifdef _WIN64 - if(Count > UINT_MAX) - Count= UINT_MAX; -#endif - - if(my_get_open_flags(fd) & _O_APPEND) - { - /* - Atomic append to the end of file is is done by special initialization of - the OVERLAPPED structure. See MSDN WriteFile documentation for more info. - */ - memset(&ov, 0, sizeof(ov)); - ov.Offset= FILE_WRITE_TO_END_OF_FILE; - ov.OffsetHigh= -1; - pov= &ov; - } - - hFile= my_get_osfhandle(fd); - if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov)) - { - my_osmaperr(GetLastError()); - DBUG_RETURN((size_t)-1); - } - DBUG_RETURN(nWritten); -} - - -int my_win_chsize(File fd, my_off_t newlength) -{ - HANDLE hFile; - LARGE_INTEGER length; - DBUG_ENTER("my_win_chsize"); - - hFile= (HANDLE) my_get_osfhandle(fd); - length.QuadPart= newlength; - if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN)) - goto err; - if (!SetEndOfFile(hFile)) - goto err; - DBUG_RETURN(0); -err: - my_osmaperr(GetLastError()); - set_my_errno(errno); - DBUG_RETURN(-1); -} - - -/* Get the file descriptor for stdin,stdout or stderr */ -static File my_get_stdfile_descriptor(FILE *stream) -{ - HANDLE hFile; - DWORD nStdHandle; - DBUG_ENTER("my_get_stdfile_descriptor"); - - if(stream == stdin) - nStdHandle= STD_INPUT_HANDLE; - else if(stream == stdout) - nStdHandle= STD_OUTPUT_HANDLE; - else if(stream == stderr) - nStdHandle= STD_ERROR_HANDLE; - else - DBUG_RETURN(-1); - - hFile= GetStdHandle(nStdHandle); - if(hFile != INVALID_HANDLE_VALUE) - DBUG_RETURN(my_open_osfhandle(hFile, 0)); - DBUG_RETURN(-1); -} - - -File my_win_fileno(FILE *file) -{ - HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file)); - int retval= -1; - uint i; - - DBUG_ENTER("my_win_fileno"); - - for(i= MY_FILE_MIN; i < my_file_limit; i++) - { - if(my_file_info[i].fhandle == hFile) - { - retval= i; - break; - } - } - if(retval == -1) - /* try std stream */ - DBUG_RETURN(my_get_stdfile_descriptor(file)); - DBUG_RETURN(retval); -} - - -FILE *my_win_fopen(const char *filename, const char *type) -{ - FILE *file; - int flags= 0; - DBUG_ENTER("my_win_open"); - - /* - If we are not creating, then we need to use my_access to make sure - the file exists since Windows doesn't handle files like "com1.sym" - very well - */ - if (check_if_legal_filename(filename)) - { - errno= EACCES; - DBUG_RETURN(NULL); - } - - file= fopen(filename, type); - if(!file) - DBUG_RETURN(NULL); - - if(strchr(type,'a') != NULL) - flags= O_APPEND; - - /* - Register file handle in my_table_info. - Necessary for my_fileno() - */ - if(my_open_osfhandle((HANDLE)_get_osfhandle(fileno(file)), flags) < 0) - { - fclose(file); - DBUG_RETURN(NULL); - } - DBUG_RETURN(file); -} - - -FILE * my_win_fdopen(File fd, const char *type) -{ - FILE *file; - int crt_fd; - int flags= 0; - - DBUG_ENTER("my_win_fdopen"); - - if(strchr(type,'a') != NULL) - flags= O_APPEND; - /* Convert OS file handle to CRT file descriptor and then call fdopen*/ - crt_fd= _open_osfhandle((intptr_t)my_get_osfhandle(fd), flags); - if(crt_fd < 0) - file= NULL; - else - file= fdopen(crt_fd, type); - DBUG_RETURN(file); -} - - -int my_win_fclose(FILE *file) -{ - File fd; - - DBUG_ENTER("my_win_close"); - fd= my_fileno(file); - if(fd < 0) - DBUG_RETURN(-1); - if(fclose(file) < 0) - DBUG_RETURN(-1); - invalidate_fd(fd); - DBUG_RETURN(0); -} - - - -/* - Quick and dirty my_fstat() implementation for Windows. - Use CRT fstat on temporarily allocated file descriptor. - Patch file size, because size that fstat returns is not - reliable (may be outdated) -*/ -int my_win_fstat(File fd, struct _stati64 *buf) -{ - int crt_fd; - int retval; - HANDLE hFile, hDup; - - DBUG_ENTER("my_win_fstat"); - - hFile= my_get_osfhandle(fd); - if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(), - &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS)) - { - my_osmaperr(GetLastError()); - DBUG_RETURN(-1); - } - if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0) - DBUG_RETURN(-1); - - retval= _fstati64(crt_fd, buf); - if(retval == 0) - { - /* File size returned by stat is not accurate (may be outdated), fix it*/ - GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size))); - } - _close(crt_fd); - DBUG_RETURN(retval); -} - - - -int my_win_stat( const char *path, struct _stati64 *buf) -{ - DBUG_ENTER("my_win_stat"); - if(_stati64( path, buf) == 0) - { - /* File size returned by stat is not accurate (may be outdated), fix it*/ - WIN32_FILE_ATTRIBUTE_DATA data; - if (GetFileAttributesEx(path, GetFileExInfoStandard, &data)) - { - LARGE_INTEGER li; - li.LowPart= data.nFileSizeLow; - li.HighPart= data.nFileSizeHigh; - buf->st_size= li.QuadPart; - } - DBUG_RETURN(0); - } - DBUG_RETURN(-1); -} - - - -int my_win_fsync(File fd) -{ - DBUG_ENTER("my_win_fsync"); - if(FlushFileBuffers(my_get_osfhandle(fd))) - DBUG_RETURN(0); - my_osmaperr(GetLastError()); - DBUG_RETURN(-1); -} - - - -int my_win_dup(File fd) -{ - HANDLE hDup; - DBUG_ENTER("my_win_dup"); - if (DuplicateHandle(GetCurrentProcess(), my_get_osfhandle(fd), - GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) - { - DBUG_RETURN(my_open_osfhandle(hDup, my_get_open_flags(fd))); - } - my_osmaperr(GetLastError()); - DBUG_RETURN(-1); -} - -#endif /*_WIN32*/ |