Add 32-bit API calls for open file and close file.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
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_ *);
#include <sys/types.h>
#include <dev.h>
#include <fcntl.h>
+#include <syslinux/pmapi.h>
/* Device structure; contains the relevant operations */
/* 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 */
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;
}
{
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;
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;
}
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;
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);
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;
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;
}
fp->iop = &gzip_file_dev;
- fp->i.length = -1; /* Unknown */
+ fp->i.fd.size = -1; /* Unknown */
return 0;
}
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;
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
; 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
; 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
;
;
comapi_close:
mov si,P_SI
- pm_call close_file
+ pm_call pm_close_file
clc
ret
; 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
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) {
}
}
+void pm_close_file(com32sys_t *regs)
+{
+ close_file(regs->esi.w[0]);
+}
+
/*
* it will do:
* initialize the memory management function;
.ret: ret
.stack_full:
- pm_call close_file
+ pm_call pm_close_file
xor ax,ax ; ZF <- 1
pop bx
ret
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
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);
.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,
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
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]