From b4da45a8a0a7c7e6f66850dee1f1733100767c30 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 4 Mar 2010 22:54:07 -0800 Subject: [PATCH] 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 --- 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(-) delete mode 100644 com32/lib/closedir.c delete mode 100644 com32/lib/opendir.c delete mode 100644 com32/lib/readdir.c create mode 100644 com32/lib/sys/readdir.c 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 -#include -#include - -#include -#include -#include -#include -#include - -int closedir(DIR * dir) -{ - int rv = -1; - - if (dir) { - com32sys_t regs; - memset(®s, 0, sizeof regs); - regs.eax.w[0] = 0x0022; - regs.esi.l = (uint32_t)dir; - __com32.cs_intcall(0x22, ®s, ®s); - 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 -#include -#include - -#include -#include -#include -#include -#include - -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, ®s, ®s); - - 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 -#include -#include - -#include -#include -#include -#include -#include - -struct dirent *readdir(DIR * dir) -{ - struct dirent *newde; - com32sys_t regs; - - memset(®s, 0, sizeof(regs)); - regs.eax.w[0] = 0x0021; - regs.esi.l = (uint32_t)dir; - __com32.cs_intcall(0x22, ®s, ®s); - 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 +#include +#include + +#include +#include +#include +#include +#include + +#include + +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 #include #include +#include #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. -- 2.7.4