delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/03/16/08:55:43

From: Martin Stromberg <Martin DOT Stromberg AT lu DOT erisoft DOT se>
Message-Id: <199803161212.NAA22497@propus.lu.erisoft.se>
Subject: Re: Where to get the latest sources for djtar
To: eliz AT is DOT elta DOT co DOT il (Eli Zaretskii)
Date: Mon, 16 Mar 1998 13:12:37 +0100 (MET)
Cc: djgpp-workers AT delorie DOT com
In-Reply-To: <Pine.SUN.3.91.980316132944.13570E-100000@is> from "Eli Zaretskii" at Mar 16, 98 01:30:15 pm
MIME-Version: 1.0

> The problem is that `djtar' automatically applied change rules for
> directory names without testing whether they have ever worked before.
> This made it loop endlessly, eventually overwriting the stack.  Please
> try the patch below and tell me if it helps.

I'll try that.

> I think testing for a full disk is too expensive, and also doesn't
> cover all the cases (e.g., a write-protected floppy that isn't full).

Hardly too expensive, it's only done when an error occurs. Isn't some
better diagnostics worth the time?


Here's my mkdir.c patch, for what it is worth. 

Some things to note:

ENOSPC and ENAMETOOLONG: I don't know if these are the right E-codes to
use.

24 slashes: this is what I empirically determined on my two partitions. I
couldn't find any #define for this. Does anybody know if this is defined
somewhere? I mean a #define in a header file as well as some DOS-ish FAT
definition.

Setting errno: I don't know if it is a bug or a feature, but in case of
errno == EACCES, the original mkdir.c clobbers errno, without restoring
it by the call to access().


*** mkdir.org	Sat Aug 31 21:09:32 1996
--- mkdir.c	Mon Mar 16 01:02:24 1998
***************
*** 2,12 ****
--- 2,18 ----
  #include <libc/stubs.h>
  #include <errno.h>
  #include <sys/stat.h>
+ #include <sys/vfs.h>
  #include <go32.h>
  #include <dpmi.h>
  #include <unistd.h>
  #include <fcntl.h>
+ #include <limits.h>
  #include <libc/dosio.h>
+ 
+ #if 0
+ #include <stdio.h>
+ #endif
   
  int
  mkdir(const char *dirname, mode_t mode)
***************
*** 27,40 ****
    if (r.x.flags & 1)
    {
      errno = __doserr_to_errno(r.x.ax);
      if (errno == EACCES)
      {
        /* see if the directory existed, in which case
  	 we should return EEXIST - DJ */
        if (access(dirname, D_OK) == 0)
  	errno = EEXIST;
      }
!     return -1;
    }
  
    /* DOS ignores directory permissions, and mkdir is stub'd,
--- 33,99 ----
    if (r.x.flags & 1)
    {
      errno = __doserr_to_errno(r.x.ax);
+ #if 0
+     fprintf(stderr, "mkdir: errno = %d.\n", errno);
+ #endif
      if (errno == EACCES)
      {
+       struct statfs sfs;
+       char tn[PATH_MAX];
+ 
        /* see if the directory existed, in which case
  	 we should return EEXIST - DJ */
        if (access(dirname, D_OK) == 0)
+       {
  	errno = EEXIST;
+ 	return(-1);
+       }
+ #if 0
+       fprintf(stderr, "mkdir: dirname = '%s'.\n", dirname);
+ #endif
+       /* See if the disk is full, in which case
+ 	 we should return ENOSPC - AMS */
+       if(!statfs(dirname, &sfs))
+       {
+ #if 0
+ 	fprintf(stderr, "mkdir statfs.(bfree, bavail, ffree) = (%ld, %ld, %ld).\n",
+ 		sfs.f_bfree, sfs.f_bavail, sfs.f_ffree);
+ #endif
+ 	if(!sfs.f_bfree)
+ 	{
+ 	  errno = ENOSPC;
+ 	  return(-1);
+ 	}
+       }
+       /* See if its to deep directory nesting, in which case
+ 	 we should return ENAMETOOLONG - AMS */
+       if(_truename(dirname, tn))
+       {
+ 	const char *p;
+ 	int slashes;
+ #if 0
+ 	fprintf(stderr, "mkdir: tn = '%s'.\n", tn);
+ #endif
+ 	p = tn;
+ 	slashes = 0;
+ 	while(*p != '\0')
+ 	{
+ 	  if(*p == '\\')
+ 	  {
+ 	    slashes++;
+ 	  }
+ 	  p++;
+ 	}
+ 	if(24 < slashes)
+ 	{
+ 	  errno = ENAMETOOLONG;
+ 	  return(-1);
+ 	}
+       }
+       /* Restore errno. */
+       errno = EACCES;
      }
!     return(-1);
    }
  
    /* DOS ignores directory permissions, and mkdir is stub'd,


- Raw text -


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