aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-03-06 11:55:57 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-03-06 11:55:57 -0800
commite375515ddc712f1f69ee21337db2a3267caa5d49 (patch)
tree234cecab51fe9bfb341289ce0d0620543f77f047
parentead9bc6ff2fdfffc2f0974bb8de02f54a7671922 (diff)
downloadsyslinux-e375515ddc712f1f69ee21337db2a3267caa5d49.tar.gz
syslinux-e375515ddc712f1f69ee21337db2a3267caa5d49.tar.xz
syslinux-e375515ddc712f1f69ee21337db2a3267caa5d49.zip
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 <hpa@zytor.com>
-rw-r--r--com32/include/syslinux/pmapi.h8
-rw-r--r--com32/lib/sys/file.h6
-rw-r--r--com32/lib/sys/fileclose.c11
-rw-r--r--com32/lib/sys/fileread.c10
-rw-r--r--com32/lib/sys/fstat.c4
-rw-r--r--com32/lib/sys/open.c29
-rw-r--r--com32/lib/sys/openmem.c4
-rw-r--r--com32/lib/sys/zfile.c8
-rw-r--r--core/comboot.inc17
-rw-r--r--core/extern.inc2
-rw-r--r--core/fs/fs.c46
-rw-r--r--core/getc.inc4
-rw-r--r--core/include/fs.h4
-rw-r--r--core/pmapi.c2
-rw-r--r--doc/comboot.txt16
15 files changed, 101 insertions, 70 deletions
diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h
index 34648e52..5631dcba 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 66192fbf..e984f160 100644
--- a/com32/lib/sys/file.h
+++ b/com32/lib/sys/file.h
@@ -39,6 +39,7 @@
#include <sys/types.h>
#include <dev.h>
#include <fcntl.h>
+#include <syslinux/pmapi.h>
/* 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 e005567e..e2c929f2 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(&regs, 0, sizeof regs);
- regs.eax.w[0] = 0x0008; /* Close file */
- regs.esi.w[0] = fp->i.filedes;
-
- __com32.cs_intcall(0x22, &regs, 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 cfd49557..aab99c80 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 6a853933..0ce8cadb 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 94465925..cb7c1b4d 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, &regs, &regs);
-
- 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 33b8de0d..a56a4af8 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 a1213a94..0e6ba916 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 c42df807..7e4c3d6f 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 fbc4759b..301ac0be 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 865f398d..ae261b13 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 47dca1e6..efe60de3 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 14073e53..332607b7 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 96ede130..88a7f34f 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 b970b281..8adff330 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]