delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/08/24/21:43:36

X-Authentication-Warning: new-smtp2.ihug.com.au: Host p18-max14.syd.ihug.com.au [203.173.154.18] claimed to be acceleron
Message-ID: <00de01c12d06$82e2cd40$0a02a8c0@acceleron>
From: "Andrew Cottrell" <acottrel AT ihug DOT com DOT au>
To: <eliz AT is DOT elta DOT co DOT il>, "Charles Sandmann" <sandmann AT clio DOT rice DOT edu>
Cc: <djgpp-workers AT delorie DOT com>
Subject: Read 3F00 STDIN problem on Win 2K ( was Re: Fseek on STDIN problem on Win 2K)
Date: Sat, 25 Aug 2001 11:37:13 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4807.1700
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700
Reply-To: djgpp-workers AT delorie DOT com

> > > > fstat() doesn't cause this problem in 2.03 which might explain why
> > > > it's more rare).
> > >
> > > So perhaps we should find out which change since v2.03 triggers this.
> >
> > Yes.
> From my test above 203 also exhibits the problem. Probably the reason 203
> does not show up the problem in is_executable() is that thre are other
calls
> somewhere else in the code that "fix" the problem, in a similar way to
when
> the extra call to 4200 is inserted into the sample code.
>
> I wonder if the 3700 call is broken in Windows 2K. I am going to have a
look
> at this and get back with my results in a few hours.
> I may be going off on a tangent, but it will only take a few hours to
check
> and satisfy my hunch.
Sorry the call is 3F00 not 3700. And my hunch is correct in that the 3F00
call is broken on WIn 2K and it depends on what other calls are made after
this as to whether thje problem is seen or not. This is why you go nuts
trying to figure out why it works and then it does not etc.... grrr MS... or
if you try it in another app or in another package it stops working or
starts working.

I have greped the LIBC and the places that call 3F00 are:
    a) is_exec.c
    b) _read.c
    c) d_read.c
    d) int86.c

A quick fix is outlined below thanks to Charles finding that a fix for
is_executable() is to add a call to 4201 with an offset of 0 after the 3F00
call, this also fixes _read(). If this is okay I can also include a similar
change to d_read.c and int86.c

What do people think about this?


A proposal to fix this is to modify _read.c and is_exec.c as follows:

*** _read_orig.c        Sun Mar 11 00:08:58 2001
--- _read.c     Sat Aug 25 11:11:18 2001
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <libc/stubs.h>
  #include <unistd.h>
***************
*** 7,12 ****
--- 8,15 ----
  #include <dpmi.h>
  #include <io.h>
  #include <sys/fsext.h>
+ #include <fcntl.h>
+ #include <dos.h>

  #include <libc/dosio.h>

***************
*** 17,22 ****
--- 20,26 ----
    int ngot;
    unsigned long tbsize;
    __dpmi_regs r;
+   unsigned use_lfn = _USE_LFN;

    __FSEXT_Function *func = __FSEXT_get_function(handle);
    if (func)
***************
*** 48,52 ****
--- 52,73 ----
        dosmemget(__tb, k, buffer);
      buffer = (void *)((int)buffer + k);
    } while(count && j == k);   /* if not == on DOS then no more */
+
+   if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532)
+   {
+     /* Windows 2000 or XP; or NT with LFN TSR.        Windows 2000 behaves
+        badly when using 3F00 call. We need to seek to the current
+        position in order for subseqent calls to work. */
+     memset(&r,0,sizeof(r));
+     r.x.ax = 0x4201;     /* 4201h current file position */
+     r.x.bx = handle;     /*  BX = file handle */
+     r.x.cx = r.x.dx =0;    /* CX:DX = (signed) offset from origin of new
file position */
+     __dpmi_int(0x21, &r);
+     if (r.x.flags & 1)
+     {
+       errno = __doserr_to_errno(r.x.ax);
+       return -1;
+     }
+   }
    return ngot;
  }

*** is_exec_orig.c      Sat Aug 25 11:15:22 2001
--- is_exec.c   Sat Aug 25 11:14:06 2001
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /* IS_EXEC.C
***************
*** 26,31 ****
--- 27,35 ----
  #include <io.h>
  #include <libc/farptrgs.h>
  #include <libc/dosio.h>
+ #include <fcntl.h>
+ #include <dos.h>
+

  extern unsigned short _djstat_flags;
  unsigned short              _get_magic(const char *, int);
***************
*** 45,50 ****
--- 49,55 ----
    unsigned short       retval;
    unsigned short       fpos_high = 0, fpos_low = 0;
    int                read_fail = 0;
+   unsigned use_lfn = _USE_LFN;

    /* If given a pathname, open the file. */
    if (s)
***************
*** 91,96 ****
--- 96,120 ----
       or (3) fail to read at all.  */
    if (regs.x.ax != 2)
      read_fail = (regs.x.flags & 1) ? regs.x.ax : -1;
+   else
+   {
+     if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532)
+     {
+       /* Windows 2000 or XP; or NT with LFN TSR.  Windows 2000 behaves
+        badly when using 3F00 call. We need to seek to the current
+        position in order for subseqent calls to work. */
+       memset(&regs,0,sizeof(regs));
+       regs.x.ax = 0x4201;        /* 4201h current file position */
+       regs.x.bx = fh;            /*  BX = file handle */
+       regs.x.cx = regs.x.dx =0;    /* CX:DX = (signed) offset from origin
of new file position */
+       __dpmi_int(0x21, &regs);
+       if (regs.x.flags & 1)
+       {
+       errno = __doserr_to_errno(regs.x.ax);
+       return 0;
+       }
+     }
+   }

    /* If called with filename, close the file. */
    if (s)


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019