Add 32-bit versions of open file/close file
authorH. Peter Anvin <hpa@zytor.com>
Sat, 6 Mar 2010 19:55:57 +0000 (11:55 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 6 Mar 2010 19:55:57 +0000 (11:55 -0800)
Add 32-bit API calls for open file and close file.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
15 files changed:
com32/include/syslinux/pmapi.h
com32/lib/sys/file.h
com32/lib/sys/fileclose.c
com32/lib/sys/fileread.c
com32/lib/sys/fstat.c
com32/lib/sys/open.c
com32/lib/sys/openmem.c
com32/lib/sys/zfile.c
core/comboot.inc
core/extern.inc
core/fs/fs.c
core/getc.inc
core/include/fs.h
core/pmapi.c
doc/comboot.txt

index 34648e5..5631dcb 100644 (file)
 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_ *);
index 66192fb..e984f16 100644 (file)
@@ -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 */
index e005567..e2c929f 100644 (file)
 
 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;
 }
index cfd4955..aab99c8 100644 (file)
@@ -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;
index 6a85393..0ce8cad 100644 (file)
@@ -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;
index 9446592..cb7c1b4 100644 (file)
@@ -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;
 
index 33b8de0..a56a4af 100644 (file)
@@ -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;
index a1213a9..0e6ba91 100644 (file)
@@ -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
index c42df80..7e4c3d6 100644 (file)
@@ -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
 
index fbc4759..301ac0b 100644 (file)
@@ -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
index 865f398..ae261b1 100644 (file)
@@ -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;
index 47dca1e..efe60de 100644 (file)
@@ -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
index 14073e5..332607b 100644 (file)
@@ -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);
index 96ede13..88a7f34 100644 (file)
@@ -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,
index b970b28..8adff33 100644 (file)
@@ -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]