Mail Archives: djgpp-workers/1998/03/16/08:55:43
> 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 -