[syslinux:pathbased] readdir: replace opendir/readdir/closedir API with a 32-bit API

syslinux-bot for H. Peter Anvin hpa at zytor.com
Thu Mar 4 22:57:07 PST 2010


Commit-ID:  b4da45a8a0a7c7e6f66850dee1f1733100767c30
Gitweb:     http://syslinux.zytor.com/commit/b4da45a8a0a7c7e6f66850dee1f1733100767c30
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 4 Mar 2010 22:54:07 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Thu, 4 Mar 2010 22:54:07 -0800

readdir: replace opendir/readdir/closedir API with a 32-bit API

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 at zytor.com>


---
 com32/include/sys/dirent.h     |    7 +---
 com32/include/syslinux/pmapi.h |    7 ++++
 com32/lib/Makefile             |    2 +-
 com32/lib/closedir.c           |   30 --------------------
 com32/lib/opendir.c            |   41 ---------------------------
 com32/lib/readdir.c            |   27 ------------------
 com32/lib/sys/readdir.c        |   30 ++++++++++++++++++++
 com32/rosh/rosh.c              |    1 -
 core/comboot.inc               |   47 ++-----------------------------
 core/fs/readdir.c              |   54 ++++++++++++++++++-----------------
 core/include/fs.h              |    6 ++++
 core/pmapi.c                   |    4 ++
 doc/comboot.txt                |   60 +++++++++++++++------------------------
 13 files changed, 104 insertions(+), 212 deletions(-)

diff --git a/com32/include/sys/dirent.h b/com32/include/sys/dirent.h
index cc2916e..a7f26e4 100644
--- a/com32/include/sys/dirent.h
+++ b/com32/include/sys/dirent.h
@@ -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
 
diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h
index d16d3de..34648e5 100644
--- a/com32/include/syslinux/pmapi.h
+++ b/com32/include/syslinux/pmapi.h
@@ -42,11 +42,18 @@
  * 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 */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 8aad4f8..93643ce 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -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
index f4de67a..0000000
--- a/com32/lib/closedir.c
+++ /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
index e3c35ce..0000000
--- a/com32/lib/opendir.c
+++ /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
index d59ad3a..0000000
--- a/com32/lib/readdir.c
+++ /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
index 0000000..d2a8c03
--- /dev/null
+++ b/com32/lib/sys/readdir.c
@@ -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);
+}
diff --git a/com32/rosh/rosh.c b/com32/rosh/rosh.c
index 13e8ffb..aa3e453 100644
--- a/com32/rosh/rosh.c
+++ b/com32/rosh/rosh.c
@@ -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");}
 		}
diff --git a/core/comboot.inc b/core/comboot.inc
index 13daf3e..c42df80 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -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
diff --git a/core/fs/readdir.c b/core/fs/readdir.c
index 0e35641..7fa9934 100644
--- a/core/fs/readdir.c
+++ b/core/fs/readdir.c
@@ -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;
 }
 
 
diff --git a/core/include/fs.h b/core/include/fs.h
index c210288..14073e5 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -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
  */
diff --git a/core/pmapi.c b/core/pmapi.c
index 0cb664e..96ede13 100644
--- a/core/pmapi.c
+++ b/core/pmapi.c
@@ -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,
 };
diff --git a/doc/comboot.txt b/doc/comboot.txt
index b6c947a..b970b28 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -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.



More information about the Syslinux-commits mailing list