diff --git a/fs/initrd.c b/fs/initrd.c index 36d07ee8..11c2593b 100644 --- a/fs/initrd.c +++ b/fs/initrd.c @@ -57,51 +57,86 @@ typedef struct { static ssize_t initrd_read(fildes_t* file, uint8_t* buffer, size_t size) { - uint32_t i, pos = 0, found = 0; - off_t offset = 0; - char* data = NULL; vfs_node_t* node = file->node; - block_list_t* blist = &node->block_list; - if (file->flags & O_WRONLY) - return -EACCES; + if (node->type != FS_DIRECTORY) { + /*********** The original read function ****************/ + uint32_t i, pos = 0, found = 0; + off_t offset = 0; + char* data = NULL; + block_list_t* blist = &node->block_list; - /* init the tmp offset */ - offset = file->offset; + if (file->flags & O_WRONLY) + return -EACCES; - /* searching for the valid data block */ - if (offset) { - pos = offset / node->block_size; - offset = offset % node->block_size; - } - do { - for(i=0; idata[i]) { - found++; - if (found > pos) - data = (char*) blist->data[i]; - } + /* init the tmp offset */ + offset = file->offset; + + /* searching for the valid data block */ + if (offset) { + pos = offset / node->block_size; + offset = offset % node->block_size; } + do { + for(i=0; idata[i]) { + found++; + if (found > pos) + data = (char*) blist->data[i]; + } + } - blist = blist->next; - } while(blist && !data); + blist = blist->next; + } while(blist && !data); - if (BUILTIN_EXPECT(!data, 0)) - return 0; + if (BUILTIN_EXPECT(!data, 0)) + return 0; - /* - * If the data block is not large engough, - * we copy only the rest of the current block. - * The user has to restart the read operation - * for the next block. - */ - if ((offset + size) >= node->block_size) - size = node->block_size - offset; + /* + * If the data block is not large engough, + * we copy only the rest of the current block. + * The user has to restart the read operation + * for the next block. + */ + if ((offset + size) >= node->block_size) + size = node->block_size - offset; - memcpy(buffer, data + offset, size); + memcpy(buffer, data + offset, size); - file->offset += size; - return size; + file->offset += size; + return size; + } else { + /*********** The emulated readdir funtion *************/ + uint32_t i, j, k, count; + uint32_t index = file->offset; + dirent_t* dirent; + dir_block_t* dirblock; + block_list_t* blist = &node->block_list; + + do { + for(i=0,count=0; idata[i]; + for(j=0; dirblock && jentries[j]; + if (dirent->vfs_node) { + count++; + if (count > index) { + k=0; + do { + buffer[k] = dirent->name[0]; + k++; + } while(dirent->name[k] != '\0'); + return k; + } + } + } + } + + blist = blist->next; + } while(blist); + + return -EINVAL; + } } static ssize_t initrd_write(fildes_t* file, uint8_t* buffer, size_t size) @@ -343,6 +378,7 @@ static vfs_node_t* initrd_mkdir(vfs_node_t* node, const char* name) memset(new_node, 0x00, sizeof(vfs_node_t)); new_node->type = FS_DIRECTORY; + new_node->read = &initrd_read; new_node->readdir = &initrd_readdir; new_node->finddir = &initrd_finddir; new_node->mkdir = &initrd_mkdir; diff --git a/kernel/syscall.c b/kernel/syscall.c index 9dc1722a..f0f5521f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -164,7 +164,6 @@ static int sys_read(int fd, const char* buf, size_t len) return read_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len); } - #if defined(CONFIG_LWIP) && LWIP_SOCKET static int sys_socket(int domain, int type, int protocol) { diff --git a/newlib/examples/hello.c b/newlib/examples/hello.c index 2ea2eeae..ad00a38e 100644 --- a/newlib/examples/hello.c +++ b/newlib/examples/hello.c @@ -22,6 +22,7 @@ #include #include #include +#include #undef errno extern int errno; @@ -46,6 +47,8 @@ int main(int argc, char** argv) { int i, testfile; char* teststr; + DIR* testdir; + dirent_t* testdirent; for(i=0; environ[i]; i++) printf("environ[%d] = %s\n", i, environ[i]); @@ -56,14 +59,22 @@ int main(int argc, char** argv) if (!teststr) return EFAULT; - testfile = open("/bin/test/test.txt", O_CREAT | O_EXCL, "wr"); + testfile = open("/bin/test.txt", O_CREAT | O_EXCL, "wr"); if (testfile < 1) printf("error"); - write(testfile, "hello in new file '/bin/test/test.txt'", 34); + write(testfile, "hello in new file '/bin/test.txt'", 34); lseek(testfile, 0, SEEK_SET); read(testfile, teststr, 100); close(testfile); + testdir = opendir("/bin/"); + if (testdir < 1) + printf("error"); + testdirent = readdir(testdir); + printf("1. Dirent: %s", testdirent->d_name); + closedir(testdir); + + printf("read from new file: %s\n", teststr); return errno; diff --git a/newlib/src/libgloss/metalsvm/include/sys/dirent.h b/newlib/src/libgloss/metalsvm/include/sys/dirent.h index d12acba5..3e324a2e 100644 --- a/newlib/src/libgloss/metalsvm/include/sys/dirent.h +++ b/newlib/src/libgloss/metalsvm/include/sys/dirent.h @@ -7,6 +7,8 @@ * Sean Eric Fagan, sef@Kithrup.COM */ +#include "../../../../../include/metalsvm/config.h" + typedef struct _dirdesc { int dd_fd; long dd_loc; @@ -30,7 +32,7 @@ typedef struct dirent { off_t d_off; unsigned short d_reclen; /* we need better syntax for variable-sized arrays */ - char d_name[1]; + char d_name[MAX_FNAME]; } dirent_t; #endif diff --git a/newlib/src/libgloss/metalsvm/readdir.c b/newlib/src/libgloss/metalsvm/readdir.c index 0c32b69d..7462a621 100644 --- a/newlib/src/libgloss/metalsvm/readdir.c +++ b/newlib/src/libgloss/metalsvm/readdir.c @@ -38,6 +38,7 @@ #include <_syslist.h> #include #include +#include #undef errno extern int errno; #include "warning.h" @@ -47,9 +48,20 @@ dirent_t* _DEFUN (readdir, (dirp), DIR *dirp) { - dirent_t* dirent; + dirent_t* dirent = malloc(sizeof(dirent_t)); + int ret; + /* init */ + dirent->d_ino = 0; + dirent->d_off = 0; + dirent->d_reclen = MAX_FNAME; + dirent->d_name[0] = '\n'; - read(dirp->dd_fd, dirent, 0); + ret = read(dirp->dd_fd, dirent->d_name, MAX_FNAME); + + if (ret < 0) { + errno = -ret; + return NULL; + } return dirent; }