Gene Cumm
2009-Feb-11 03:18 UTC
[syslinux] [PATCH 1/1] COM32 API: Add functions for directory use
From: Gene Cumm <gene.cumm at gmail.com> COM32: Add directory functions getcwd(), opendir(), readdir() and closedir(). This depends on the patch that I just submitted creating the COMBOOT API calls. Signed-off-by: Gene Cumm <gene.cumm at gmail.com> --- The intention is to create the library calls with (hopefully) POSIX compliance such that a small application written to use these 4 POSIX calls will work properly. diff --git a/com32/include/dirent.h b/com32/include/dirent.h new file mode 100644 index 0000000..956b911 --- /dev/null +++ b/com32/include/dirent.h @@ -0,0 +1,36 @@ +/* + * dirent.h + */ + +#ifndef _DIRENT_H +#define _DIRENT_H + +#include <klibc/extern.h> +#include <klibc/compiler.h> +#include <stddef.h> +#include <sys/types.h> + +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + +struct dirent { + long d_ino; /* Inode/File number */ + off_t d_size; /* Size of file */ + mode_t d_mode; /* Type of file */ + char d_name[NAME_MAX + 1]; +}; + +typedef struct { + short dd_stat; /* status return from last lookup */ + uint16_t dd_fd; + size_t dd_sect; + char dd_name[NAME_MAX + 1]; /* directory */ +} DIR; + +__extern DIR *opendir(const char *); +__extern struct dirent *readdir(DIR *); +__extern int closedir(DIR *); +__extern DIR *fdopendir(int); + +#endif /* Not _DIRENT_H */ diff --git a/com32/include/unistd.h b/com32/include/unistd.h index d0b8309..c0b52d6 100644 --- a/com32/include/unistd.h +++ b/com32/include/unistd.h @@ -22,6 +22,9 @@ __extern int isatty(int); __extern int getscreensize(int, int *, int *); +__extern char *getcwd(char *, int); +__extern int chdir(const char *); + /* Standard file descriptor numbers. */ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 91405a0..0cc4061 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -21,6 +21,8 @@ LIBOBJS = \ asprintf.o vasprintf.o strlcpy.o strlcat.o \ vsscanf.o zalloc.o \ \ + opendir.o readdir.o closedir.o getcwd.o chdir.o fdopendir.o \ + \ libgcc/__ashldi3.o libgcc/__udivdi3.o \ libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o \ libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o \ diff --git a/com32/lib/chdir.c b/com32/lib/chdir.c new file mode 100644 index 0000000..88dceec --- /dev/null +++ b/com32/lib/chdir.c @@ -0,0 +1,13 @@ +/* + * chdir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +int chdir(const char *path) +{ + errno = ENOSYS; + return -1; +} diff --git a/com32/lib/closedir.c b/com32/lib/closedir.c new file mode 100644 index 0000000..8a0430e --- /dev/null +++ b/com32/lib/closedir.c @@ -0,0 +1,29 @@ +/* + * closedir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +int closedir(DIR *dir) +{ + int rv; + com32sys_t regs; + if (dir == NULL) { + rv = 0; + } else { + memset(®s, 0, sizeof regs); /* ?Needed? */ + regs.eax.w[0] = 0x0022; + regs.esi.w[0] = dir->dd_fd; + __com32.cs_intcall(0x22, ®s, ®s); + free(dir); /* garbage collection? */ + rv = 0; + } + return rv; +} diff --git a/com32/lib/fdopendir.c b/com32/lib/fdopendir.c new file mode 100644 index 0000000..83a7ac6 --- /dev/null +++ b/com32/lib/fdopendir.c @@ -0,0 +1,13 @@ +/* + * fdopendir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +DIR *fdopendir(int __fd) +{ + errno = ENOSYS; + return NULL; +} diff --git a/com32/lib/getcwd.c b/com32/lib/getcwd.c new file mode 100644 index 0000000..95008bb --- /dev/null +++ b/com32/lib/getcwd.c @@ -0,0 +1,29 @@ +/* + * getcwd.c + */ + +#include <syslinux/config.h> +#include <klibc/compiler.h> +#include <com32.h> + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +char *getcwd(char *buf, size_t size) +{ + static com32sys_t reg; + char *pwdstr, *ret; + + reg.eax.w[0] = 0x001f; + __intcall(0x22, ®, ®); + pwdstr = MK_PTR(reg.es, reg.ebx.w[0]); + if ((strlen(pwdstr) < size) && (buf != NULL)) { + strcpy(buf, pwdstr); + ret = buf; + } else { + ret = NULL; + errno = ERANGE; + } + return ret; +} diff --git a/com32/lib/opendir.c b/com32/lib/opendir.c new file mode 100644 index 0000000..aa2ba5b --- /dev/null +++ b/com32/lib/opendir.c @@ -0,0 +1,41 @@ +/* + * opendir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + + +DIR *opendir(const char *pathname) +{ + DIR *newdir; + com32sys_t regs; + + newdir = NULL; + + strlcpy(__com32.cs_bounce, pathname, __com32.cs_bounce_size); + + regs.eax.w[0] = 0x0020; + regs.esi.w[0] = OFFS(__com32.cs_bounce); + regs.es = SEG(__com32.cs_bounce); + + __com32.cs_intcall(0x22, ®s, ®s); + + if (!(regs.eflags.l & EFLAGS_CF)) { + /* Initialization: malloc() then zero */ + newdir = calloc(1, sizeof(DIR)); + strcpy(newdir->dd_name, pathname); + newdir->dd_fd = regs.esi.w[0]; + newdir->dd_sect = regs.eax.l; + newdir->dd_stat = 0; + } + + /* We're done */ + return newdir; +} diff --git a/com32/lib/readdir.c b/com32/lib/readdir.c new file mode 100644 index 0000000..bfa5252 --- /dev/null +++ b/com32/lib/readdir.c @@ -0,0 +1,54 @@ +/* + * readdir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +struct dirent *readdir(DIR *dir) +{ + struct dirent *newde; + com32sys_t regs; + + newde = NULL; + if ((dir != NULL) && (dir->dd_fd != 0) && (dir->dd_stat >= 0)) { + memset(__com32.cs_bounce, 0, 32); + memset(®s, 0, sizeof(regs)); + + regs.eax.w[0] = 0x0021; + regs.esi.w[0] = dir->dd_fd; + regs.edi.w[0] = OFFS(__com32.cs_bounce); + regs.es = SEG(__com32.cs_bounce); + + __com32.cs_intcall(0x22, ®s, ®s); + + /* Don't do this as we won't be able to rewind. + dir->dd_fd = regs.esi.w[0]; /* Shouldn't be needed? */ + if ((!(regs.eflags.l & EFLAGS_CF)) && (regs.esi.w[0] != 0)) { + newde = calloc(1, sizeof(newde)); + if (newde != NULL) { + strcpy(newde->d_name, __com32.cs_bounce); + newde->d_mode = regs.edx.b[0]; + newde->d_size = regs.eax.l; + newde->d_ino = regs.ebx.l; + dir->dd_stat = 1; + } else { + dir->dd_stat = -2; + errno = ENOMEM; + } + } else { + dir->dd_stat = -1; + errno = EIO; /* Is this the right nmber? */ + } + } else { + errno = EBADF; + } + + return newde; +}
H. Peter Anvin
2009-Feb-11 05:33 UTC
[syslinux] [PATCH 1/1] COM32 API: Add functions for directory use
Gene Cumm wrote:> From: Gene Cumm <gene.cumm at gmail.com> > > COM32: Add directory functions getcwd(), opendir(), readdir() and closedir(). > > This depends on the patch that I just submitted creating the COMBOOT API calls. > > Signed-off-by: Gene Cumm <gene.cumm at gmail.com>Applied to the "dir" branch, thanks! -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.