From 675c47f1b376c2e65a6130c0f0ceab53cbb90556 Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Wed, 28 Sep 2011 00:10:54 +0200 Subject: [PATCH] add basic support for syscall stat --- include/metalsvm/fs.h | 24 ++++++++++++++++++++++++ kernel/syscall.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/include/metalsvm/fs.h b/include/metalsvm/fs.h index b281c8be..59e3eaa4 100644 --- a/include/metalsvm/fs.h +++ b/include/metalsvm/fs.h @@ -165,6 +165,30 @@ typedef struct { char entries[MAX_DATAENTRIES]; } data_block_t; + +/* Time Value Specification Structures, P1003.1b-1993, p. 261 */ +struct timespec { + long tv_sec; /* Seconds */ + long tv_nsec; /* Nanoseconds */ +}; + +struct stat +{ + uint16_t st_dev; /* ID of device containing file */ + uint16_t st_ino; /* inode number */ + uint32_t st_mode; /* protection */ + unsigned short st_nlink; /* number of hard links */ + uint16_t st_uid; /* user ID of owner */ + uint16_t st_gid; /* group ID of owner */ + uint16_t st_rdev; /* device ID (if special file) */ + off_t st_size; /* total size, in bytes */ + struct timespec st_atim; /* time of last access */ + struct timespec st_mtim; /* time of last modification */ + struct timespec st_ctim; /* time of last status change */ + uint32_t st_blksize; /* blocksize for filesystem I/O */ + uint32_t st_blocks; /* number of blocks allocated */ +} stat_t; + extern vfs_node_t* fs_root; // The root of the filesystem. /** @defgroup fsfunc FS related functions diff --git a/kernel/syscall.c b/kernel/syscall.c index f2d25d8c..cf956ecf 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -98,6 +98,33 @@ static int sys_dup(int fd) return new_fd; } +static int sys_stat(const char* name, struct stat* st) { + vfs_node_t* node; + + node = findnode_fs(name); + if (node == NULL) + return -EINVAL; + + st->st_dev = 0; /* ID of device containing file */ + st->st_ino = 0; /* inode number */ + st->st_mode = node->mask; /* protection */ + st->st_nlink = 0; /* number of hard links */ + st->st_uid = node->uid; /* user ID of owner */ + st->st_gid = node->gid; /* group ID of owner */ + st->st_rdev = node->type; /* device ID (if special file) */ + st->st_size = (node->block_size / MAX_DATAENTRIES + 1) * MAX_DATAENTRIES; /* total size, in bytes */ + st->st_blksize = node->block_size; /* blocksize for filesystem I/O */ + st->st_blocks = node->block_size / MAX_DATAENTRIES + 1; /* number of blocks allocated */ + st->st_atim.tv_sec = 0; /* time of last access */ + st->st_atim.tv_nsec = 0; + st->st_mtim.tv_sec = 0; /* time of last modification */ + st->st_mtim.tv_nsec = 0; + st->st_ctim.tv_sec = 0; /* time of last status change */ + st->st_ctim.tv_nsec = 0; + + return 0; +} + #if defined(CONFIG_LWIP) && LWIP_SOCKET static int sys_socket(int domain, int type, int protocol) { @@ -267,10 +294,10 @@ int syscall_handler(uint32_t sys_nr, ...) break; } case __NR_stat: { - //const char* name = va_arg(vl, const char*); - //struct stat* st = va_arg(vl, struct stat*); - - ret = -EINVAL; + const char* name = va_arg(vl, const char*); + struct stat* st = va_arg(vl, struct stat*); + + ret = sys_stat(name, st); break; } case __NR_read: {