From 193430d226a18142f9f61eb2d7adfe45bcc080b4 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Tue, 12 Feb 2008 19:09:46 +0000 Subject: [PATCH] Added test code for testing of directory listing. Added system call prototypes and posix glue for reading a directory. TODO: FS0 should implement the L4_IPC_TAG_READDIR ipc call. --- tasks/libl4/include/l4lib/ipcdefs.h | 1 + tasks/libl4/include/l4lib/os/posix/readdir.h | 7 + tasks/libposix/read.c | 75 ++++++++-- tasks/test0/include/tests.h | 1 + tasks/test0/src/dirtest.c | 138 +++++++++++++++++++ 5 files changed, 210 insertions(+), 12 deletions(-) create mode 100644 tasks/libl4/include/l4lib/os/posix/readdir.h create mode 100644 tasks/test0/src/dirtest.c diff --git a/tasks/libl4/include/l4lib/ipcdefs.h b/tasks/libl4/include/l4lib/ipcdefs.h index 43b80ae..74e16e8 100644 --- a/tasks/libl4/include/l4lib/ipcdefs.h +++ b/tasks/libl4/include/l4lib/ipcdefs.h @@ -39,6 +39,7 @@ #define L4_IPC_TAG_LSEEK 15 #define L4_IPC_TAG_CLOSE 16 #define L4_IPC_TAG_BRK 17 +#define L4_IPC_TAG_READDIR 18 /* Tags for ipc between fs0 and mm0 */ #define L4_IPC_TAG_OPENDATA 25 diff --git a/tasks/libl4/include/l4lib/os/posix/readdir.h b/tasks/libl4/include/l4lib/os/posix/readdir.h new file mode 100644 index 0000000..de6d184 --- /dev/null +++ b/tasks/libl4/include/l4lib/os/posix/readdir.h @@ -0,0 +1,7 @@ +#ifndef __OS_READDIR_H__ +#define __OS_READDIR_H__ + +/* Any os syscall related data that is not in posix */ +ssize_t os_readdir(int fd, void *buf, size_t count); + +#endif diff --git a/tasks/libposix/read.c b/tasks/libposix/read.c index e1faa3d..2533585 100644 --- a/tasks/libposix/read.c +++ b/tasks/libposix/read.c @@ -1,5 +1,5 @@ /* - * l4/posix glue for read() + * l4/posix glue for read() / sys_readdir() * * Copyright (C) 2007 Bahadir Balban */ @@ -10,35 +10,86 @@ #include #include #include +#include -static inline int l4_read(int fd, void *buf, size_t count) +static inline int l4_readdir(int fd, void *buf, size_t count) { - size_t rcnt; + size_t cnt; write_mr(L4SYS_ARG0, fd); write_mr(L4SYS_ARG1, (unsigned long)buf); write_mr(L4SYS_ARG2, count); /* Call pager with shmget() request. Check ipc error. */ - if ((errno = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_READ)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, errno); - return -1; + if ((cnt = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_READDIR)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, cnt); + return cnt; } /* Check if syscall itself was successful */ - if ((rcnt = l4_get_retval()) < 0) { - printf("%s: READ Error: %d.\n", __FUNCTION__, (int)rcnt); - errno = (int)rcnt; - return -1; + if ((cnt = l4_get_retval()) < 0) { + printf("%s: READ Error: %d.\n", __FUNCTION__, (int)cnt); + return cnt; } - return rcnt; + return cnt; +} + +static inline int l4_read(int fd, void *buf, size_t count) +{ + size_t cnt; + + write_mr(L4SYS_ARG0, fd); + write_mr(L4SYS_ARG1, (unsigned long)buf); + write_mr(L4SYS_ARG2, count); + + /* Call pager with shmget() request. Check ipc error. */ + if ((cnt = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_READ)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, cnt); + return cnt; + } + /* Check if syscall itself was successful */ + if ((cnt = l4_get_retval()) < 0) { + printf("%s: READ Error: %d.\n", __FUNCTION__, (int)cnt); + return cnt; + + } + return cnt; } ssize_t read(int fd, void *buf, size_t count) { + int ret; + if (!count) return 0; - return l4_read(fd, buf, count); + ret = l4_read(fd, buf, count); + + /* If error, return positive error code */ + if (ret < 0) { + errno = -ret; + return -1; + } + /* else return value */ + return ret; + +} + +ssize_t os_readdir(int fd, void *buf, size_t count) +{ + int ret; + + if (!count) + return 0; + + ret = l4_readdir(fd, buf, count); + + /* If error, return positive error code */ + if (ret < 0) { + errno = -ret; + return -1; + } + /* else return value */ + return ret; } diff --git a/tasks/test0/include/tests.h b/tasks/test0/include/tests.h index 1b9b506..8b83587 100644 --- a/tasks/test0/include/tests.h +++ b/tasks/test0/include/tests.h @@ -3,5 +3,6 @@ int shmtest(void); int mmaptest(void); +int dirtest(void); #endif /* __TEST0_TESTS_H__ */ diff --git a/tasks/test0/src/dirtest.c b/tasks/test0/src/dirtest.c new file mode 100644 index 0000000..b433226 --- /dev/null +++ b/tasks/test0/src/dirtest.c @@ -0,0 +1,138 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DENTS_TOTAL 50 + +void print_fsize(struct stat *s) +{ + printf("%d", s->st_size); +} + +void print_flink(struct stat *s) +{ + printf("%d", s->st_nlink); +} + +void print_fuser(struct stat *s) +{ + printf("%d", s->st_uid); + printf("%c", ' '); + printf("%c", ' '); + printf("%d", s->st_gid); +} + +void print_ftype(struct stat *s) +{ + unsigned int type = s->st_mode & S_IFMT; + + if (type == S_IFDIR) + printf("%c", 'd'); + else if (type == S_IFSOCK) + printf("%c", 's'); + else if (type == S_IFCHR) + printf("%c", 'c'); + else if (type == S_IFLNK) + printf("%c", 'l'); + else if (type == S_IFREG) + printf("%c", '-'); +} + +void print_fperm(struct stat *s) +{ + if (s->st_mode & S_IRUSR) + printf("%c", 'r'); + else + printf("%c", '-'); + if (s->st_mode & S_IWUSR) + printf("%c", 'w'); + else + printf("%c", '-'); + if (s->st_mode & S_IXUSR) + printf("%c", 'x'); + else + printf("%c", '-'); +} + +void print_fstat(struct stat *s) +{ + print_ftype(s); + print_fperm(s); + printf("%c", ' '); + printf("%c", ' '); + print_fsize(s); + printf("%c", ' '); +} + +void print_dirents(char *path, void *buf, int cnt) +{ + int i = 0; + struct dirent *dp = buf; + // struct stat statbuf; + char pathbuf[256]; + + strncpy(pathbuf, path, 256); + while (cnt > 0) { + strcpy(pathbuf, path); + strcpy(&pathbuf[strlen(pathbuf)],"/"); + strcpy(&pathbuf[strlen(pathbuf)],dp->d_name); + //printf("Dirent %d:\n", i); + //printf("Inode: %d\n", dp->d_ino); + //printf("Offset: %d\n", dp->d_off); + //printf("Reclen: %d\n", dp->d_reclen); + //if (stat(pathbuf, &statbuf) < 0) + // perror("STAT"); + // print_fstat(&statbuf); + printf("%s\n", dp->d_name); + cnt -= dp->d_reclen; + dp = (struct dirent *)((void *)dp + dp->d_reclen); + i++; + } +} + +int lsdir(char *path) +{ + int fd; + struct dirent dents[DENTS_TOTAL]; + int bytes; + + memset(dents, 0, sizeof(struct dirent) * DENTS_TOTAL); + + if ((fd = open(path, O_RDONLY)) < 0) { + perror("OPEN"); + return 0; + } else + // printf("OPEN OK.\n"); + + if ((bytes = os_readdir(fd, dents, sizeof(struct dirent) * DENTS_TOTAL)) < 0) { + perror("GETDENTS"); + return 0; + } + //printf("GETDENTS OK.\n"); + print_dirents(path, dents, bytes); + + return 0; +} + + +int dirtest(void) +{ + printf("\nlsdir current directory:\n"); + lsdir("."); + printf("\nlsdir root directory:\n"); + lsdir("/"); + + return 0; +} +