Mail Archives: djgpp-workers/2000/12/25/11:53:22
From: | "Tim Van Holder" <tim DOT van DOT holder AT pandora DOT be>
|
To: | <djgpp-workers AT delorie DOT com>
|
Subject: | Draft patch for opendir() extension
|
Date: | Mon, 25 Dec 2000 17:56:57 +0100
|
Message-ID: | <NEBBIOJNGMKPNOBKHCGHIEAOCAAA.tim.van.holder@pandora.be>
|
MIME-Version: | 1.0
|
X-Priority: | 3 (Normal)
|
X-MSMail-Priority: | Normal
|
X-Mailer: | Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0)
|
X-MimeOLE: | Produced By Microsoft MimeOLE V5.50.4133.2400
|
Importance: | Normal
|
X-MIME-Autoconverted: | from quoted-printable to 8bit by delorie.com id LAA07056
|
Reply-To: | djgpp-workers AT delorie DOT com
|
Below is a patch to extend opendir() et al to support 'virtual
files' introduced by the fsext mechanism (eg /dev/zero). The
idea is that fsext modules register and deregister any files
they handle.
The registering/deregistering isn't yet implemented in this
draft, as this probably requires more thought: i.e. do fsext
functions know the name of the file they're working on after
the initial open()? Probably not, so they'd need to register
a fd/name combination instead of just a name, so they can
properly deregister a file.
Any and all suggestions are welcomed.
This patch also fixes a bug in telldir/seekdir.
telldir() returns the number of actual entries read and
seekdir() calls readdir() that many times after doing a
rewinddir(). But if the DIR has simulated dots (or with this
patch, other simulated entries), those numbers do not match.
*** /dev/null Mon Dec 25 17:51:34 2000
--- include/sys/fsextdir.h Mon Dec 25 17:29:02 2000
***************
*** 0 ****
--- 1,33 ----
+ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+ /* Written by Tim Van Holder.
+ * This file declares functions that allow fsext routines to
+ * register/deregister virtual file names (eg /dev/zero), and a
+ * function that retrieves a NULL-terminated list of such entries
+ * in a given directory. */
+
+ #ifndef __dj_include_libc_fsextdir_h_
+ #define __dj_include_libc_fsextdir_h_
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ #ifndef __dj_ENFORCE_ANSI_FREESTANDING
+ #ifndef __STRICT_ANSI__
+ #ifndef _POSIX_SOURCE
+
+ void __fsext_register_entry(const char *_entry);
+ void __fsext_deregister_entry(const char *_entry);
+
+ char **__fsext_entries(const char *_dir_name);
+
+ #endif /* !_POSIX_SOURCE */
+ #endif /* !__STRICT_ANSI__ */
+ #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+ #endif /* !__dj_include_libc_fsextdir_h_ */
*** /dev/null Mon Dec 25 17:51:37 2000
--- src/libc/fsext/fsextdir.c Mon Dec 25 17:38:44 2000
***************
*** 0 ****
--- 1,25 ----
+ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+ /* Written by Tim Van Holder.
+ * This file defines functions that allow fsext routines to
+ * register/deregister virtual file names (eg /dev/zero), and a
+ * function that retrieves a NULL-terminated list of such entries
+ * in a given directory. */
+
+ #include <libc/fsextdir.h>
+
+ void
+ __fsext_register_entry (const char* d)
+ {
+ }
+
+ void
+ __fsext_deregister_entry (const char* d)
+ {
+ }
+
+ char**
+ __fsext_entries (const char* d)
+ {
+ return NULL;
+ }
Index: src/libc/posix/dirent/closedir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/closedir.c,v
retrieving revision 1.2
diff -c -r1.2 closedir.c
*** closedir.c 1998/11/15 13:48:38 1.2
--- closedir.c 2000/12/25 16:47:11
***************
*** 17,22 ****
--- 17,29 ----
errno = e;
else
retval = -1;
+ if (dir->fsext_entries)
+ {
+ dir->fsext_entry = dir->fsext_entries;
+ while (*dir->fsext_entry != NULL)
+ free (*(dir->fsext_entry++));
+ free (dir->fsext_entries);
+ }
free(dir->name);
free(dir);
return retval;
Index: src/libc/posix/dirent/dirstruc.h
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/dirstruc.h,v
retrieving revision 1.3
diff -c -r1.3 dirstruc.h
*** dirstruc.h 1996/09/11 23:23:52 1.3
--- dirstruc.h 2000/12/25 16:47:11
***************
*** 9,12 ****
--- 9,15 ----
struct ffblk ff;
struct dirent de;
int need_fake_dot_dotdot; /* 0=no, 1=.., 2=. */
+ int exists;
+ char **fsext_entries;
+ char **fsext_entry;
};
Index: src/libc/posix/dirent/opendir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/opendir.c,v
retrieving revision 1.4
diff -c -r1.4 opendir.c
*** opendir.c 2000/08/22 18:38:03 1.4
--- opendir.c 2000/12/25 16:47:11
***************
*** 5,10 ****
--- 5,11 ----
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <libc/symlink.h>
+ #include <libc/fsextdir.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
***************
*** 59,70 ****
char name_copy[FILENAME_MAX + 1];
if (!__solve_symlinks(name, name_copy))
! return NULL;
dir = (DIR *)malloc(sizeof(DIR));
if (dir == 0)
return 0;
dir->num_read = 0;
dir->name = (char *)malloc(PATH_MAX);
if (dir->name == 0)
{
--- 60,72 ----
char name_copy[FILENAME_MAX + 1];
if (!__solve_symlinks(name, name_copy))
! return NULL;
dir = (DIR *)malloc(sizeof(DIR));
if (dir == 0)
return 0;
dir->num_read = 0;
+ dir->exists = 1;
dir->name = (char *)malloc(PATH_MAX);
if (dir->name == 0)
{
***************
*** 79,90 ****
/* Make absolute path */
_fixpath(name_copy, dir->name);
! /* Ensure that directory to be accessed exists */
if (access(dir->name, D_OK))
{
! free(dir->name);
! free(dir);
! return 0;
}
/* Strip trailing slashes, so we can append "/ *.*" */
--- 81,105 ----
/* Make absolute path */
_fixpath(name_copy, dir->name);
! dir->fsext_entries = __fsext_entries (dir->name);
! dir->fsext_entry = dir->fsext_entries;
!
! /* Ensure that directory to be accessed exists; only matters if there are
! * no entries faked by the fsext system. */
if (access(dir->name, D_OK))
{
! if (dir->fsext_entries == NULL)
! {
! free(dir->name);
! free(dir);
! return 0;
! }
! else
! {
! dir->exists = 0;
! dir->need_fake_dot_dotdot = 2;
! return dir;
! }
}
/* Strip trailing slashes, so we can append "/ *.*" */
Index: src/libc/posix/dirent/readdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/readdir.c,v
retrieving revision 1.3
diff -c -r1.3 readdir.c
*** readdir.c 1998/11/15 13:47:22 1.3
--- readdir.c 2000/12/25 16:47:13
***************
*** 17,35 ****
int oerrno = errno;
int mbsize;
! if (dir->need_fake_dot_dotdot)
{
/* Fake out . and .. on /; see opendir for comments */
! dir->need_fake_dot_dotdot --;
! if (dir->need_fake_dot_dotdot)
! strcpy(dir->de.d_name, ".");
! else
strcpy(dir->de.d_name, "..");
dir->de.d_namlen = strlen(dir->de.d_name);
return &(dir->de);
}
! if (dir->num_read)
done = findnext(&dir->ff);
else
{
--- 17,49 ----
int oerrno = errno;
int mbsize;
! if (dir->num_read < dir->need_fake_dot_dotdot)
{
/* Fake out . and .. on /; see opendir for comments */
! dir->num_read++;
! if (dir->num_read == dir->need_fake_dot_dotdot)
strcpy(dir->de.d_name, "..");
+ else
+ strcpy(dir->de.d_name, ".");
dir->de.d_namlen = strlen(dir->de.d_name);
return &(dir->de);
}
+
+ if (dir->fsext_entries != NULL && dir->fsext_entry != NULL)
+ {
+ strcpy (dir->de.d_name, *(dir->fsext_entry));
+ dir->de.d_namlen = strlen (dir->de.d_name);
+ dir->fsext_entry++;
+ dir->num_read++;
+ if (*(dir->fsext_entry) == NULL)
+ dir->fsext_entry = NULL;
+ return &(dir->de);
+ }
+
+ if (!dir->exists)
+ return NULL;
! if (dir->exists == 2)
done = findnext(&dir->ff);
else
{
***************
*** 39,44 ****
--- 53,59 ----
if (dir->flags & __OPENDIR_FIND_LABEL)
ff_flags |= FA_LABEL;
done = findfirst(dir->name, &dir->ff, ff_flags);
+ dir->exists = 2;
}
if (done)
{
Index: src/libc/posix/dirent/rewinddi.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/rewinddi.c,v
retrieving revision 1.2
diff -c -r1.2 rewinddi.c
*** rewinddi.c 1998/11/15 13:48:38 1.2
--- rewinddi.c 2000/12/25 16:47:13
***************
*** 15,21 ****
dir->ff.lfn_handle = 0; /* 0 means it's closed */
}
- /* Recompute need_fake_dot_dotdot member. See comments in opendir.c. */
- __set_need_fake_dot_dotdot(dir);
dir->num_read = 0;
}
--- 15,22 ----
dir->ff.lfn_handle = 0; /* 0 means it's closed */
}
dir->num_read = 0;
+ if (dir->exists != 0)
+ dir->exists = 1;
+ dir->fsext_entry = dir->fsext_entries;
}
- Raw text -