delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/12/13/03:02:15

Date: Sun, 13 Dec 1998 10:01:18 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: DJ Delorie <dj AT delorie DOT com>
cc: djgpp-workers AT delorie DOT com
Subject: Re: djgpp 2.02 and the /dev/x/foo feature
In-Reply-To: <Pine.SUN.3.91.981203083734.2275F-100000@is>
Message-ID: <Pine.SUN.3.91.981213095501.26792B-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

On Thu, 3 Dec 1998, I wrote:

> I know about at least one problem which I didn't finish to work out:
> the /dev/x/foo feature doesn't work with all library functions.  I am
> in the middle of writing a test program that will run all the relevant
> library functions through such file names and reveal those which need
> to be fixed (I expect to see about 2 or 3 such functions).

I'm delivering as promised ;-).

It turned out there were 9 functions that didn't work correctly with 
/dev/x/foo file names.  Fortunately, I was able to correct these problems 
by patching only 5 files.  See the patch below; I tried to make the 
patches as simple and localized as I possibly could, to avoid introducing 
any more bugs.

The fixed versions were tested using the same test program I used to 
discover the bugs (for the source of the test program, see my other 
mail).

*** src/libc/compat/sys/vfs/statfs.c~0	Sun Nov 16 14:05:50 1997
--- src/libc/compat/sys/vfs/statfs.c	Sat Dec 12 13:53:34 1998
*************** statfs(const char *path, struct statfs *
*** 19,28 ****
    int cdrom_calls_used = 0;
    int blocks = 0;
  
!   /* Get the drive number */
!   if (path[0] && path[1] == ':')
!     drive_number = (path[0] & 0x1f) - 1;
!   else
    {
      regs.h.ah = 0x19;
      __dpmi_int(0x21, &regs);
--- 19,29 ----
    int cdrom_calls_used = 0;
    int blocks = 0;
  
!   /* Get the drive number, including the case of magic
!      names like /dev/c/foo.  */
!   _put_path(path);
!   drive_number = (_farpeekb(_dos_ds, __tb) & 0x1f) - 1;
!   if (_farpeekb(_dos_ds, __tb + 1) != ':' || drive_number == -1)
    {
      regs.h.ah = 0x19;
      __dpmi_int(0x21, &regs);
*** src/libc/dos/lfn/_use_lfn.c~0	Sun Jun 28 22:18:02 1998
--- src/libc/dos/lfn/_use_lfn.c	Sat Dec 12 14:17:00 1998
***************
*** 17,22 ****
--- 17,23 ----
  #include <libc/bss.h>
  #include <libc/environ.h>
  #include <libc/farptrgs.h>
+ #include <libc/dosio.h>
  
  static int      use_lfn_bss_count = -1;	/* if we are restarted (emacs) */
  static unsigned filesystem_flags  = _FILESYS_UNKNOWN;
*************** _get_volume_info (const char *path, int 
*** 35,58 ****
  
    if (path && *path)
    {
!     if (path[1] == ':')
      {
-       dosmemput (path, 3, tbuf_la);
        tbuf_la += 3;
!       if (path[2] != '\\')
! 	_farpokeb(_dos_ds, tbuf_la - 1, '\\');
!       _farpokeb(_dos_ds, tbuf_la++, '\0');
      }
!     else if (*path == '\\' && path[1] == '\\')
      {
-       int plen = strlen (path) + 1;
- 
        /* FIXME: what should we do with the UNC pathnames like
  	 "\\machine\vol\path"?  We need to know either their
  	 DOS drive letter or where does the root directory path
  	 ends.  For now, we assume the entire path is the root path.  */
!       dosmemput (path, plen, tbuf_la);
!       tbuf_la += plen + 1;
      }
    }
  
--- 36,59 ----
  
    if (path && *path)
    {
!     _put_path(path);
!     _farsetsel(_dos_ds);
!     if (_farnspeekb(tbuf_la + 1) == ':')
      {
        tbuf_la += 3;
!       if (_farnspeekb(tbuf_la - 1) != '\\')
! 	_farnspokeb(tbuf_la - 1, '\\');
!       _farnspokeb(tbuf_la++, '\0');
      }
!     else if (_farnspeekb(tbuf_la) == '\\' && _farnspeekb(tbuf_la + 1) == '\\')
      {
        /* FIXME: what should we do with the UNC pathnames like
  	 "\\machine\vol\path"?  We need to know either their
  	 DOS drive letter or where does the root directory path
  	 ends.  For now, we assume the entire path is the root path.  */
!       for (tbuf_la += 2; _farnspeekb(tbuf_la) != 0; tbuf_la++)
! 	;
!       tbuf_la++;
      }
    }
  
*************** _use_lfn (const char *path)
*** 135,144 ****
      }
  
    same_drive_as_last_time = 1;
!   if (path)
    {
      /* FIXME: a UNC PATH will always force a call to `_get_volume_info'.  */
!     if ((path[1] == ':' && toupper (*path) != last_drive)
  	|| (*path == '\\' && path[1] == '\\'))
        same_drive_as_last_time = 0;
      else
--- 136,147 ----
      }
  
    same_drive_as_last_time = 1;
!   if (path && *path)
    {
+     _put_path(path);
      /* FIXME: a UNC PATH will always force a call to `_get_volume_info'.  */
!     if ((_farpeekb(_dos_ds, __tb + 1) == ':'
! 	 && toupper (_farpeekb(_dos_ds, __tb)) != last_drive)
  	|| (*path == '\\' && path[1] == '\\'))
        same_drive_as_last_time = 0;
      else
*** src/libc/dos/process/dosexec.c~0	Sun Nov 15 13:45:14 1998
--- src/libc/dos/process/dosexec.c	Sat Dec 12 14:41:46 1998
*************** direct_exec_tail(const char *program, co
*** 177,184 ****
    proglen = strlen(program)+1;
    if (!check_talloc(proglen))
      return -1;
    if(lfn) {
-     dosmemput(program, proglen, tbuf_ptr);
      r.x.ax = 0x7160;			/* Truename */
      r.x.cx = 1;				/* Get short name */
      r.x.ds = r.x.es = tbuf_ptr / 16;
--- 177,186 ----
    proglen = strlen(program)+1;
    if (!check_talloc(proglen))
      return -1;
+   /* Make sure any magic names, like /dev/c/foo, are converted to the
+      usual DOS form, and, under LFN, to the short 8+3 alias.  */
+   _put_path2(program, tbuf_beg == __tb ? tbuf_ptr - tbuf_beg : 0);
    if(lfn) {
      r.x.ax = 0x7160;			/* Truename */
      r.x.cx = 1;				/* Get short name */
      r.x.ds = r.x.es = tbuf_ptr / 16;
*************** direct_exec_tail(const char *program, co
*** 189,199 ****
        errno = __doserr_to_errno(r.x.ax);
        return -1;
      }
!     dosmemget(tbuf_ptr, FILENAME_MAX, short_name);
!     progname = short_name;
!     proglen = strlen(short_name)+1;
!   } else
!     progname = program;
  
    if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 48))
      return -1;
--- 191,200 ----
        errno = __doserr_to_errno(r.x.ax);
        return -1;
      }
!   }
!   dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name);
!   progname = short_name;
!   proglen = strlen(short_name)+1;
  
    if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 48))
      return -1;
*** src/libc/posix/sys/stat/fixpath.c~0	Sun Aug 31 13:12:54 1997
--- src/libc/posix/sys/stat/fixpath.c	Sat Dec 12 13:29:14 1998
*************** void
*** 78,90 ****
  _fixpath(const char *in, char *out)
  {
    int		drive_number;
!   const char	*ip = in;
    char		*op = out;
    int		preserve_case = _preserve_fncase();
    char		*name_start;
    int		mbsize;
  
!   use_lfn = _USE_LFN;
  
    /* Add drive specification to output string */
    if (((*ip >= 'a' && *ip <= 'z') ||
--- 78,96 ----
  _fixpath(const char *in, char *out)
  {
    int		drive_number;
!   char		in1[FILENAME_MAX];
!   char		*ip;
    char		*op = out;
    int		preserve_case = _preserve_fncase();
    char		*name_start;
    int		mbsize;
  
!   use_lfn = _use_lfn(in);
! 
!   /* Perform the same magic conversions that _put_path does.  */
!   _put_path(in);
!   dosmemget(__tb, sizeof(in1), in1);
!   ip = in1;
  
    /* Add drive specification to output string */
    if (((*ip >= 'a' && *ip <= 'z') ||
*** src/libc/posix/unistd/chdir.c~0	Mon Jun 29 00:15:08 1998
--- src/libc/posix/unistd/chdir.c	Sat Dec 12 13:40:50 1998
***************
*** 9,19 ****
--- 9,21 ----
  #include <ctype.h>
  #include <dpmi.h>
  #include <libc/dosio.h>
+ #include <libc/farptrgs.h>
  
  int
  __chdir (const char *mydirname)
  {
    __dpmi_regs r;
+   int drv_no = -1;
  
    if (mydirname == 0)
    {
*************** __chdir (const char *mydirname)
*** 27,33 ****
      return -1;
    }
  
!   if (mydirname[1] != ':' || mydirname[2])
    {
      if(_USE_LFN)
        r.x.ax = 0x713b;
--- 29,43 ----
      return -1;
    }
  
!   _put_path(mydirname);
! 
!   /* _put_path performs some magic conversions of file names, so
!      the path in the transfer buffer can include a drive even though
!      MYDIRNAME doesn't seem to.  */
!   if (_farpeekb(_dos_ds, __tb + 1) == ':')
!     drv_no = (_farpeekb(_dos_ds, __tb) & 0x1f) - 1;
! 
!   if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0)
    {
      if(_USE_LFN)
        r.x.ax = 0x713b;
*************** __chdir (const char *mydirname)
*** 35,41 ****
        r.h.ah = 0x3b;
      r.x.dx = __tb_offset;
      r.x.ds = __tb_segment;
-     _put_path(mydirname);
      __dpmi_int(0x21, &r);
      if(r.x.flags & 1)
      {
--- 45,50 ----
*************** __chdir (const char *mydirname)
*** 44,55 ****
      }
    }
  
!   if (mydirname[1] == ':')
    {
      /* Change current drive also.  This *will* work if
         the directory change above worked. */
      r.h.ah = 0x0e;
!     r.h.dl = (mydirname[0] & 0x1f) - 1;
      __dpmi_int(0x21, &r);
    }
  
--- 53,64 ----
      }
    }
  
!   if (drv_no != -1)
    {
      /* Change current drive also.  This *will* work if
         the directory change above worked. */
      r.h.ah = 0x0e;
!     r.h.dl = drv_no;
      __dpmi_int(0x21, &r);
    }
  

- Raw text -


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