delorie.com/archives/browse.cgi   search  
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 -


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