Regards,
Juan M. Guerrero
Reading specs from c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/specs
Configured with: /gnu/gcc-3.44/configure djgpp --prefix=/dev/env/DJDIR --disable-nls --disable-libstdcxx-pch
Thread model: single
gcc version 3.4.4
c:/djgpp-2.04/bin/../libexec/gcc/djgpp/3.44/cc1.exe -quiet -v -iprefix c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/ -remap -imacros c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/djgpp.ver 1.c -quiet -dumpbase 1.c -mtune=pentium -auxbase 1 -version -o C:/TMP/cc9lZmUB.s
ignoring nonexistent directory "c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/../../../../djgpp/include"
ignoring nonexistent directory "c:/djgpp-2.04/djgpp/include/"
#include "..." search starts here:
#include <...> search starts here:
c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/include
c:/djgpp-2.04/lib/gcc/djgpp/3.44/include/
c:/djgpp-2.04/include/
End of search list.
GNU C version 3.4.4 (djgpp)
compiled by GNU C version 3.4.4.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
cc1.exe: c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/djgpp.ver: Value too large (EOVERFLOW)
1.c:1:19: c:/djgpp-2.04/include/stdio.h: Value too large (EOVERFLOW)
Can you find out where did this error message come from? Which system
call or library function emits EOVERFLOW?
The functions generating EOVERFLOW are filelength() and lfilelength(). Both of
them usefunction 0x7A46 to get the file size if LFN support is available. But I
assume that neither MSDOS nor DOSLFN provide the required function. May we
need to disind a better to certainly identify the OS used.
Regards,
Juan M. Guerrero
On Aug 31, 2:17 pm, Juan Manuel Guerrero <juan.guerr...@gmx.de> wrote:
> Am Mittwoch, 31. August 2011 schrieb Eli Zaretskii:
>
> > > From: Juan Manuel Guerrero <juan.guerr...@gmx.de>
> > > Date: Wed, 31 Aug 2011 00:27:21 +0200
>
> > > cc1.exe: c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/djgpp.ver: Value too large (EOVERFLOW)
> > > 1.c:1:19: c:/djgpp-2.04/include/stdio.h: Value too large (EOVERFLOW)
>
> > Can you find out where did this error message come from? Which system
> > call or library function emits EOVERFLOW?
>
> The functions generating EOVERFLOW are filelength() and lfilelength(). Both of
> them usefunction 0x7A46 to get the file size if LFN support is available. But I
> assume that neither MSDOS nor DOSLFN provide the required function. May we
> need to disind a better to certainly identify the OS used.
I don't have easy access to MS-DOS 6.22 these days (old 486 is
disconnected, too painful to setup right now, half dead anyways), but
I vaguely remember seeing similar issues.
You could try StarLFN instead, it should work, but no promises how
well. In particular, I can't remember exactly, but you may or may not
have to make the LONGNAME.DAT file not be +H (hidden), at least on
FreeDOS, not sure about MS-DOS. (It also supports direct VFAT access a
la DOSLFN, but I usually avoid that.)
http://sta.c64.org/starlfn.html
starlfn /i
...
starlfn /u
P.S. I didn't write it, obviously, but at one time I did get the crazy
idea to rebuild it with JWasm for 8086, and esp. strip out all the
(unneeded, patented) VFAT crud. Never got around to it, of course.
Still would be worth doing, IMHO. (And it's not hard, just tedious.)
Perhaps we should not fail these library functions if 7A46 returns an
error that translates into EOVERFLOW, but instead invoke the SFN
equivalent.
Could you post the "trivial hello world program"? Or, could you post a
minimal example of code that fails?
If you're sure the problem is DOSLFN, the first thing I'd try is an older
version without Jason Hood's updates. Haftmann's final version, DOSLFN
0.32o, is at the following link, in German, half-way down:
http://www-user.tu-chemnitz.de/~heha/hs_freeware/freew.html
I don't have 6.22 either. I have MS-DOS 7.10 with GCC v3.41, GCC v4.0.1,
DOSLFN 0.32o, DOSLFN 0.40e installed. So, I can test combinations of those,
if needed.
Rod Pemberton
#include<stdio.h>
int main(void)
{
return 0;
}
That is exactly the code that produced the error
message I posted.
> If you're sure the problem is DOSLFN, the first thing I'd try is an older
> version without Jason Hood's updates. Haftmann's final version, DOSLFN
> 0.32o, is at the following link, in German, half-way down:http://www-user.tu-chemnitz.de/~heha/hs_freeware/freew.html
IIRC I downloaded DOSLFN from that link. I will try an older
version ASAP.
OFYI, I have djgpp 2.03 installed on the same partition with the same
MSDOS 6.22 so I can choose if I want to compile with 2.04 or 2.03.
gcc 4.6.1 and djgpp-2.03 work flawlessly.
> I don't have 6.22 either. I have MS-DOS 7.10 with GCC v3.41, GCC v4.0.1,
> DOSLFN 0.32o, DOSLFN 0.40e installed. So, I can test combinations of those,
> if needed.
Regards,
Juan M. Guerrero
I'm wondering if your directories were created or extracted correctly.
> ignoring nonexistent directory
> "c:/djgpp-2.04/bin/../lib/gcc/djgpp/3.44/../../../../djgpp/include"
lib in bin ... ? Why would lib be in bin?
> ignoring nonexistent directory "c:/djgpp-2.04/djgpp/include/"
Is this a problem? Should that include directory should be present? Do you
have an extra "djgpp" in the path? E.g., C:/djgpp-2.04/include
Rod Pemberton
These are both side-effects of the way gcc searches for its libraries
relative to whever it thinks it's being run from.
Wait a minute. Are you saying that the problem is _only_ with GCC
compiled with DJGPP 2.04, and that 2.03-compiled GCC works? I don't
think you said that before.
If you compile with v2.03 a simple program that calls 7A46, and then
run it with DOSLFN, does it also fail?
If so, this is certainly due to the use of 7A46, because in v2.03
`filelength' didn't call that function and `lfilelength' didn't exist
at all.
So I think we need to fix these 2 functions to work around this
problem.
AFAICS, filelength() calls 71A6, not 7A46. (Typo?)
OTOH, filelength() from 2.03 didn't call 71A6 either.
> OTOH, filelength() from 2.03 didn't call 71A6 either.
correct.
Regards,
Juan M. Guerrero
Sorry for having been imprecise. I usualy do not use djgpp 2.03
anymore
so I did not note that the gcc version compiled with 2.03 worked.
Yes, you are right, the problem is only with 2.04's `filelength' and
`lfilelength'.
Both use 71A6 and fail with EOVERFLOW under certain circunstances.
The only thing we need to do is to fix both functions so they work
like
the 2.03 versions if the 71A6 call fails with EOVERFLOW.
Regards,
Juan M. Guerrero
Something like the following then? (Very quick+dirty patch, I know.)
I also wonder whether fchmod() and/or fstat() are affected by this
lfn issue...
Index: src/libc/posix/sys/stat/filelen.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/filelen.c,v
retrieving revision 1.6
diff -u -p -r1.6 filelen.c
--- src/libc/posix/sys/stat/filelen.c 25 Sep 2001 01:00:52 -0000 1.6
+++ src/libc/posix/sys/stat/filelen.c 2 Sep 2011 14:21:13 -0000
@@ -50,13 +50,19 @@ filelength(int fhandle)
if ((_farpeekl(_dos_ds, __tb + 0x20) != 0) || (retval == -1))
{
+ /*
errno = EOVERFLOW;
return -1L;
+ */
+ /* This failure can happen under certain circumstances,
+ e.g. for DOS 6.22 with LFN driver installed. Therefore,
+ fallback to no-lfn way instead of returning error. */
+ goto _nofln;
}
return retval;
}
}
-
+_nofln:
/* Remember the current file position, so we can return there
later. */
regs.x.ax = 0x4201; /* set pointer from current position */
Index: src/libc/posix/sys/stat/lfilelen.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/lfilelen.c,v
retrieving revision 1.3
diff -u -p -r1.3 lfilelen.c
--- src/libc/posix/sys/stat/lfilelen.c 4 Feb 2001 19:13:01 -0000 1.3
+++ src/libc/posix/sys/stat/lfilelen.c 2 Sep 2011 14:21:13 -0000
@@ -45,15 +45,21 @@ lfilelength(int fhandle)
if (retval_h < 0)
{
+ /*
errno = EOVERFLOW;
return -1;
+ */
+ /* This failure can happen under certain circumstances,
+ e.g. for DOS 6.22 with LFN driver installed. Therefore,
+ fallback to no-lfn way instead of returning error. */
+ goto _nofln;
}
retval = retval_l + retval_h * (1LL << 32);
return retval;
}
}
-
+_nofln:
/* Remember the current file position, so we can return there
later. */
regs.x.ax = 0x4201; /* set pointer from current position */
--
O.S.
Yes, thanks. Although it would be better to know whether DOSLFN
returns -1 in offset 0x24 or non-zero in offset 0x20, and have a more
fine-grain recovery here.
> I also wonder whether fchmod() and/or fstat() are affected by this
> lfn issue...
Juan, can you test that?
Okay, I compiled that this way:
gcc -Wall -ansi -pedantic -O2 -o hw.exe hw.c
I'm not seeing any errors with MS-DOS v7.10 ...
works - DJGPP 2.03 GCCv3.4.1 no lfn
works - DJGPP 2.03 GCCv3.4.1 DOSLFN 0.32o
works - DJGPP 2.03 GCCv3.4.1 DOSLFN 0.40e
works - DJGPP 2.04 GCCv4.1.0 no lfn
works - DJGPP 2.04 GCCv4.1.0 DOSLFN 0.32o
works - DJGPP 2.04 GCCv4.1.0 DOSLFN 0.40e
some setup info:
MSDOS v7.10 (Win98SE)
HIMEM.SYS was loaded
DOSKEY was loaded
SMARTDRV was not loaded
no DRVSPACE.BIN or DBLSPACE.BIN loaded
CWSDPMI v0.90+ (r5)
modern, post 486 cpu, w/internal coprocessor, multiple cores
Rod Pemberton
IIUC, the error would show itself if the accessed file is really >= 2GB,
however Juan's test was simply running gcc to compile a hello.c and I
don't think that gcc is trying to access any such large file in the process.
Am I missing something?
--
O.S.
You are probably right. However, Charles's point is worth taking,
because we also fail these two functions with EOVERFLOW when the
registers returned by 71A6 indicate that the file size is > 2GB. So
it could make sense to treat each of these 2 cases differently, where
we currently don't.
Again, running under GDB to see which of these is actually the case
for GCC will allow us to be smarter.
All functions that call filelength/lfilelength
will be affected by this bug. The same applies
to all ports that have been compiled with djdev204.
GDB is an example. To debug this with DOSLFN installed
I had to use the 2.03 version of latest GDB port.
fcmod is no concerned but fstat is. fstat calls
filelength() so it fails. The values of both
offsets are printed by filelength().
The test program below generates this output:
offset 0x24 = 0x9713c0 offset 0x20 = 0x8f4000
fstat: errno=40 status=-1 size=0
fchmod: errno=0 status=0
Regards,
Juan M. Guerrero
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
int main(void)
{
FILE *f = fopen("./foobar.txt", "w");
struct stat sbuf;
int status;
fprintf(f, "%s\n", "The file name is foobar.txt");
fflush(f);
errno = 0;
status = fstat(fileno(f), &sbuf);
printf("fstat: errno=%d status=%d size=%d\n", errno, status,
sbuf.st_size);
errno = 0;
status = fchmod(fileno(f), S_IWUSR|S_IRUSR);
printf("fchmod: errno=%d status=%d\n", errno, status);
return 0;
}
On Aug 30, 5:27 pm, Juan Manuel Guerrero <juan.guerr...@gmx.de> wrote:
>
> I have tried to compile a simple program on MSDOS 6.22. I have installed stock
> djgpp 2.04 binaries. Before installing djgpp I installed doslfn 0.40e so I had
> LFN support avialable during unzipping the djgpp packages. All djgpp programs
> I started were able to use the installed LFN driver. The only exception was
> gcc and gpp. I was not able to compile a trivial hello world program. I tried
> gcc 3.4.4 and gcc 4.6.1. This is surprissing because the LFN driver used is the
> same I use with FreeDOS, and there it works. It makes no difference if I load
> the driver in conventional memory or if I load it in UMBs. Also it makes no difference
> if the driver generates numerical tails for the SFN or not. Of course, as soon
> as I remove the driver gcc works again. Below is the error output produced by
> gcc. Any suggestions would be welcome.
I've read the thread so far, but I'm still confused. Why would it work
at all on FreeDOS then? Perhaps they support the API (only)? I don't
think they (even these days) support bigger than 2 GB files, even on
FAT32. I guess it silently fails, dunno. I wish somebody (FD kernel
dev) would take a look, esp. since what other (free) choice is there?
Win9x is rare these days, and I'm not sure even Win2k/WinXP support
large files. Maybe EDR-DOS (FAT+), who knows.
Sorry if this comment isn't very helpful, but I felt like I had to say
it. :-(
Maybe FreeDOS supports that function natively, and doesn't need
DOSLFN.
Or maybe DOSLFN does something that works on FreeDOS, but on on
MS-DOS.
I have found my old FreeDOS CD and installed DOSLFN 0.40c.
With this driver everthing works on MSDOS. Stepping into
the filelength() code shows that the 0.40e version does
not set the CF when it returns from 0x71A6 call while 0.40c
does so that it jumps directly into the 0x4201 code instead
of returning an EOVERFLOW.
Neitherless, the points that were pointed out by Charles
Sandmann in
http://www.delorie.com/archives/browse.cgi?p=djgpp/2011/09/02/23:45:11
still are open. Some fix for that issue would be nice.
Regards,
Juan M. Guerrero
If 0.40e does not set the CF, shouldn't I be seeing the error with
MS-DOS 7.10 too? I don't get why this is just 6.22 or FreeDOS ...
Rod Pemberton
If no one objects I will commit the patch below.
Regards,
Juan M. Guerrero
2011-09-04 Juan Manuel Guerrero <juan.g...@gmx.de>
* src/libc/posix/sys/stat/filelen.c: Check that 0x71A6 call is supported
by checking that ax does not contain 0x7100.
* src/libc/posix/sys/stat/lfilelen.c: Check that 0x71A6 call is supported
by checking that ax does not contain 0x7100.
diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/filelen.c djgpp/src/libc/posix/sys/stat/filelen.c
--- djgpp.orig/src/libc/posix/sys/stat/filelen.c 2001-09-25 01:00:52 +0000
+++ djgpp/src/libc/posix/sys/stat/filelen.c 2011-09-04 12:25:38 +0000
@@ -39,12 +39,13 @@ filelength(int fhandle)
regs.x.bx = fhandle;
regs.x.ds = __tb >> 4;
regs.x.dx = 0;
regs.x.flags |= 1;
__dpmi_int(0x21, ®s);
-
- if ((regs.x.flags & 1) == 0)
+
+ /* If function 0x71A6 is not supported then ax contains 0x7100. */
+ if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
{
/* Offset 0x24 contains the low 32-bits of the file size.
Offset 0x20 contains the high 32-bits. */
retval = _farpeekl(_dos_ds, __tb + 0x24);
diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/lfilelen.c djgpp/src/libc/posix/sys/stat/lfilelen.c
--- djgpp.orig/src/libc/posix/sys/stat/lfilelen.c 2001-02-04 19:13:00 +0000
+++ djgpp/src/libc/posix/sys/stat/lfilelen.c 2011-09-04 12:25:38 +0000
@@ -33,12 +33,13 @@ lfilelength(int fhandle)
regs.x.bx = fhandle;
regs.x.ds = __tb >> 4;
regs.x.dx = 0;
regs.x.flags |= 1;
__dpmi_int (0x21, ®s);
-
- if ((regs.x.flags & 1) == 0)
+
+ /* If function 0x71A6 is not supported then ax contains 0x7100. */
+ if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
{
/* Offset 0x24 contains the low 32-bits of the file size.
Offset 0x20 contains the high 32-bits. */
long retval_l = _farpeekl (_dos_ds, __tb + 0x24);
long retval_h = _farpeekl (_dos_ds, __tb + 0x20);
I do not know why the behaviour is as it is. But I can
confirm that that for some reason MSDOS and FreeDOS have
different behaviour. Both partitions use FAT16. If MSDOS
is used and DOSLFN-0.40c is used the CF is reset after
calling 0x71A6 and ax contents 0x7100. If I replace the
driver with DOSLFN-0.40e the the CF is not reseted but
ax contents 0x7100 too. This has the consequence that
the code below from filelength() generates an EOVERFLOW
if MSDOS is used.
if (_USE_LFN && (fhandle != 0 || _os_trueversion != 0x532))
{
regs.x.ax = 0x71A6;
regs.x.bx = fhandle;
regs.x.ds = __tb >> 4;
regs.x.dx = 0;
regs.x.flags |= 1;
__dpmi_int(0x21, ®s);
if ((regs.x.flags & 1) == 0)
{
/* Offset 0x24 contains the low 32-bits of the file size.
Offset 0x20 contains the high 32-bits. */
retval = _farpeekl(_dos_ds, __tb + 0x24);
if ((_farpeekl(_dos_ds, __tb + 0x20) != 0) || (retval == -1))
{
errno = EOVERFLOW;
return -1L;
}
return retval;
}
}
If FreeDOS is used, the CF is always reset no matter what
driver version is used. ax always contents 0x7100. This
has been verified with debugger sessions.
IMHO there are only 2 conclusions to this. Or DJGPP has
a bug somewhere in __dpmi_int() or the OS and driver have
a bug. Neitherless it is a fact that filelength should
have checked that 0x71A6 is supported at all.
Regards,
Juan M.Guerrero
Looks fine to me, but perhaps mention in the comments the problems
encountered with DOSLFN, including the versions.
Thanks.
I expect the bug is in this API call. DJGPP has heavily used
and tested it's API over the last 15 years. On the other hand,
the API to get file lengths over 2GB is very rarely used and
very likely to be buggy given the various combinations of
drivers and DOS versions.
I think your patch is a good one.
While v2.03 was tested in all environments, v2.04 has had
very sparse testing on non-XP environments.
I wonder, though: Is something really gained by using 71a6 after
along with many checks, as opposed to conventional 4201 ?
--
O.S.
True.
_USE_LFN was probably used to "test" for support of 0x71A6 since Windows
98/SE supports that function. However, 71A6h and other LFN functions are
not
implemented by the various LFN drivers for DOS.
I tested _some_ of the LFN functions that were supported by different
drivers some years ago.
These are the functions I tested (unsorted):
710D, 71A0, 7139, 713B, 7147, 71A8, 716C, 7160, 5704, 5705, 5706, 5707,
71A6, 714E, 714F, 71A1, 7156, 7141, 71AA, 713A
Win98 supports all of those and likely some others.
Of the test list of functions above, DOSLFN and LFNDOS do not support these:
710D, 71A6, 71AA, 5706, 5707
So, those should all have checks. It seems I did not check StarLFN ...
My notes (unconfirmed) say that DJGPP v2.03 calls all of those in the test
list, except for these two:
5707, 71AA
DJGPP also calls this one, so it should have a check too:
7143
Probably Win98 only:
71A7, 71A9
HTH,
Rod Pemberton
That's probably because you'd need FAT32 to have files bigger than 2GB.
So MSDOS 7.1 can and does (whatever that makes it work), 6.X can't and
FreeDOS can but doesn't (bug?).
--
MartinS
This doesn't sound right. Files bigger than 2GB requires FAT32. This
should be independent of LFN.
In my (perfect) world at least...
--
MartinS