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