readdir: replace opendir/readdir/closedir API with a 32-bit API
authorH. Peter Anvin <hpa@zytor.com>
Fri, 5 Mar 2010 06:54:07 +0000 (22:54 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 5 Mar 2010 06:54:07 +0000 (22:54 -0800)
The 16-bit API to opendir/readdir/closedir was confused, had a memory
leak, and was incompatible with Syslinux 3.x anyway.  Replace it with
a pure 32-bit API.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
13 files changed:
com32/include/sys/dirent.h
com32/include/syslinux/pmapi.h
com32/lib/Makefile
com32/lib/closedir.c [deleted file]
com32/lib/opendir.c [deleted file]
com32/lib/readdir.c [deleted file]
com32/lib/sys/readdir.c [new file with mode: 0644]
com32/rosh/rosh.c
core/comboot.inc
core/fs/readdir.c
core/include/fs.h
core/pmapi.c
doc/comboot.txt

index cc2916e..a7f26e4 100644 (file)
@@ -19,11 +19,8 @@ struct dirent {
     char d_name[NAME_MAX + 1];
 };
 
-struct file;
-
-typedef struct {
-    struct file *dd_dir;
-} DIR;
+struct _DIR_;
+typedef struct _DIR_ DIR;
 
 #define DIR_REC_LEN(name) (12 + strlen(name) + 1 + 3) & ~3
 
index d16d3de..34648e5 100644 (file)
  * Note: add new members to this structure only at the end.
  * The position of elements in this structure is an ABI.
  */
+struct _DIR_;
+struct dirent;
+
 struct com32_pmapi {
     void *(*lmalloc)(size_t);
     void (*lfree)(void *);
 
     size_t (*read_file)(uint16_t *, void *, size_t);
+
+    struct _DIR_ *(*opendir)(const char *);
+    struct dirent *(*readdir)(struct _DIR_ *);
+    int (*closedir)(struct _DIR_ *);
 };
 
 #endif /* _SYSLINUX_PMAPI_H */
index 8aad4f8..93643ce 100644 (file)
@@ -31,7 +31,7 @@ LIBOBJS = \
        \
        dprintf.o vdprintf.o                                            \
        \
-       opendir.o readdir.o closedir.o getcwd.o chdir.o fdopendir.o     \
+       sys/readdir.o getcwd.o chdir.o fdopendir.o                      \
        \
        libgcc/__ashldi3.o libgcc/__udivdi3.o                           \
        libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o         \
diff --git a/com32/lib/closedir.c b/com32/lib/closedir.c
deleted file mode 100644 (file)
index f4de67a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * closedir.c
- */
-
-#include <dirent.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <com32.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-int closedir(DIR * dir)
-{
-    int rv = -1;
-       
-    if (dir) {
-       com32sys_t regs;
-       memset(&regs, 0, sizeof regs);
-       regs.eax.w[0] = 0x0022;
-       regs.esi.l = (uint32_t)dir;
-       __com32.cs_intcall(0x22, &regs, &regs);
-       free(dir);
-       rv = 0;
-    }
-    
-    return rv;
-}
diff --git a/com32/lib/opendir.c b/com32/lib/opendir.c
deleted file mode 100644 (file)
index e3c35ce..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * opendir.c
- */
-
-#include <dirent.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <com32.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-DIR *opendir(const char *pathname)
-{
-    DIR *newdir = NULL;
-    com32sys_t regs;
-    char *lm_pathname;
-
-    lm_pathname = lstrdup(pathname);
-    if (!lm_pathname)
-       return NULL;
-
-    regs.eax.w[0] = 0x0020;
-    regs.esi.w[0] = OFFS(lm_pathname);
-    regs.es = SEG(lm_pathname);
-
-    __com32.cs_intcall(0x22, &regs, &regs);
-       
-    if (!(regs.eflags.l & EFLAGS_CF)) {
-        /* Initialization: malloc() then zero */
-        newdir = zalloc(sizeof(DIR));
-       newdir->dd_dir = (struct file *)regs.eax.l;
-    }
-
-    lfree(lm_pathname);
-
-    /* We're done */
-    return newdir;
-}
diff --git a/com32/lib/readdir.c b/com32/lib/readdir.c
deleted file mode 100644 (file)
index d59ad3a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * readdir.c
- */
-
-#include <dirent.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <com32.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-struct dirent *readdir(DIR * dir)
-{
-    struct dirent *newde;
-    com32sys_t regs;
-    
-    memset(&regs, 0, sizeof(regs));            
-    regs.eax.w[0] = 0x0021;
-    regs.esi.l = (uint32_t)dir;
-    __com32.cs_intcall(0x22, &regs, &regs);
-    newde = (struct dirent *)(regs.eax.l);
-
-    return newde;
-}
diff --git a/com32/lib/sys/readdir.c b/com32/lib/sys/readdir.c
new file mode 100644 (file)
index 0000000..d2a8c03
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * readdir.c
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <com32.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <syslinux/pmapi.h>
+
+DIR *opendir(const char *pathname)
+{
+    return __com32.cs_pm->opendir(pathname);
+}
+
+struct dirent *readdir(DIR *dir)
+{
+    return __com32.cs_pm->readdir(dir);
+}
+
+int closedir(DIR *dir)
+{
+    return __com32.cs_pm->closedir(dir);
+}
index 13e8ffb..aa3e453 100644 (file)
@@ -451,7 +451,6 @@ void rosh_dir_arg(const char *ifilstr, const char *pwdstr)
 // inchar = fgetc(stdin);
 // fgets(instr, ROSH_CMD_SZ, stdin);
 #endif /* DO_DEBUG */
-                   free(de);
                    de = readdir(d);
 // if(filepos>15){      de = NULL;      printf("Force Break\n");}
                }
index 13daf3e..c42df80 100644 (file)
@@ -904,47 +904,6 @@ comapi_getcwd:
                ret
 
 ;
-; INT 22h AX=0020h     Open directory
-;
-%if IS_PXELINUX
-comapi_opendir equ comapi_err
-
-%else
-comapi_opendir:
-               mov es,P_ES
-               mov si,P_SI
-               pm_call opendir
-               jz comapi_err   ; Didn't find a directory
-               cmp eax,0
-               jz comapi_err   ; Found nothing
-                mov P_EAX,eax
-               clc
-               ret
-%endif
-
-;
-; INT 22h AX=0021h     Read directory
-;
-%if IS_PXELINUX
-comapi_readdir equ comapi_err
-
-%else
-comapi_readdir:
-               mov esi,P_ESI       ; The address of DIR structure
-               pm_call readdir
-               mov P_EAX,eax       ; The address of newly read dirent structure
-               ret
-%endif
-
-;
-; INT 22h AX=0022h     Close directory
-;
-comapi_closedir:
-               mov esi,P_ESI    ; The address of DIR structure
-               pm_call closedir
-               ret
-
-;
 ; INT 22h AX=0023h     Query shuffler size
 ;
 comapi_shufsize:
@@ -1016,9 +975,9 @@ int22_table:
                dw comapi_writeadv      ; 001D write ADV to disk
                dw comapi_kbdtable      ; 001E keyboard remapping table
                dw comapi_getcwd        ; 001F get current working directory
-               dw comapi_opendir       ; 0020 open directory
-               dw comapi_readdir       ; 0021 read directory
-               dw comapi_closedir      ; 0022 close directory
+               dw comapi_err           ; 0020 open directory
+               dw comapi_err           ; 0021 read directory
+               dw comapi_err           ; 0022 close directory
                dw comapi_shufsize      ; 0023 query shuffler size
                dw comapi_shufraw       ; 0024 cleanup, shuffle and boot raw
 int22_count    equ ($-int22_table)/2
index 0e35641..7fa9934 100644 (file)
@@ -5,47 +5,49 @@
 #include "core.h"
 
 /* 
- * open dir, return the file structure pointer in _eax_, or NULL if failed 
+ * Open a directory
  */
-void opendir(com32sys_t *regs)
+DIR *opendir(const char *path)
 {
-    const char *src = MK_PTR(regs->es, regs->esi.w[0]);
     int rv;
 
-    rv = searchdir(src);
-    if (rv < 0) {
-       regs->eax.l = 0;
-       regs->eflags.l |= EFLAGS_ZF;
-    } else {
-       regs->eax.l = (uint32_t)handle_to_file(rv);
-       regs->eflags.l &= ~EFLAGS_ZF;
-    }
+    rv = searchdir(path);
+    if (rv < 0)
+       return NULL;
+
+    /* XXX: check for a directory handle here */
+    return (DIR *)handle_to_file(rv);
 }
 
 /*
- * Read one dirent at one time. 
- *
- * @input: _esi_ register stores the address of DIR structure
- * @output: _eax_ register stores the address of newly read dirent structure
+ * Read one directory entry at one time. 
  */
-void readdir(com32sys_t *regs)
+struct dirent *readdir(DIR *dir)
 {
-    DIR *dir = (DIR *)regs->esi.l;     
+    static struct dirent buf;
     struct dirent *de = NULL;
+    struct file *dd_dir = (struct file *)dir;
     
-    if (dir->dd_dir)
-       de = this_fs->fs_ops->readdir(dir->dd_dir);
-    else
-       de = NULL;
+    if (dd_dir)
+       de = dd_dir->fs->fs_ops->readdir(dd_dir);
     
-    /* Return the newly read de in _eax_ register */
-    regs->eax.l = (uint32_t)de;
+    if (de) {
+       memcpy(&buf, de, sizeof *de);
+       free(de);
+       return &buf;
+    } else {
+       return NULL;
+    }
 }
 
-void closedir(com32sys_t *regs)
+/*
+ * Close a directory
+ */
+int closedir(DIR *dir)
 {
-    DIR *dir = (DIR *)regs->esi.l;
-    _close_file(dir->dd_dir);
+    struct file *dd_dir = (struct file *)dir;
+    _close_file(dd_dir);
+    return 0;
 }
 
 
index c210288..14073e5 100644 (file)
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <com32.h>
 #include <stdio.h>
+#include <sys/dirent.h>
 #include "core.h"
 #include "disk.h"
 
@@ -210,6 +211,11 @@ void pm_realpath(com32sys_t *regs);
 size_t realpath(char *dst, const char *src, size_t bufsize);
 int chdir(const char *src);
 
+/* readdir.c */
+DIR *opendir(const char *pathname);
+struct dirent *readdir(DIR *dir);
+int closedir(DIR *dir);
+
 /*
  * Generic functions that filesystem drivers may choose to use
  */
index 0cb664e..96ede13 100644 (file)
@@ -23,4 +23,8 @@ const struct com32_pmapi pm_api_vector =
     .lfree     = free,          /* Free low memory */
 
     .read_file = pmapi_read_file,
+
+    .opendir   = opendir,
+    .readdir   = readdir,
+    .closedir  = closedir,
 };
index b6c947a..b970b28 100644 (file)
@@ -869,44 +869,16 @@ AX=001Fh [3.74]   Get current working directory
        Input:  AX      0001Fh
        Output: ES:BX   null-terminated directory name string
 
-       Returns the current working directory.  For SYSLINUX, ISOLINUX,
-       and PXELINUX, this will be an absolute path.  For EXTLINUX, it
-       currently returns "./".
+       Returns the current working directory.
 
 
-AX=0020h [3.74] Open directory
-       Input:  AX      0020h
-               ES:SI   /-null-terminated directory name
-       Output: SI      directory handle
-               EAX     clobbered
+AX=0020h [3.74] Obsoleted in 4.00
+AX=0021h [3.74] Obsoleted in 4.00
+AX=0022h [3.74] Obsoleted in 4.00
 
-       Open a directory for reading.  Directory name must have a trailing
-        "/" before the null (otherwise, you're looking for a file)(This
-       may change as this is a BETA call).
-
-
-AX=0021h [3.74] Read directory
-       Input:  AX      0021h
-               SI      directory handle
-               ES:DI   buffer for file name
-       Output: DL      Type of file
-               SI      directory handle, or 0 if end of directory was reached
-               EAX     Size of file
-               EBX     Inode of file
-
-       Read one filename from the directory, incrementing the
-       directory structure at SI as appropriate, storing the filename
-       into the buffer at ES:DI, and returning the type of the file
-       in DL, the file length in EAX, the inode/file number in EBX
-       and the updated directory handle.
-
-
-AX=0022h [3.74] Close directory
-       Input:  AX      0022h
-               SI      directory handle
-       Output  SI      0
-
-       Closes a directory.
+       These three functions provided opendir/readdir/closedir
+       functionality in the late 3.xx series.  They have been
+       replaced by the protected-mode interface.
 
 
 AX=0023h [3.80] Get shuffler parameters
@@ -983,13 +955,27 @@ AX=0024h [3.80] Cleanup, shuffle and boot, raw version
 
        ++++ 32-BIT ONLY API CALLS ++++
 
-void *pm_cs->lmalloc(size_t)
+void *pm_cs->lmalloc(size_t bytes)
 
        Allocate a buffer in low memory (below 1 MB).
 
 
-void pm_cs->lfree(void *)
+void pm_cs->lfree(void *ptr)
 
        Free a buffer allocated with pm_cs->lmalloc().
 
 
+DIR *pm_cs->opendir(const char *pathname)
+
+       Open a directory.
+
+
+struct dirent *pm_cs->readdir(DIR *dir)
+
+       Read an entry from a directory.  The entry is returned in a
+       static buffer.
+
+
+int pm_cs->closedir(DIR *dir)
+
+       Close a directory.