From d959b68e09b636cd56f0e96bb3b771f76ab66171 Mon Sep 17 00:00:00 2001 From: hinus Date: Wed, 11 Aug 2021 16:39:19 +0800 Subject: [PATCH] Title: System call 'lseek' Issue: https://gitee.com/hinus/linux_kernel_011/issues/I44ZBN Description: System call 'lseek' --- fs/read_write.c | 29 +++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ include/linux/sys.h | 4 ++-- include/unistd.h | 2 ++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 7c61f34..cf2c111 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -9,6 +9,35 @@ extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); extern int file_read(struct m_inode * inode, struct file * filp, char * buf, int count); +int sys_lseek(unsigned int fd,off_t offset, int origin) { + struct file * file; + int tmp; + + if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) + || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) + return -EBADF; + if (file->f_inode->i_pipe) + return -ESPIPE; + + switch (origin) { + case 0: + if (offset<0) return -EINVAL; + file->f_pos=offset; + break; + case 1: + if (file->f_pos+offset<0) return -EINVAL; + file->f_pos += offset; + break; + case 2: + if ((tmp=file->f_inode->i_size+offset) < 0) + file->f_pos = tmp; + break; + default: + return -EINVAL; + } + return file->f_pos; +} + int sys_read(unsigned int fd,char * buf,int count) { struct file * file; struct m_inode * inode; diff --git a/include/linux/fs.h b/include/linux/fs.h index 7f9044f..808ad32 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3,6 +3,8 @@ #include +#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3) + #define READ 0 #define WRITE 1 #define READA 2 diff --git a/include/linux/sys.h b/include/linux/sys.h index 1643a18..8ae4fc4 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -17,7 +17,7 @@ extern int sys_chmod(); extern int sys_chown(); extern int sys_break(); //extern int sys_stat(); -//extern int sys_lseek(); +extern int sys_lseek(); extern int sys_getpid(); //extern int sys_mount(); //extern int sys_umount(); @@ -108,7 +108,7 @@ fn_ptr sys_call_table[] = { sys_chown, sys_break, 0, //sys_stat, - 0, //sys_lseek, + sys_lseek, sys_getpid, 0, //sys_mount, diff --git a/include/unistd.h b/include/unistd.h index a805ffd..6d3027d 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -162,9 +162,11 @@ int sync(); int open(const char * filename, int flag, ...); int write(int fildes, const char * buf, off_t count); int read(int fildes, const char * buf, off_t count); +int lseek(int fildes, off_t offset, int origin); int rmdir(const char* pathname); time_t time(time_t * tloc); +int uname(struct utsname * name); #endif -- Gitee