From e375515ddc712f1f69ee21337db2a3267caa5d49 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 6 Mar 2010 11:55:57 -0800 Subject: [PATCH] Add 32-bit versions of open file/close file Add 32-bit API calls for open file and close file. Signed-off-by: H. Peter Anvin --- com32/include/syslinux/pmapi.h | 8 ++++++++ com32/lib/sys/file.h | 6 ++---- com32/lib/sys/fileclose.c | 11 ++-------- com32/lib/sys/fileread.c | 10 ++++----- com32/lib/sys/fstat.c | 4 ++-- com32/lib/sys/open.c | 29 +++----------------------- com32/lib/sys/openmem.c | 4 ++-- com32/lib/sys/zfile.c | 8 +++++--- core/comboot.inc | 17 +++------------- core/extern.inc | 2 +- core/fs/fs.c | 46 ++++++++++++++++++++++++++++++++++++++++-- core/getc.inc | 4 ++-- core/include/fs.h | 4 ++++ core/pmapi.c | 2 ++ doc/comboot.txt | 16 +++++++++++++++ 15 files changed, 101 insertions(+), 70 deletions(-) diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h index 34648e5..5631dcb 100644 --- a/com32/include/syslinux/pmapi.h +++ b/com32/include/syslinux/pmapi.h @@ -45,11 +45,19 @@ struct _DIR_; struct dirent; +struct com32_filedata { + size_t size; /* File size */ + int blocklg2; /* log2(block size) */ + uint16_t handle; /* File handle */ +}; + struct com32_pmapi { void *(*lmalloc)(size_t); void (*lfree)(void *); + int (*open_file)(const char *, struct com32_filedata *); size_t (*read_file)(uint16_t *, void *, size_t); + void (*close_file)(uint16_t); struct _DIR_ *(*opendir)(const char *); struct dirent *(*readdir)(struct _DIR_ *); diff --git a/com32/lib/sys/file.h b/com32/lib/sys/file.h index 66192fb..e984f16 100644 --- a/com32/lib/sys/file.h +++ b/com32/lib/sys/file.h @@ -39,6 +39,7 @@ #include #include #include +#include /* Device structure; contains the relevant operations */ @@ -87,11 +88,8 @@ struct file_info { /* Structure used for input blocking */ struct { - int blocklg2; /* Blocksize log 2 */ + struct com32_filedata fd; size_t offset; /* Current file offset */ - size_t length; /* Total file length */ - uint16_t filedes; /* File descriptor */ - uint16_t _filler; /* Unused */ size_t nbytes; /* Number of bytes available in buffer */ char *datap; /* Current data pointer */ void *pvt; /* Private pointer for driver */ diff --git a/com32/lib/sys/fileclose.c b/com32/lib/sys/fileclose.c index e005567..e2c929f 100644 --- a/com32/lib/sys/fileclose.c +++ b/com32/lib/sys/fileclose.c @@ -38,15 +38,8 @@ int __file_close(struct file_info *fp) { - com32sys_t regs; - - if (fp->i.filedes) { - memset(®s, 0, sizeof regs); - regs.eax.w[0] = 0x0008; /* Close file */ - regs.esi.w[0] = fp->i.filedes; - - __com32.cs_intcall(0x22, ®s, NULL); - } + if (fp->i.fd.handle) + __com32.cs_pm->close_file(fp->i.fd.handle); return 0; } diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c index cfd4955..aab99c8 100644 --- a/com32/lib/sys/fileread.c +++ b/com32/lib/sys/fileread.c @@ -42,8 +42,8 @@ int __file_get_block(struct file_info *fp) { ssize_t bytes_read; - bytes_read = __com32.cs_pm->read_file(&fp->i.filedes, fp->i.buf, - MAXBLOCK >> fp->i.blocklg2); + bytes_read = __com32.cs_pm->read_file(&fp->i.fd.handle, fp->i.buf, + MAXBLOCK >> fp->i.fd.blocklg2); if (!bytes_read) { errno = EIO; return -1; @@ -62,13 +62,13 @@ ssize_t __file_read(struct file_info * fp, void *buf, size_t count) while (count) { if (fp->i.nbytes == 0) { - if (fp->i.offset >= fp->i.length || !fp->i.filedes) + if (fp->i.offset >= fp->i.fd.size || !fp->i.fd.handle) return n; /* As good as it gets... */ if (count > MAXBLOCK) { /* Large transfer: copy directly, without buffering */ - ncopy = __com32.cs_pm->read_file(&fp->i.filedes, bufp, - count >> fp->i.blocklg2); + ncopy = __com32.cs_pm->read_file(&fp->i.fd.handle, bufp, + count >> fp->i.fd.blocklg2); if (!ncopy) { errno = EIO; return n ? n : -1; diff --git a/com32/lib/sys/fstat.c b/com32/lib/sys/fstat.c index 6a85393..0ce8cad 100644 --- a/com32/lib/sys/fstat.c +++ b/com32/lib/sys/fstat.c @@ -45,14 +45,14 @@ int fstat(int fd, struct stat *buf) } if (fp->iop->flags & __DEV_FILE) { - if (fp->i.length == (uint32_t) - 1) { + if (fp->i.fd.size == (uint32_t) - 1) { /* File of unknown length, report it as a socket (it probably really is, anyway!) */ buf->st_mode = S_IFSOCK | 0444; buf->st_size = 0; } else { buf->st_mode = S_IFREG | 0444; - buf->st_size = fp->i.length; + buf->st_size = fp->i.fd.size; } } else { buf->st_mode = S_IFCHR | 0666; diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c index 9446592..cb7c1b4 100644 --- a/com32/lib/sys/open.c +++ b/com32/lib/sys/open.c @@ -52,10 +52,8 @@ const struct input_dev __file_dev = { int open(const char *pathname, int flags, ...) { - com32sys_t regs; - int fd; + int fd, handle; struct file_info *fp; - char *lm_pathname; fd = opendev(&__file_dev, NULL, flags); @@ -64,31 +62,10 @@ int open(const char *pathname, int flags, ...) fp = &__file_info[fd]; - lm_pathname = lstrdup(pathname); - if (!lm_pathname) + handle = __com32.cs_pm->open_file(pathname, &fp->i.fd); + if (handle < 0) return -1; - regs.eax.w[0] = 0x0006; - regs.esi.w[0] = OFFS(lm_pathname); - regs.es = SEG(lm_pathname); - - __com32.cs_intcall(0x22, ®s, ®s); - - lfree(lm_pathname); - - if ((regs.eflags.l & EFLAGS_CF) || regs.esi.w[0] == 0) { - close(fd); - errno = ENOENT; - return -1; - } - - { - uint16_t blklg2; - asm("bsrw %1,%0" : "=r" (blklg2) : "rm" (regs.ecx.w[0])); - fp->i.blocklg2 = blklg2; - } - fp->i.length = regs.eax.l; - fp->i.filedes = regs.esi.w[0]; fp->i.offset = 0; fp->i.nbytes = 0; diff --git a/com32/lib/sys/openmem.c b/com32/lib/sys/openmem.c index 33b8de0..a56a4af 100644 --- a/com32/lib/sys/openmem.c +++ b/com32/lib/sys/openmem.c @@ -52,9 +52,9 @@ int openmem(const void *base, size_t len, int flags) fp = &__file_info[fd]; - fp->i.length = fp->i.nbytes = len; + fp->i.fd.size = fp->i.nbytes = len; fp->i.datap = (void *)base; - fp->i.filedes = 0; /* No actual file */ + fp->i.fd.handle = 0; /* No actual file */ fp->i.offset = 0; return fd; diff --git a/com32/lib/sys/zfile.c b/com32/lib/sys/zfile.c index a1213a9..0e6ba91 100644 --- a/com32/lib/sys/zfile.c +++ b/com32/lib/sys/zfile.c @@ -75,7 +75,7 @@ static int gzip_file_init(struct file_info *fp) } fp->iop = &gzip_file_dev; - fp->i.length = -1; /* Unknown */ + fp->i.fd.size = -1; /* Unknown */ return 0; } @@ -92,7 +92,7 @@ static ssize_t gzip_file_read(struct file_info *fp, void *ptr, size_t n) zs->next_out = p; zs->avail_out = n; - if (!zs->avail_in && fp->i.filedes) { + if (!zs->avail_in && fp->i.fd.handle) { if (__file_get_block(fp)) return nout ? nout : -1; @@ -154,7 +154,9 @@ int zopen(const char *pathname, int flags, ...) if (__file_get_block(fp)) goto err; - if (fp->i.nbytes >= 14 && (uint8_t) fp->i.buf[0] == 037 && (uint8_t) fp->i.buf[1] == 0213 && /* gzip */ + if (fp->i.nbytes >= 14 && + (uint8_t) fp->i.buf[0] == 037 && + (uint8_t) fp->i.buf[1] == 0213 && /* gzip */ fp->i.buf[2] == 8) /* deflate */ rv = gzip_file_init(fp); else diff --git a/core/comboot.inc b/core/comboot.inc index c42df80..7e4c3d6 100644 --- a/core/comboot.inc +++ b/core/comboot.inc @@ -63,7 +63,7 @@ ; Looks like a COMBOOT image but too large comboot_too_large: - pm_call close_file + pm_call pm_close_file mov si,err_comlarge call writestr jmp enter_command @@ -517,18 +517,7 @@ comapi_textmode: ; INT 22h AX=0006h Open file ; comapi_open: - push ds - mov ds,P_ES - mov si,P_SI - mov di,InitRD - pm_call pm_mangle_name - pop ds - pm_call pm_searchdir - jz comapi_err - mov P_EAX,eax - mov P_CX,SECTOR_SIZE - mov P_SI,si - clc + pm_call pm_open_file ret ; @@ -551,7 +540,7 @@ comapi_read: ; comapi_close: mov si,P_SI - pm_call close_file + pm_call pm_close_file clc ret diff --git a/core/extern.inc b/core/extern.inc index fbc4759..301ac0b 100644 --- a/core/extern.inc +++ b/core/extern.inc @@ -14,7 +14,7 @@ ; fs.c extern fs_init, pm_searchdir, getfssec, pm_mangle_name, load_config - extern close_file + extern pm_open_file, pm_close_file ; chdir.c extern pm_realpath diff --git a/core/fs/fs.c b/core/fs/fs.c index 865f398..ae261b1 100644 --- a/core/fs/fs.c +++ b/core/fs/fs.c @@ -293,9 +293,46 @@ err_no_close: return -1; } -void close_file(com32sys_t *regs) +int open_file(const char *name, struct com32_filedata *filedata) +{ + int rv; + struct file *file; + char mangled_name[FILENAME_MAX]; + + mangle_name(mangled_name, name); + rv = searchdir(mangled_name); + + if (rv >= 0) { + file = handle_to_file(rv); + filedata->size = file->file_len; + filedata->blocklg2 = SECTOR_SHIFT(file->fs); + filedata->handle = rv; + } + return rv; +} + +void pm_open_file(com32sys_t *regs) +{ + int rv; + struct file *file; + const char *name = MK_PTR(regs->es, regs->esi.w[0]); + char mangled_name[FILENAME_MAX]; + + mangle_name(mangled_name, name); + rv = searchdir(mangled_name); + if (rv < 0) { + regs->eflags.l |= EFLAGS_CF; + } else { + file = handle_to_file(rv); + regs->eflags.l &= ~EFLAGS_CF; + regs->eax.l = file->file_len; + regs->ecx.w[0] = SECTOR_SIZE(file->fs); + regs->esi.w[0] = rv; + } +} + +void close_file(uint16_t handle) { - uint16_t handle = regs->esi.w[0]; struct file *file; if (handle) { @@ -304,6 +341,11 @@ void close_file(com32sys_t *regs) } } +void pm_close_file(com32sys_t *regs) +{ + close_file(regs->esi.w[0]); +} + /* * it will do: * initialize the memory management function; diff --git a/core/getc.inc b/core/getc.inc index 47dca1e..efe60de 100644 --- a/core/getc.inc +++ b/core/getc.inc @@ -83,7 +83,7 @@ openfd: .ret: ret .stack_full: - pm_call close_file + pm_call pm_close_file xor ax,ax ; ZF <- 1 pop bx ret @@ -178,7 +178,7 @@ close: push si mov bx,[CurrentGetC] mov si,[bx+gc_file] - pm_call close_file + pm_call pm_close_file add bx,getc_file_size mov [CurrentGetC],bx pop si diff --git a/core/include/fs.h b/core/include/fs.h index 14073e5..332607b 100644 --- a/core/include/fs.h +++ b/core/include/fs.h @@ -205,6 +205,10 @@ void mangle_name(char *, const char *); int searchdir(const char *name); void _close_file(struct file *); size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors); +int open_file(const char *name, struct com32_filedata *filedata); +void pm_open_file(com32sys_t *); +void close_file(uint16_t handle); +void pm_close_file(com32sys_t *); /* chdir.c */ void pm_realpath(com32sys_t *regs); diff --git a/core/pmapi.c b/core/pmapi.c index 96ede13..88a7f34 100644 --- a/core/pmapi.c +++ b/core/pmapi.c @@ -22,7 +22,9 @@ const struct com32_pmapi pm_api_vector = .lmalloc = pmapi_lmalloc, /* Allocate low memory */ .lfree = free, /* Free low memory */ + .open_file = open_file, .read_file = pmapi_read_file, + .close_file = close_file, .opendir = opendir, .readdir = readdir, diff --git a/doc/comboot.txt b/doc/comboot.txt index b970b28..8adff33 100644 --- a/doc/comboot.txt +++ b/doc/comboot.txt @@ -320,6 +320,16 @@ AX=0006h [2.08] Open file In 3.70 or later, EAX can contain -1 indicating that the file length is unknown. + 32-BIT VERSION: + + int cs_pm->open_file(const char *filename, struct com32_filedata *data) + + filename - null-terminated filename + data - pointer to a file data buffer + + Returns the file handle, or -1 on failure. + The file data buffer contains block size and file size. + AX=0007h [2.08] Read file @@ -373,6 +383,12 @@ AX=0008h [2.08] Close file WARNING: Calling this function with an invalid file handle will probably crash the system. + 32-BIT VERSION: + + void cs_pm->close_file(uint16_t handle) + + handle - file handle to close + AX=0009h [2.00] Call PXE Stack [PXELINUX ONLY] -- 2.7.4