Project

General

Profile

Bug #11172

Updated by naruse (Yui NARUSE) almost 9 years ago

Windowsでopen("hoge.txt", "ab+")すると、開いたファイルの既存の内容が読めません。 
 File::APPEND|File::CREAT|File::RDWR|File::BINARYでも同様です。 

 Unixでは読める上に、a+の時、つまり_openを使う場合も読めるので、意図しない挙動でしょう。 

 ``` 
 diff --git a/win32/win32.c b/win32/win32.c 
 index 55e0d2e..57d9df4 100644 
 --- a/win32/win32.c 
 +++ b/win32/win32.c 
 @@ -6476,12 +6476,16 @@ rb_w32_close(int fd) 
  } 
 
  static int 
 -setup_overlapped(OVERLAPPED *ol, int fd) 
 +setup_overlapped(OVERLAPPED *ol, int fd, int iswrite) 
  { 
      memset(ol, 0, sizeof(*ol)); 
      if (!(_osfile(fd) & (FDEV | FPIPE))) { 
 	 LONG high = 0; 
 - 	 DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT; 
 + 	 /* On mode:a, it can write only FILE_END. 
 + 	  * On mode:a+, though it can write only FILE_END, 
 + 	  * it can read from everywhere. 
 + 	  */ 
 + 	 DWORD method = ((_osfile(fd) & FAPPEND) && iswrite) ? FILE_END : FILE_CURRENT; 
 	 DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method); 
  #ifndef INVALID_SET_FILE_POINTER 
  #define INVALID_SET_FILE_POINTER ((DWORD)-1) 
 @@ -6578,7 +6582,7 @@ rb_w32_read(int fd, void *buf, size_t size) 
 
      /* if have cancel_io, use Overlapped I/O */ 
      if (cancel_io) { 
 - 	 if (setup_overlapped(&ol, fd)) { 
 + 	 if (setup_overlapped(&ol, fd, FALSE)) { 
 	     rb_acrt_lowio_unlock_fh(fd); 
 	     return -1; 
 	 } 
 @@ -6708,7 +6712,7 @@ rb_w32_write(int fd, const void *buf, size_t size) 
 
      /* if have cancel_io, use Overlapped I/O */ 
      if (cancel_io) { 
 - 	 if (setup_overlapped(&ol, fd)) { 
 + 	 if (setup_overlapped(&ol, fd, TRUE)) { 
 	     rb_acrt_lowio_unlock_fh(fd); 
 	     return -1; 
 	 } 
 ```

Back