Error in wine's implementation of msvcrt

David D. Hagood wowbagger at sktc.net
Sun Nov 6 19:22:56 CST 2005


Uwe Bonnes wrote:
> Run with
> WINEDEBUG=+relay,+snoop WINEDLLOVERRIDES=msvcrt=n wine <your.program>
> and
> WINEDEBUG=+relay,+snoop,+msvcrt WINEDLLOVERRIDES=msvcrt=b wine <your.program>
> and compare how the msvcrt calls are handled step by step. Tedious, but
> promising...
>  
Tedious, but productive. Wine's fgets does not behave as does 
Microsoft's on EOF:

The Microsoft version:
// This is the read of the last line
MSVCRT.fgets(7fa3f8e0,00000050,78034ca8) ret=7f5f4e12
000d:RET  MSVCRT.fgets() retval=7fa3f8e0 ret=7f5f4e12
000d:CALL MSVCRT.strlen(7fa3f8e0) ret=7f5f4e68
000d:RET  MSVCRT.strlen() retval=0000001b ret=7f5f4e68
// This is the read of EOF
000d:CALL MSVCRT.fgets(7fa3f96c,00000050,78034ca8) ret=7f5f4cc2
000d:RET  MSVCRT.fgets() retval=00000000 ret=7f5f4cc2
// Notice the fgets returns NULL.
000d:CALL MSVCRT.fclose(78034ca8) ret=7f5f4dc6
// OK, done with file, close and clean up.
000d:RET  MSVCRT.fclose() retval=00000000 ret=7f5f4dc6

And the WINE version
// Again - the gets of the last line
msvcrt.fgets(7fa3f8e0,00000050,7fe04ff8) ret=7f594e12
trace:msvcrt:MSVCRT_fgets :file(0x7fe04ff8) fd (4) str (0x7fa3f8e0) len (80)
trace:msvcrt:MSVCRT_fgets :got "1a 2b 4c 6c 7b 7a 68 67 75\n"
000b:Ret  msvcrt.fgets() retval=7fa3f8e0 ret=7f594e12
000b:Call msvcrt.strlen(7fa3f8e0 "1a 2b 4c 6c 7b 7a 68 67 75\n") 
ret=7f594e68
000b:Ret  msvcrt.strlen() retval=0000001b ret=7f594e68
// This is the gets of EOF
000b:Call msvcrt.fgets(7fa3f96c,00000050,7fe04ff8) ret=7f594cc2
trace:msvcrt:MSVCRT_fgets :file(0x7fe04ff8) fd (4) str (0x7fa3f96c) len (80)
trace:msvcrt:_read :fd (4) handle (0xb8) buf (0x7fe07e40) len (512)
// Yup - EOF
trace:msvcrt:_read :EOF
trace:msvcrt:_read ""...
// Gets thinks it got a CTRL-Z
trace:msvcrt:MSVCRT_fgets :got "\x1a"
// Gets therefor returns that
000b:Ret  msvcrt.fgets() retval=7fa3f96c ret=7f594cc2
000b:Call msvcrt.fclose(7fe04ff8) ret=7f594d7a
trace:msvcrt:_close :fd (4) handle (0xb8)
trace:msvcrt:msvcrt_free_fd :fd (4) freed
trace:msvcrt:_close :ok
000b:Ret  msvcrt.fclose() retval=00000000 ret=7f594d7a
// The program says WTF?
000b:Call msvcrt.vsprintf(7fa3f8c4,7f5d5664 "Error loading

The file in question has an old-style DOS 0x1A at the end of file - 
evidently the MS version of MSVCRT removes any CTRL-Z at EOF.

I've attached a patch that corrects the problem.

Changelog

dlls/msvcrt/file.c David Hagood (wowbagger at sktc.net)
When reading a file in text mode, remove any old-style DOS
EOF characters (CTRL-Z) from the end of file.

-------------- next part --------------
Index: dlls/msvcrt/file.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/file.c,v
retrieving revision 1.91
diff -u -r1.91 file.c
--- dlls/msvcrt/file.c	7 Oct 2005 15:01:15 -0000	1.91
+++ dlls/msvcrt/file.c	7 Nov 2005 01:15:55 -0000
@@ -1657,7 +1657,16 @@
               TRACE(":EOF\n");
               MSVCRT_fdesc[fd].wxflag |= WX_ATEOF;
               if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
+              {
                   num_read -= remove_cr(bufstart+all_read,num_read);
+                  /* we also need to remove any CTRL-Z at EOF */
+                  while (num_read && (bufstart[all_read+num_read-1] == 0x1a))
+                  {
+                     TRACE("Removing CTRL-Z from EOF\n");
+                     bufstart[all_read+num_read-1] = 0;
+                     num_read --;
+                  }
+              }
               all_read += num_read;
               if (count > 4)
                   TRACE("%s\n",debugstr_an(buf,all_read));
                   


More information about the wine-devel mailing list