List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:June 4 2008 1:08am
Subject:commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653) Bug#24509,
WL#3049
View as plain text  
#At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-wtf/

 2653 Vladislav Vaintroub	2008-06-04
      Bug#24509 - 2048 file descriptor limit on windows needs increasing, also 
      WL#3049 - improved Windows I/O
      
      The patch replaces the use of the POSIX I/O interfaces in mysys on Windows with 
      the Win32 API calls (CreateFile, WriteFile, etc). The Windows HANDLE for the open 
      file is stored in the my_file_info struct, along with a flag for append mode 
      (because the Windows API does not support opening files in append mode in all cases)
      The default max open files has been increased to 16384 and can be increased further
      by setting --max-open-files=<value> during the server start.
      
      Additionally, my_(f)stat() is changed to use __stati64 structure with  64 file size
and
      timestamps. It will now return correct file size now, unlike C runtime stat() that
may 
      report outdated info.
added:
  mysys/my_winerr.c
modified:
  client/mysqlbinlog.cc
  client/mysqlslap.c
  client/readline.cc
  include/config-win.h
  include/my_dir.h
  include/my_global.h
  include/my_sys.h
  libmysql/CMakeLists.txt
  mysys/CMakeLists.txt
  mysys/Makefile.am
  mysys/default_modify.c
  mysys/my_chsize.c
  mysys/my_div.c
  mysys/my_file.c
  mysys/my_fopen.c
  mysys/my_fstream.c
  mysys/my_lib.c
  mysys/my_lock.c
  mysys/my_mmap.c
  mysys/my_open.c
  mysys/my_pread.c
  mysys/my_quick.c
  mysys/my_read.c
  mysys/my_seek.c
  mysys/my_static.c
  mysys/my_sync.c
  mysys/my_write.c
  storage/innobase/handler/ha_innodb.cc
  storage/myisam/mi_locking.c

per-file comments:
  client/mysqlbinlog.cc
    Changed fileno() to my_fileno()
  client/mysqlslap.c
    Changed fileno() to my_fileno()
  client/readline.cc
    Changed fileno() to my_fileno()
  include/config-win.h
    Increase limit for number of open files on windows
  include/my_dir.h
    use struct _stati64 instead of struct stat for stat() family of functions,
    (because of 64 bit file size and timestamps)
  include/my_global.h
    - Increased MY_NFILE (default value for --max-open-files  on Windows) to 16384
    
    - Introduced MY_FILE_MIN the minimal file descriptor returned by my_open().
    Useful on Windows to catch errors if somebody mixes C runtime functions with mysys IO,
    as C runtime descriptor are always smaller than MY_FILE_MIN (==2048 on Windows).
    
    - Don't use MY_STAT_STRUCT in stat() functions , use struct __stati64 instead 
    (because the later has 64 bit file size and timestamps)
  include/my_sys.h
    - Extend my_file_info to include HANDLE and open flag on Windows.
    - Declare some new Windows IO functions and my_fileno()
  libmysql/CMakeLists.txt
    New file my_winerr.c
  mysys/CMakeLists.txt
    New file  my_winerr.c
  mysys/Makefile.am
    New file my_winerr.c
  mysys/default_modify.c
    fileno()->my_fileno()
  mysys/my_chsize.c
    _get_osfhandle()->my_get_osfhandle()
    
    Use SetFilePointerEx instead of SetFilePointer in my_chsize (simpler API)
  mysys/my_div.c
    Ignore filedescriptors smaller than MY_FILE_MIN in my_filename()
  mysys/my_file.c
    Valid range for file descriptors is [MY_FILE_MIN,my_file_limit]
  mysys/my_fopen.c
    mysys native Windows IO - adapt my_fopen, my_fdopen and my_fclose
  mysys/my_fstream.c
    mysys native Windows IO - new function my_fileno()
  mysys/my_lib.c
    mysys native Windows IO - adaptations for stat() and my_fstat().
  mysys/my_lock.c
    _get_osfhandle -> my_get_osfhandle
  mysys/my_mmap.c
    _get_osfhandle -> my_get_osfhandle
  mysys/my_open.c
    mysys native Windows IO - implement my_open() and my_close().
  mysys/my_pread.c
    _get_osfhandle -> my_get_osfhandle
  mysys/my_quick.c
    mysys native Windows IO  for my_quick_read() and my_quick_write()
  mysys/my_read.c
    mysys native Windows IO  for my_read()
  mysys/my_seek.c
    mysys native Windows IO  for my_seek()
  mysys/my_static.c
    Remove initialization for my_file_info_default, because my_file_info structure is 
    now platform dependent. As global variable, it is initialized with  all nulls anyway.
  mysys/my_sync.c
    mysys native Windows IO  for my_sync()
  mysys/my_winerr.c
    New file my_winerr. Contains my_osmaperr modelled after undocumented C runtime
    function _dosmaperr(). The problem with _dosmaperr() used previously is that 
    1) it is nowhere documented and thus code relying on it is not guaranteed to work
    in subsequent releases on the C runtime
    2) it is present only in static C runtime (mysqld does not link if compiled with
    /MD)
  mysys/my_write.c
    mysys native Windows IO  for my_write.
    Atomic APPEND is handled via technique described in MSDN community 
    content for WriteFile (and driver documentation)
  storage/innobase/handler/ha_innodb.cc
    mysys native Windows IO : correct innodb tmp file handling
    
    mysql_tmpfile does not return valid CRT file descriptor, thus
    it is not possible to do a dup() on it. Instead, the native file handle has 
    to be duplicated and converted to CRT descriptor.
  storage/myisam/mi_locking.c
    mysys Windows native IO : replace _commit() with my_sync. 
    _commit is not going to work for something that is not CRT file descriptor.
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2008-04-03 17:22:10 +0000
+++ b/client/mysqlbinlog.cc	2008-06-03 23:08:38 +0000
@@ -1840,7 +1840,7 @@ static Exit_status dump_local_log_entrie
       return ERROR_STOP;
     }
 #endif 
-    if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
+    if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
 		      0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
     {
       error("Failed to init IO cache.");

=== modified file 'client/mysqlslap.c'
--- a/client/mysqlslap.c	2008-04-25 16:43:25 +0000
+++ b/client/mysqlslap.c	2008-06-03 23:08:38 +0000
@@ -1331,7 +1331,7 @@ get_options(int *argc,char ***argv)
     
     if (opt_csv_str[0] == '-')
     {
-      csv_file= fileno(stdout);
+      csv_file= my_fileno(stdout);
     }
     else
     {

=== modified file 'client/readline.cc'
--- a/client/readline.cc	2007-05-10 09:59:39 +0000
+++ b/client/readline.cc	2008-06-03 23:08:38 +0000
@@ -33,7 +33,7 @@ LINE_BUFFER *batch_readline_init(ulong m
   if (!(line_buff=(LINE_BUFFER*)
         my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
     return 0;
-  if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
+  if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size))
   {
     my_free(line_buff,MYF(0));
     return 0;

=== modified file 'include/config-win.h'
--- a/include/config-win.h	2008-05-09 11:25:34 +0000
+++ b/include/config-win.h	2008-06-03 23:08:38 +0000
@@ -353,7 +353,7 @@ inline double ulonglong2double(ulonglong
 #define FN_DEVCHAR	':'
 #define FN_NETWORK_DRIVES	/* Uses \\ to indicate network drives */
 #define FN_NO_CASE_SENCE	/* Files are not case-sensitive */
-#define OS_FILE_LIMIT	2048
+#define OS_FILE_LIMIT	UINT_MAX /* No limit*/
 
 #define DO_NOT_REMOVE_THREAD_WRAPPERS
 #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))

=== modified file 'include/my_dir.h'
--- a/include/my_dir.h	2006-12-23 19:17:15 +0000
+++ b/include/my_dir.h	2008-06-03 23:08:38 +0000
@@ -69,7 +69,11 @@ typedef struct my_stat
 
 #else
 
+#if(_MSC_VER)
+#define MY_STAT struct __stat64 /* 64 bit file size and timestamp */
+#else
 #define MY_STAT struct stat	/* Orginal struct have what we need */
+#endif
 
 #endif /* USE_MY_STAT_STRUCT */
 

=== modified file 'include/my_global.h'
--- a/include/my_global.h	2008-05-08 20:43:28 +0000
+++ b/include/my_global.h	2008-06-03 23:08:38 +0000
@@ -469,15 +469,17 @@ C_MODE_END
 #include <assert.h>
 
 /* an assert that works at compile-time. only for constant expression */
-#ifndef __GNUC__
-#define compile_time_assert(X)  do { } while(0)
-#else
+#if (_MSC_VER >=1400)
+#define compile_time_assert(X)  do { C_ASSERT(X); } while(0)
+#elif defined (___GNUC__)
 #define compile_time_assert(X)                                  \
   do                                                            \
   {                                                             \
     char compile_time_assert[(X) ? 1 : -1]                      \
                              __attribute__ ((unused));          \
   } while(0)
+#else
+#define compile_time_assert(X)  do { } while(0)
 #endif
 
 /* Go around some bugs in different OS and compilers */
@@ -727,7 +729,30 @@ typedef SOCKET_SIZE_TYPE size_socket;
 #define FN_LIBCHAR	'/'
 #define FN_ROOTDIR	"/"
 #endif
+
+/* 
+  MY_FILE_MIN is  Windows speciality and is used to quickly detect
+  the mismatch of CRT and mysys file IO usage on Windows at runtime.
+  CRT file descriptors can be in the range 0-2047, whereas descriptors returned
+  by my_open() will start with 2048. If a file descriptor with value less then
+  MY_FILE_MIN is passed to mysys IO function, chances are it stemms from
+  open()/fileno() and not my_open()/my_fileno.
+
+  On Unix, where the mysys functions are light wrappers around libc, MY_FILE_MIN
+  is logically 0.
+*/
+#ifdef __WIN__
+#define MY_FILE_MIN  2048
+#else
+#define MY_FILE_MIN  0
+#endif
+
+#ifndef __WIN__
 #define MY_NFILE	64	/* This is only used to save filenames */
+#else
+#define MY_NFILE (16384 + MY_FILE_MIN) /* This is used to store file handles */
+#endif
+
 #ifndef OS_FILE_LIMIT
 #define OS_FILE_LIMIT	65535
 #endif
@@ -766,7 +791,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
 #define NO_HASH			/* Not needed anymore */
 #ifdef __WIN__
 #define NO_DIR_LIBRARY		/* Not standar dir-library */
-#define USE_MY_STAT_STRUCT	/* For my_lib */
 #endif
 
 /* Some defines of functions for portability */

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2008-05-08 16:01:15 +0000
+++ b/include/my_sys.h	2008-06-03 23:08:38 +0000
@@ -310,8 +310,12 @@ enum file_type
 
 struct st_my_file_info
 {
-  char *		name;
-  enum file_type	type;
+  char *  name;
+#ifdef __WIN__
+  HANDLE fhandle;   /* win32 file handle */
+  int    oflag;     /* open flags, e.g O_APPEND */
+#endif
+  enum   file_type	type;
 #if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
   pthread_mutex_t	mutex;
 #endif
@@ -617,8 +621,12 @@ extern void *my_memmem(const void *hayst
 
 
 #ifdef __WIN__
-extern int my_access(const char *path, int amode);
-extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+extern int    my_access(const char *path, int amode);
+extern File   my_sopen(const char *path, int oflag, int shflag, int pmode);
+extern void   my_osmaperr(unsigned long last_error);
+extern File   my_open_osfhandle(HANDLE handle, int oflag);
+extern HANDLE my_get_osfhandle(File fd);
+extern int    my_get_open_flags(File fd);
 #else
 #define my_access access
 #endif
@@ -639,6 +647,7 @@ extern void init_glob_errs(void);
 extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
 extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
 extern int my_fclose(FILE *fd,myf MyFlags);
+extern File my_fileno(FILE *fd);
 extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
 extern int my_sync(File fd, myf my_flags);
 extern int my_sync_dir(const char *dir_name, myf my_flags);
@@ -904,7 +913,7 @@ extern int my_getncpus();
 #define HAVE_MMAP
 #endif
 
-void *my_mmap(void *, size_t, int, int, int, my_off_t);
+void *my_mmap(void *, size_t, int, int, File, my_off_t);
 int my_munmap(void *, size_t);
 #endif
 

=== modified file 'libmysql/CMakeLists.txt'
--- a/libmysql/CMakeLists.txt	2008-04-08 01:47:13 +0000
+++ b/libmysql/CMakeLists.txt	2008-06-03 23:08:38 +0000
@@ -98,7 +98,7 @@ SET(CLIENT_SOURCES   ../mysys/array.c ..
                      ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c
../strings/strxnmov.c 
                      ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c
../vio/viosocket.c 
                      ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c
../mysys/mf_qsort.c
-		     ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES})
+		     ../mysys/my_getsystime.c ../mysys/my_sync.c ../mysys/my_winerr.c ${LIB_SOURCES})
 
 # Need to set USE_TLS for building the DLL, since __declspec(thread)
 # approach to thread local storage does not work properly in DLLs.

=== modified file 'mysys/CMakeLists.txt'
--- a/mysys/CMakeLists.txt	2007-11-07 23:18:30 +0000
+++ b/mysys/CMakeLists.txt	2008-06-03 23:08:38 +0000
@@ -39,7 +39,7 @@ SET(MYSYS_SOURCES  array.c charset-def.c
 				my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c 
 				my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
 				my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
-				my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c
+				my_winerr.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c
 				rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
 				thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c
 				my_atomic.c my_getncpus.c lf_dynarray.c lf_alloc-pin.c lf_hash.c)

=== modified file 'mysys/Makefile.am'
--- a/mysys/Makefile.am	2008-04-01 15:13:57 +0000
+++ b/mysys/Makefile.am	2008-06-03 23:08:38 +0000
@@ -57,7 +57,7 @@ libmysys_a_SOURCES =    my_init.c my_get
 EXTRA_DIST =		thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
 			thr_mutex.c thr_rwlock.c \
 			CMakeLists.txt mf_soundex.c \
-			my_conio.c my_wincond.c my_winthread.c
+			my_conio.c my_wincond.c my_winthread.c my_winerr.c
 libmysys_a_LIBADD =	@THREAD_LOBJECTS@
 # test_dir_DEPENDENCIES=	$(LIBRARIES)
 # testhash_DEPENDENCIES=	$(LIBRARIES)

=== modified file 'mysys/default_modify.c'
--- a/mysys/default_modify.c	2007-07-30 08:33:50 +0000
+++ b/mysys/default_modify.c	2008-06-03 23:08:38 +0000
@@ -80,7 +80,7 @@ int modify_defaults_file(const char *fil
     DBUG_RETURN(2);
 
   /* my_fstat doesn't use the flag parameter */
-  if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
+  if (my_fstat(my_fileno(cnf_file), &file_stat, MYF(0)))
     goto malloc_err;
 
   if (option && option_value)
@@ -215,7 +215,7 @@ int modify_defaults_file(const char *fil
   if (opt_applied)
   {
     /* Don't write the file if there are no changes to be made */
-    if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
+    if (my_chsize(my_fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
                   MYF(MY_WME)) ||
         my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
         my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),

=== modified file 'mysys/my_chsize.c'
--- a/mysys/my_chsize.c	2007-05-10 09:59:39 +0000
+++ b/mysys/my_chsize.c	2008-06-03 23:08:38 +0000
@@ -52,19 +52,16 @@ int my_chsize(File fd, my_off_t newlengt
 
   if (oldsize > newlength)
   {
-#if defined(HAVE_SETFILEPOINTER)
-  /* This is for the moment only true on windows */
-    long is_success;
-    HANDLE win_file= (HANDLE) _get_osfhandle(fd);
-    long length_low, length_high;
-    length_low= (long) (ulong) newlength;
-    length_high= (long) ((ulonglong) newlength >> 32);
-    is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
-    if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
+#ifdef __WIN__
+    HANDLE win_file= (HANDLE) my_get_osfhandle(fd);
+    LARGE_INTEGER length;
+    length.QuadPart = newlength;
+    if(!SetFilePointerEx(win_file, length , NULL , FILE_BEGIN))
       goto err;
     if (SetEndOfFile(win_file))
       DBUG_RETURN(0);
-    my_errno= GetLastError();
+    my_osmaperr(GetLastError());
+    my_errno= errno;
     goto err;
 #elif defined(HAVE_FTRUNCATE)
     if (ftruncate(fd, (off_t) newlength))

=== modified file 'mysys/my_div.c'
--- a/mysys/my_div.c	2007-05-10 09:59:39 +0000
+++ b/mysys/my_div.c	2008-06-03 23:08:38 +0000
@@ -28,7 +28,7 @@ char * my_filename(File fd)
   DBUG_ENTER("my_filename");
   if ((uint) fd >= (uint) my_file_limit)
     DBUG_RETURN((char*) "UNKNOWN");
-  if (fd >= 0 && my_file_info[fd].type != UNOPEN)
+  if (fd >= MY_FILE_MIN && my_file_info[fd].type != UNOPEN)
   {
     DBUG_RETURN(my_file_info[fd].name);
   }

=== modified file 'mysys/my_file.c'
--- a/mysys/my_file.c	2006-12-23 19:20:40 +0000
+++ b/mysys/my_file.c	2008-06-03 23:08:38 +0000
@@ -97,6 +97,7 @@ uint my_set_max_open_files(uint files)
   DBUG_ENTER("my_set_max_open_files");
   DBUG_PRINT("enter",("files: %u  my_file_limit: %u", files, my_file_limit));
 
+  files += MY_FILE_MIN;
   files= set_max_open_files(min(files, OS_FILE_LIMIT));
   if (files <= MY_NFILE)
     DBUG_RETURN(files);

=== modified file 'mysys/my_fopen.c'
--- a/mysys/my_fopen.c	2008-03-27 18:40:00 +0000
+++ b/mysys/my_fopen.c	2008-06-03 23:08:38 +0000
@@ -17,6 +17,7 @@
 #include "my_static.h"
 #include <errno.h>
 #include "mysys_err.h"
+#include <my_sys.h>
 
 static void make_ftype(char * to,int flag);
 
@@ -66,18 +67,27 @@ FILE *my_fopen(const char *filename, int
       on some OS (SUNOS). Actually the filename save isn't that important
       so we can ignore if this doesn't work.
     */
-    if ((uint) fileno(fd) >= my_file_limit)
+    int filedesc;
+#ifndef __WIN__
+    filedesc = my_fileno(fd);
+    if ((uint)filedesc >= my_file_limit)
     {
       thread_safe_increment(my_stream_opened,&THR_LOCK_open);
       DBUG_RETURN(fd);				/* safeguard */
     }
+#else
+    filedesc = my_open_osfhandle((HANDLE)_get_osfhandle(fileno(fd)), flags);
+    if(filedesc < 0)
+      DBUG_RETURN(NULL);
+
+#endif
     pthread_mutex_lock(&THR_LOCK_open);
-    if ((my_file_info[fileno(fd)].name = (char*)
+    if ((my_file_info[filedesc].name = (char*)
 	 my_strdup(filename,MyFlags)))
     {
       my_stream_opened++;
       my_file_total_opened++;
-      my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
+      my_file_info[filedesc].type = STREAM_BY_FOPEN;
       pthread_mutex_unlock(&THR_LOCK_open);
       DBUG_PRINT("exit",("stream: %p", fd));
       DBUG_RETURN(fd);
@@ -97,8 +107,8 @@ FILE *my_fopen(const char *filename, int
 } /* my_fopen */
 
 
-	/* Close a stream */
 
+/* Close a stream */
 int my_fclose(FILE *fd, myf MyFlags)
 {
   int err,file;
@@ -106,7 +116,7 @@ int my_fclose(FILE *fd, myf MyFlags)
   DBUG_PRINT("my",("stream: %p  MyFlags: %d", fd, MyFlags));
 
   pthread_mutex_lock(&THR_LOCK_open);
-  file=fileno(fd);
+  file= my_fileno(fd);
   if ((err = fclose(fd)) < 0)
   {
     my_errno=errno;
@@ -138,7 +148,19 @@ FILE *my_fdopen(File Filedes, const char
 		   Filedes, Flags, MyFlags));
 
   make_ftype(type,Flags);
-  if ((fd = fdopen(Filedes, type)) == 0)
+#ifndef __WIN__
+  fd = fdopen(Filedes, type);
+#else
+  {
+    /* Convert OS file handle to CRT file descriptor and then call fdopen*/
+    int crt_fd = _open_osfhandle((intptr_t)my_get_osfhandle(Filedes), Flags);
+    if(crt_fd < 0)
+      fd = 0;
+    else
+      fd = fdopen(crt_fd, type);
+  }
+#endif
+  if(!fd)
   {
     my_errno=errno;
     if (MyFlags & (MY_FAE | MY_WME))

=== modified file 'mysys/my_fstream.c'
--- a/mysys/my_fstream.c	2008-04-09 01:07:00 +0000
+++ b/mysys/my_fstream.c	2008-06-03 23:08:38 +0000
@@ -56,11 +56,11 @@ size_t my_fread(FILE *stream, uchar *Buf
     {
       if (ferror(stream))
 	my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
-		 my_filename(fileno(stream)),errno);
+		 my_filename(my_fileno(stream)),errno);
       else
       if (MyFlags & (MY_NABP | MY_FNABP))
 	my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
-		 my_filename(fileno(stream)),errno);
+		 my_filename(my_fileno(stream)),errno);
     }
     my_errno=errno ? errno : -1;
     if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
@@ -144,7 +144,7 @@ size_t my_fwrite(FILE *stream, const uch
 	if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
 	{
 	  my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
-		   my_filename(fileno(stream)),errno);
+		   my_filename(my_fileno(stream)),errno);
 	}
 	writtenbytes= (size_t) -1;        /* Return that we got error */
 	break;
@@ -184,3 +184,53 @@ my_off_t my_ftell(FILE *stream, myf MyFl
   DBUG_PRINT("exit",("ftell: %lu",(ulong) pos));
   DBUG_RETURN((my_off_t) pos);
 } /* my_ftell */
+
+#ifdef __WIN__
+/* Get internal 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");
+  DBUG_PRINT("my",("stream: %p", stream));
+
+  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);
+}
+#endif
+
+/* Get a File corresponding to the stream*/
+int my_fileno(FILE *f)
+{
+#ifndef __WIN__
+  return fileno(f);
+#else
+  HANDLE handle= (HANDLE)_get_osfhandle(fileno(f));
+  int retval= -1;
+  uint i;
+  pthread_mutex_lock(&THR_LOCK_open);
+  for(i= MY_FILE_MIN; i < my_file_limit; i++)
+  {
+    if(my_file_info[i].fhandle == handle)
+    {
+     retval = i;
+     break;
+    }
+  }
+  pthread_mutex_unlock(&THR_LOCK_open);
+  if(retval == -1)
+    /* try std stream */
+    return my_get_stdfile_descriptor(f);
+  return retval;
+#endif
+}

=== modified file 'mysys/my_lib.c'
--- a/mysys/my_lib.c	2008-04-09 01:07:00 +0000
+++ b/mysys/my_lib.c	2008-06-03 23:08:38 +0000
@@ -514,12 +514,54 @@ error:
 ** Note that MY_STAT is assumed to be same as struct stat
 ****************************************************************************/ 
 
-int my_fstat(int Filedes, MY_STAT *stat_area,
+#ifdef __WIN__
+/*
+  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)
+*/
+static int win_fstat(HANDLE hFile, MY_STAT *stat_area)
+{
+  int crt_fd;
+  int retval;
+  HANDLE hDup;
+
+  DBUG_ENTER("win_fstat");
+  DBUG_PRINT("my",("hFile: %p",hFile));
+  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, stat_area);
+  if(retval > 0)
+  {
+    /* File size returned by stat is not accurate (may be outdated), correct it*/
+    GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(stat_area->st_size)));
+  }
+  _close(crt_fd);
+  DBUG_RETURN(retval);
+}
+#endif
+
+int my_fstat(File Filedes, MY_STAT *stat_area,
              myf MyFlags __attribute__((unused)))
 {
   DBUG_ENTER("my_fstat");
   DBUG_PRINT("my",("fd: %d  MyFlags: %d", Filedes, MyFlags));
+#ifndef __WIN__
   DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
+#else
+  {
+    HANDLE hFile = my_get_osfhandle(Filedes);
+    DBUG_RETURN(win_fstat(hFile, stat_area));
+  }
+#endif
 }
 
 
@@ -533,9 +575,24 @@ MY_STAT *my_stat(const char *path, MY_ST
   if ((m_used= (stat_area == NULL)))
     if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
       goto error;
-  if (! stat((char *) path, (struct stat *) stat_area) )
+#ifndef __WIN__
+    if (! _stati64((char *) path, (struct stat *) stat_area) )
+      DBUG_RETURN(stat_area);
+#else
+  if(!_stati64((char *) path,  stat_area) )
+  {
+    /* File size returned by stat is not accurate (may be outdated), correct it*/
+    WIN32_FILE_ATTRIBUTE_DATA data;
+    if (GetFileAttributesEx(path, GetFileExInfoStandard, &data))
+    {
+      LARGE_INTEGER li;
+      li.LowPart  = data.nFileSizeLow;
+      li.HighPart = data.nFileSizeHigh;
+      stat_area->st_size = li.QuadPart;
+    }
     DBUG_RETURN(stat_area);
-
+  }
+#endif
   DBUG_PRINT("error",("Got errno: %d from stat", errno));
   my_errno= errno;
   if (m_used)					/* Free if new area */

=== modified file 'mysys/my_lock.c'
--- a/mysys/my_lock.c	2008-02-01 12:04:32 +0000
+++ b/mysys/my_lock.c	2008-06-03 23:08:38 +0000
@@ -107,7 +107,7 @@ int my_lock(File fd, int locktype, my_of
     LARGE_INTEGER liOffset,liLength;
     DWORD dwFlags;
     OVERLAPPED ov= {0};
-    HANDLE hFile= (HANDLE)_get_osfhandle(fd);
+    HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
 
     lastError= 0;
 

=== modified file 'mysys/my_mmap.c'
--- a/mysys/my_mmap.c	2006-12-23 19:20:40 +0000
+++ b/mysys/my_mmap.c	2008-06-03 23:08:38 +0000
@@ -33,11 +33,11 @@ static SECURITY_ATTRIBUTES mmap_security
   {sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
 
 void *my_mmap(void *addr, size_t len, int prot,
-               int flags, int fd, my_off_t offset)
+               int flags, File fd, my_off_t offset)
 {
   HANDLE hFileMap;
   LPVOID ptr;
-  HANDLE hFile= (HANDLE)_get_osfhandle(fd);
+  HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
   if (hFile == INVALID_HANDLE_VALUE)
     return MAP_FAILED;
 

=== modified file 'mysys/my_open.c'
--- a/mysys/my_open.c	2008-04-08 01:47:13 +0000
+++ b/mysys/my_open.c	2008-06-03 23:08:38 +0000
@@ -94,10 +94,20 @@ int my_close(File fd, myf MyFlags)
   DBUG_PRINT("my",("fd: %d  MyFlags: %d",fd, MyFlags));
 
   pthread_mutex_lock(&THR_LOCK_open);
+#ifndef __WIN__
   do
   {
     err= close(fd);
   } while (err == -1 && errno == EINTR);
+#else
+  if(!CloseHandle(my_get_osfhandle(fd)))
+  {
+    err = -1;
+    my_osmaperr(GetLastError());
+  }
+  else
+    err = 0;
+#endif
 
   if (err)
   {
@@ -141,7 +151,7 @@ File my_register_filename(File fd, const
 			  type_of_file, uint error_message_number, myf MyFlags)
 {
   DBUG_ENTER("my_register_filename");
-  if ((int) fd >= 0)
+  if ((int) fd >= MY_FILE_MIN)
   {
     if ((uint) fd >= my_file_limit)
     {
@@ -159,7 +169,7 @@ File my_register_filename(File fd, const
       {
         my_file_opened++;
         my_file_total_opened++;
-        my_file_info[fd].type = type_of_file;
+        my_file_info[fd].type= type_of_file;
 #if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
         pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
 #endif
@@ -189,7 +199,40 @@ File my_register_filename(File fd, const
 
 #ifdef __WIN__
 
-extern void __cdecl _dosmaperr(unsigned long);
+File my_open_osfhandle(HANDLE handle, int oflag)
+{
+  int offset= -1;
+  uint i;
+  pthread_mutex_lock(&THR_LOCK_open);
+  for(i= MY_FILE_MIN; i < my_file_limit;i++)
+  {
+    if(my_file_info[i].type == UNOPEN)
+    {
+      struct st_my_file_info *finfo = &(my_file_info[i]);
+      finfo->type=    FILE_BY_OPEN;
+      finfo->fhandle= handle;
+      finfo->oflag=   oflag;
+      offset = i;
+      break;
+    }
+  }
+  pthread_mutex_unlock(&THR_LOCK_open);
+  return offset;
+}
+
+
+HANDLE my_get_osfhandle(File fd)
+{
+  DBUG_ASSERT( fd >= MY_FILE_MIN && fd < my_file_limit);
+  return my_file_info[fd].fhandle;
+}
+
+int my_get_open_flags(File fd)
+{
+  DBUG_ASSERT( fd >= MY_FILE_MIN && fd < my_file_limit);
+  return my_file_info[fd].oflag;
+}
+
 
 /*
   Open a file with sharing. Similar to _sopen() from libc, but allows managing
@@ -355,14 +398,14 @@ File my_sopen(const char *path, int ofla
      * the lock, and return -1. note that it's not necessary to
      * call _free_osfhnd (it hasn't been used yet).
      */
-    _dosmaperr(GetLastError());     /* map error */
+    my_osmaperr(GetLastError());     /* map error */
     return -1;                      /* return error to caller */
   }
 
-  if ((fh= _open_osfhandle((intptr_t)osfh, 
+  if ((fh= my_open_osfhandle(osfh, 
                            oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
   {
-    _dosmaperr(GetLastError());     /* map error */
+    my_osmaperr(GetLastError());     /* map error */
     CloseHandle(osfh);
   }
 

=== modified file 'mysys/my_pread.c'
--- a/mysys/my_pread.c	2008-04-25 16:43:25 +0000
+++ b/mysys/my_pread.c	2008-06-03 23:08:38 +0000
@@ -21,7 +21,7 @@
 #endif
 
 #ifdef __WIN__
-extern void  _dosmaperr(DWORD);
+
 
 /*
   Positional read and write on Windows.
@@ -45,7 +45,7 @@ static size_t pread(File Filedes, uchar 
     Count = UINT_MAX;
 #endif
 
-  hFile=         (HANDLE)_get_osfhandle(Filedes);
+  hFile=         (HANDLE)my_get_osfhandle(Filedes);
   li.QuadPart=   offset;
   ov.Offset=     li.LowPart;
   ov.OffsetHigh= li.HighPart;
@@ -55,7 +55,7 @@ static size_t pread(File Filedes, uchar 
     DWORD lastError = GetLastError();
     if(lastError == ERROR_HANDLE_EOF)
        return 0; /*return 0 at EOF*/
-    _dosmaperr(lastError);
+    my_osmaperr(lastError);
     return -1;
   }
   else
@@ -77,14 +77,14 @@ static size_t pwrite(File Filedes, const
     Count = UINT_MAX;
 #endif
 
-  hFile=         (HANDLE)_get_osfhandle(Filedes);
+  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))
   {
-    _dosmaperr(GetLastError());
+    my_osmaperr(GetLastError());
     return -1;
   }
   else
@@ -189,7 +189,7 @@ size_t my_pread(File Filedes, uchar *Buf
     #             Number of bytes read
 */
 
-size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
+size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count,
                  my_off_t offset, myf MyFlags)
 {
   size_t writenbytes, written;

=== modified file 'mysys/my_quick.c'
--- a/mysys/my_quick.c	2007-06-21 08:13:10 +0000
+++ b/mysys/my_quick.c	2008-06-03 23:08:38 +0000
@@ -19,11 +19,19 @@
 #include "my_nosys.h"
 
 
+#ifdef __WIN__
+extern size_t my_win_read(File Filedes,uchar *Buffer,size_t Count);
+#endif
+
 size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
 {
   size_t readbytes;
-
-  if ((readbytes = read(Filedes, Buffer, Count)) != Count)
+#ifdef __WIN__
+  readbytes = my_win_read(Filedes, Buffer, Count);
+#else
+  readbytes = read(Filedes, Buffer, Count);
+#endif
+  if(readbytes != Count)
   {
 #ifndef DBUG_OFF
     if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
@@ -39,10 +47,17 @@ size_t my_quick_read(File Filedes,uchar 
   return (MyFlags & (MY_NABP | MY_FNABP)) ? 0 : readbytes;
 }
 
+#ifdef __WIN__
+extern size_t my_win_write(File Filedes,const uchar *Buffer,size_t Count);
+#endif
 
-size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
+size_t my_quick_write(File Filedes, const uchar *Buffer, size_t Count)
 {
-#ifndef DBUG_OFF
+#ifdef __WIN__
+  return my_win_write(Filedes, Buffer, Count);
+#else
+
+#if !defined (DBUG_OFF)
   size_t writtenbytes;
 #endif
 
@@ -64,4 +79,5 @@ size_t my_quick_write(File Filedes,const
     return (size_t) -1;
   }
   return 0;
+#endif
 }

=== modified file 'mysys/my_read.c'
--- a/mysys/my_read.c	2008-03-27 18:40:00 +0000
+++ b/mysys/my_read.c	2008-06-03 23:08:38 +0000
@@ -17,6 +17,22 @@
 #include "mysys_err.h"
 #include <errno.h>
 
+#ifdef __WIN__
+size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
+{
+  DWORD  nRead;
+  size_t readbytes;
+  HANDLE hFile = my_get_osfhandle(Filedes);
+  if (!ReadFile(hFile, Buffer, (DWORD)Count, &nRead, NULL))
+  {
+    my_osmaperr(GetLastError());
+    readbytes = -1;
+  }
+  else
+    readbytes = nRead;
+  return readbytes;
+}
+#endif
 
 /*
   Read a chunk of bytes from a file with retry's if needed
@@ -44,7 +60,13 @@ size_t my_read(File Filedes, uchar *Buff
   for (;;)
   {
     errno= 0;					/* Linux doesn't reset this */
-    if ((readbytes= read(Filedes, Buffer, Count)) != Count)
+#ifdef __WIN__
+    readbytes =  my_win_read(Filedes, Buffer, Count);
+#else
+    readbytes =  read(Filedes, Buffer, Count);
+#endif
+
+    if (readbytes != Count)
     {
       my_errno= errno ? errno : -1;
       DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",

=== modified file 'mysys/my_seek.c'
--- a/mysys/my_seek.c	2008-02-01 12:04:32 +0000
+++ b/mysys/my_seek.c	2008-06-03 23:08:38 +0000
@@ -45,36 +45,43 @@
 my_off_t my_seek(File fd, my_off_t pos, int whence,
 		 myf MyFlags __attribute__((unused)))
 {
-  reg1 os_off_t newpos= -1;
+  os_off_t newpos= -1;
   DBUG_ENTER("my_seek");
-  DBUG_PRINT("my",("Fd: %d  Hpos: %lu  Pos: %lu  Whence: %d  MyFlags: %d",
-		   fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos, 
-		   whence, MyFlags));
+  DBUG_PRINT("my",("Fd: %d Pos: %llu  Whence: %d  MyFlags: %d",
+		   fd, (ulonglong) pos, whence, MyFlags));
   DBUG_ASSERT(pos != MY_FILEPOS_ERROR);		/* safety check */
 
   /*
       Make sure we are using a valid file descriptor!
   */
   DBUG_ASSERT(fd != -1);
-#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
-  if (MyFlags & MY_THREADSAFE)
+#if defined (__WIN__)
+
+  /*Check Windows API seek constants are compatible with posix ones */
+  compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR 
+    && FILE_END == SEEK_END);
+
   {
-    pthread_mutex_lock(&my_file_info[fd].mutex);
-    newpos= lseek(fd, pos, whence);
-    pthread_mutex_unlock(&my_file_info[fd].mutex);
+    LARGE_INTEGER pos1;
+    pos1.QuadPart = pos;
+    if(!SetFilePointerEx(my_get_osfhandle(fd), pos1, (PLARGE_INTEGER) &newpos,
whence))
+    {
+      my_osmaperr(GetLastError());
+      newpos = -1;
+    }
   }
-  else
-#endif
+#else
     newpos= lseek(fd, pos, whence);
+#endif
   if (newpos == (os_off_t) -1)
   {
     my_errno=errno;
-    DBUG_PRINT("error",("lseek: %lu  errno: %d", (ulong) newpos,errno));
+    DBUG_PRINT("error",("lseek: %llu  errno: %d", (ulonglong) newpos,errno));
     DBUG_RETURN(MY_FILEPOS_ERROR);
   }
   if ((my_off_t) newpos != pos)
   {
-    DBUG_PRINT("exit",("pos: %lu", (ulong) newpos));
+    DBUG_PRINT("exit",("pos: %llu", (ulonglong) newpos));
   }
   DBUG_RETURN((my_off_t) newpos);
 } /* my_seek */
@@ -89,13 +96,13 @@ my_off_t my_tell(File fd, myf MyFlags __
   DBUG_ENTER("my_tell");
   DBUG_PRINT("my",("Fd: %d  MyFlags: %d",fd, MyFlags));
   DBUG_ASSERT(fd >= 0);
-#ifdef HAVE_TELL
+#if defined (HAVE_TELL) && !defined (__WIN__)
   pos=tell(fd);
 #else
-  pos=lseek(fd, 0L, MY_SEEK_CUR);
+  pos=my_seek(fd, 0L, MY_SEEK_CUR,0);
 #endif
   if (pos == (os_off_t) -1)
     my_errno=errno;
-  DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
+  DBUG_PRINT("exit",("pos: %llu", (ulonglong) pos));
   DBUG_RETURN((my_off_t) pos);
 } /* my_tell */

=== modified file 'mysys/my_static.c'
--- a/mysys/my_static.c	2008-04-08 15:32:47 +0000
+++ b/mysys/my_static.c	2008-06-03 23:08:38 +0000
@@ -35,7 +35,7 @@ int		NEAR my_umask=0664, NEAR my_umask_d
 #ifndef THREAD
 int		NEAR my_errno=0;
 #endif
-struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}};
+struct st_my_file_info my_file_info_default[MY_NFILE];
 uint   my_file_limit= MY_NFILE;
 struct st_my_file_info *my_file_info= my_file_info_default;
 

=== modified file 'mysys/my_sync.c'
--- a/mysys/my_sync.c	2007-10-11 15:07:40 +0000
+++ b/mysys/my_sync.c	2008-06-03 23:08:38 +0000
@@ -63,7 +63,14 @@ int my_sync(File fd, myf my_flags)
 #elif defined(HAVE_FSYNC)
     res= fsync(fd);
 #elif defined(__WIN__)
-    res= _commit(fd);
+    res = 0;
+    if(FlushFileBuffers(my_get_osfhandle(fd)))
+      res= 0;
+    else
+    {
+      my_osmaperr(GetLastError());
+      res = -1;
+    }
 #else
 #error Cannot find a way to sync a file, durability in danger
     res= 0;					/* No sync (strange OS) */

=== added file 'mysys/my_winerr.c'
--- a/mysys/my_winerr.c	1970-01-01 00:00:00 +0000
+++ b/mysys/my_winerr.c	2008-06-03 23:08:38 +0000
@@ -0,0 +1,123 @@
+/* Copyright (C) 2008 MySQL AB
+
+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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/*
+  Convert Windows API error (GetLastError() to Posix equivalent (errno)
+  The exported function  my_osmaperr() is modelled after and borrows
+  heavily from undocumented _dosmaperr()(found of the static Microsoft C runtime).
+*/
+
+#include <my_global.h>
+#include <my_sys.h>
+
+
+struct errentry 
+{
+  unsigned long oscode;   /* OS return value */
+  int errnocode;  /* System V error code */
+};
+
+static struct errentry errtable[] = {
+  {  ERROR_INVALID_FUNCTION,       EINVAL    },  /* 1 */
+  {  ERROR_FILE_NOT_FOUND,         ENOENT    },  /* 2 */
+  {  ERROR_PATH_NOT_FOUND,         ENOENT    },  /* 3 */
+  {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },  /* 4 */
+  {  ERROR_ACCESS_DENIED,          EACCES    },  /* 5 */
+  {  ERROR_INVALID_HANDLE,         EBADF     },  /* 6 */
+  {  ERROR_ARENA_TRASHED,          ENOMEM    },  /* 7 */
+  {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },  /* 8 */
+  {  ERROR_INVALID_BLOCK,          ENOMEM    },  /* 9 */
+  {  ERROR_BAD_ENVIRONMENT,        E2BIG     },  /* 10 */
+  {  ERROR_BAD_FORMAT,             ENOEXEC   },  /* 11 */
+  {  ERROR_INVALID_ACCESS,         EINVAL    },  /* 12 */
+  {  ERROR_INVALID_DATA,           EINVAL    },  /* 13 */
+  {  ERROR_INVALID_DRIVE,          ENOENT    },  /* 15 */
+  {  ERROR_CURRENT_DIRECTORY,      EACCES    },  /* 16 */
+  {  ERROR_NOT_SAME_DEVICE,        EXDEV     },  /* 17 */
+  {  ERROR_NO_MORE_FILES,          ENOENT    },  /* 18 */
+  {  ERROR_LOCK_VIOLATION,         EACCES    },  /* 33 */
+  {  ERROR_BAD_NETPATH,            ENOENT    },  /* 53 */
+  {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },  /* 65 */
+  {  ERROR_BAD_NET_NAME,           ENOENT    },  /* 67 */
+  {  ERROR_FILE_EXISTS,            EEXIST    },  /* 80 */
+  {  ERROR_CANNOT_MAKE,            EACCES    },  /* 82 */
+  {  ERROR_FAIL_I24,               EACCES    },  /* 83 */
+  {  ERROR_INVALID_PARAMETER,      EINVAL    },  /* 87 */
+  {  ERROR_NO_PROC_SLOTS,          EAGAIN    },  /* 89 */
+  {  ERROR_DRIVE_LOCKED,           EACCES    },  /* 108 */
+  {  ERROR_BROKEN_PIPE,            EPIPE     },  /* 109 */
+  {  ERROR_DISK_FULL,              ENOSPC    },  /* 112 */
+  {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },  /* 114 */
+  {  ERROR_INVALID_HANDLE,         EINVAL    },  /* 124 */
+  {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },  /* 128 */
+  {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },  /* 129 */
+  {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },  /* 130 */
+  {  ERROR_NEGATIVE_SEEK,          EINVAL    },  /* 131 */
+  {  ERROR_SEEK_ON_DEVICE,         EACCES    },  /* 132 */
+  {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },  /* 145 */
+  {  ERROR_NOT_LOCKED,             EACCES    },  /* 158 */
+  {  ERROR_BAD_PATHNAME,           ENOENT    },  /* 161 */
+  {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },  /* 164 */
+  {  ERROR_LOCK_FAILED,            EACCES    },  /* 167 */
+  {  ERROR_ALREADY_EXISTS,         EEXIST    },  /* 183 */
+  {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },  /* 206 */
+  {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },  /* 215 */
+  {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }    /* 1816 */
+};
+
+/* size of the table */
+#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))
+
+/* The following two constants must be the minimum and maximum
+values in the (contiguous) range of Exec Failure errors. */
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
+
+/* These are the low and high value in the range of errors that are
+access violations */
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
+
+
+static int get_errno_from_oserr(unsigned long oserrno)
+{
+  int i;
+
+  /* check the table for the OS error code */
+  for (i = 0; i < ERRTABLESIZE; ++i) 
+  {
+    if (oserrno == errtable[i].oscode) 
+    {
+      return  errtable[i].errnocode;
+    }
+  }
+
+  /* The error code wasn't in the table.  We check for a range of */
+  /* EACCES errors or exec failure errors (ENOEXEC).  Otherwise   */
+  /* EINVAL is returned.                                          */
+
+  if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE)
+    return EACCES;
+  else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR)
+    return ENOEXEC;
+  else
+    return EINVAL;
+}
+
+/* Set errno corresponsing to GetLastError() value */
+void my_osmaperr ( unsigned long oserrno)
+{
+    errno = get_errno_from_oserr(oserrno);
+}

=== modified file 'mysys/my_write.c'
--- a/mysys/my_write.c	2008-04-09 01:07:00 +0000
+++ b/mysys/my_write.c	2008-06-03 23:08:38 +0000
@@ -18,9 +18,40 @@
 #include <errno.h>
 
 
+#ifdef __WIN__
+#ifndef FILE_WRITE_TO_END_OF_FILE
+#define FILE_WRITE_TO_END_OF_FILE       0xffffffff
+#endif
+
+size_t my_win_write(File Filedes, const uchar *Buffer, size_t Count)
+{
+  DWORD nWritten;
+  OVERLAPPED ov;
+  OVERLAPPED *pov = NULL;
+  HANDLE hFile;
+
+  if(my_get_open_flags(Filedes) & _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(Filedes);
+  if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov))
+  {
+    nWritten  = (size_t)-1;
+    my_osmaperr(GetLastError());
+  }
+  return (size_t)nWritten;
+}
+#endif
 	/* Write a chunk of bytes to a file */
 
-size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
+size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
 {
   size_t writenbytes, written;
   uint errors;
@@ -35,8 +66,14 @@ size_t my_write(int Filedes, const uchar
   
   for (;;)
   {
+#ifdef __WIN__
+    if ((writenbytes= my_win_write(Filedes, Buffer, Count)) == Count)
+      break;
+#else
     if ((writenbytes= write(Filedes, Buffer, Count)) == Count)
       break;
+#endif
+
     if (writenbytes != (size_t) -1)
     {						/* Safeguard */
       written+=writenbytes;

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2008-05-08 20:43:28 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2008-06-03 23:08:38 +0000
@@ -874,7 +874,29 @@ innobase_mysql_tmpfile(void)
 		will be passed to fdopen(), it will be closed by invoking
 		fclose(), which in turn will invoke close() instead of
 		my_close(). */
+
+#ifdef _WIN32
+		/* Note that on Windows, the integer returned by mysql_tmpfile 
+		has no relation to C runtime file descriptor. Here, we need 
+		to call my_get_osfhandle to get the HANDLE and then convert it 
+		to C runtime filedescriptor. */
+		{
+			HANDLE hFile = my_get_osfhandle(fd);
+			HANDLE hDup;
+			BOOL bOK = 
+				DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+								&hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+			if(bOK) {
+				fd2 = _open_osfhandle((intptr_t)hDup,0);
+			}
+			else {
+				my_osmaperr(GetLastError());
+				fd2 = -1;
+			}	
+		}
+#else
 		fd2 = dup(fd);
+#endif
 		if (fd2 < 0) {
 			DBUG_PRINT("error",("Got error %d on dup",fd2));
 			my_errno=errno;

=== modified file 'storage/myisam/mi_locking.c'
--- a/storage/myisam/mi_locking.c	2008-04-09 01:07:00 +0000
+++ b/storage/myisam/mi_locking.c	2008-06-03 23:08:38 +0000
@@ -460,8 +460,8 @@ int _mi_writeinfo(register MI_INFO *info
 #ifdef __WIN__
       if (myisam_flush)
       {
-	_commit(share->kfile);
-	_commit(info->dfile);
+	my_sync(share->kfile,0);
+	my_sync(info->dfile,0);
       }
 #endif
     }

Thread
commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653) Bug#24509,WL#3049Vladislav Vaintroub4 Jun
  • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Davi Arnaut4 Jun
    • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch(vvaintroub:2653) Bug#24509, WL#3049Konstantin Osipov4 Jun
    • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Joerg Bruehe4 Jun
      • RE: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653) Bug#24509, WL#3049Vladislav Vaintroub4 Jun
        • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Davi Arnaut4 Jun
          • RE: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653) Bug#24509, WL#3049Vladislav Vaintroub4 Jun
            • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Davi Arnaut4 Jun
        • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Joerg Bruehe4 Jun
          • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049 [ifdefery]Davi Arnaut5 Jun
      • Re: commit into mysql-6.0-wtf:mysql-6.0-wtf branch (vvaintroub:2653)Bug#24509, WL#3049Davi Arnaut4 Jun