sys_read(), sys_write(), and sys_lseek()
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 6 Aug 2010 22:47:38 +0000 (15:47 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:50 +0000 (17:35 -0700)
kern/include/syscall.h
kern/src/kfs.c
kern/src/syscall.c
kern/src/vfs.c
tests/file_test.c

index b890f43..82aea0e 100644 (file)
@@ -36,25 +36,4 @@ int systrace_dereg(bool all, struct proc *p);
 void systrace_print(bool all, struct proc *p);
 void systrace_clear_buffer(void);
 
-intreg_t sys_read(struct proc* p, int fd, void* buf, int len);
-intreg_t sys_write(struct proc* p, int fd, const void* buf, int len);
-intreg_t sys_pread(struct proc* p, int fd, void* buf, int len, int offset);
-intreg_t sys_pwrite(struct proc* p, int fd, const void* buf, int len, int offset);
-intreg_t sys_open(struct proc* p, const char* path, int oflag, int mode);
-intreg_t sys_close(struct proc* p, int fd);
-intreg_t sys_fstat(struct proc* p, int fd, void* buf);
-intreg_t sys_stat(struct proc* p, const char* path, void* buf);
-intreg_t sys_lstat(struct proc* p, const char* path, void* buf);
-intreg_t sys_fcntl(struct proc* p, int fd, int cmd, int arg);
-intreg_t sys_access(struct proc* p, const char* path, int type);
-intreg_t sys_umask(struct proc* p, int mask);
-intreg_t sys_chmod(struct proc* p, const char* path, int mode);
-intreg_t sys_lseek(struct proc* p, int fd, int offset, int whence);
-intreg_t sys_link(struct proc* p, const char* old, const char* new);
-intreg_t sys_unlink(struct proc* p, const char* path);
-intreg_t sys_chdir(struct proc* p, const char* path);
-intreg_t sys_getcwd(struct proc* p, char* pwd, int size);
-intreg_t sys_gettimeofday(struct proc* p, int* buf);
-intreg_t sys_tcsetattr(struct proc* p, int fd, int optional_actions, const void* termios_p);
-intreg_t sys_tcgetattr(struct proc* p, int fd, void* termios_p);
 #endif /* !ROS_KERN_SYSCALL_H */
index f969404..a38a893 100644 (file)
@@ -481,9 +481,12 @@ off_t kfs_llseek(struct file *file, off_t offset, int whence)
                        temp_off = file->f_dentry->d_inode->i_size + offset;
                        break;
                default:
+                       set_errno(current_tf, EINVAL);
                        warn("Unknown 'whence' in llseek()!\n");
+                       return -1;
        }
-       /* make sure the f_pos isn't outside the limits of the existing file */
+       /* make sure the f_pos isn't outside the limits of the existing file.
+        * techincally, if they go too far, we should return EINVAL */
        temp_off = MAX(MIN(temp_off, file->f_dentry->d_inode->i_size), 0);
        file->f_pos = temp_off;
        return temp_off;
index 4cdd42d..a9bdd7d 100644 (file)
@@ -792,64 +792,42 @@ static int sys_eth_recv_check(env_t* e)
 
 #endif // Network
 
-// Syscalls below here are serviced by the appserver for now.
-#define ufe(which,a0,a1,a2,a3) \
-       frontend_syscall_errno(p,APPSERVER_SYSCALL_##which,\
-                          (int)(a0),(int)(a1),(int)(a2),(int)(a3))
-
-intreg_t sys_write(struct proc* p, int fd, const void* buf, int len)
+static intreg_t sys_read(struct proc* p, int fd, void* buf, int len)
 {
-       int ret = 0;
-       void* kbuf = user_memdup_errno(p,buf,len);
-       if(kbuf == NULL)
+       ssize_t ret;
+       struct file *file = get_file_from_fd(&p->open_files, fd);
+       if (!file) {
+               set_errno(current_tf, EBADF);
                return -1;
-#ifndef __CONFIG_APPSERVER__
-       /* Catch a common usage of stderr */
-       if (fd == 2) {
-               ((char*)kbuf)[len-1] = 0;
-               printk("[stderr]: %s\n", kbuf);
-               ret = len;
-       } else { // but warn/panic otherwise in ufe()
-               ret = ufe(write, fd, PADDR(kbuf), len, 0);
        }
-#else
-       ret = ufe(write, fd, PADDR(kbuf), len, 0);
-#endif
-       user_memdup_free(p,kbuf);
-       return ret;
-}
-
-intreg_t sys_read(struct proc* p, int fd, void* buf, int len)
-{
-       void* kbuf = kmalloc_errno(len);
-       if(kbuf == NULL)
-               return -1;
-       int ret = ufe(read,fd,PADDR(kbuf),len,0);
-       if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,len))
-               ret = -1;
-       user_memdup_free(p,kbuf);
-       return ret;
-}
-
-intreg_t sys_pwrite(struct proc* p, int fd, const void* buf, int len, int offset)
-{
-       void* kbuf = user_memdup_errno(p,buf,len);
-       if(kbuf == NULL)
-               return -1;
-       int ret = ufe(pwrite,fd,PADDR(kbuf),len,offset);
-       user_memdup_free(p,kbuf);
+       /* TODO: (UMEM) currently, read() handles user memcpy issues, but we
+        * probably should user_mem_check and pin the region here, so read doesn't
+        * worry about it */
+       ret = file->f_op->read(file, buf, len, &file->f_pos);
+       kref_put(&file->f_kref);
        return ret;
 }
 
-intreg_t sys_pread(struct proc* p, int fd, void* buf, int len, int offset)
+static intreg_t sys_write(struct proc* p, int fd, const void* buf, int len)
 {
-       void* kbuf = kmalloc_errno(len);
-       if(kbuf == NULL)
+       /* Catch common usage of stdout and stderr.  No protections or anything. */
+       if (fd == 1) {
+               printk("[stdout]: %s\n", buf);
+               return len;
+       } else if (fd == 2) {
+               printk("[stderr]: %s\n", buf);
+               return len;
+       }
+       /* the real sys_write: */
+       ssize_t ret;
+       struct file *file = get_file_from_fd(&p->open_files, fd);
+       if (!file) {
+               set_errno(current_tf, EBADF);
                return -1;
-       int ret = ufe(pread,fd,PADDR(kbuf),len,offset);
-       if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,len))
-               ret = -1;
-       user_memdup_free(p,kbuf);
+       }
+       /* TODO: (UMEM) */
+       ret = file->f_op->write(file, buf, len, &file->f_pos);
+       kref_put(&file->f_kref);
        return ret;
 }
 
@@ -857,7 +835,7 @@ intreg_t sys_pread(struct proc* p, int fd, void* buf, int len, int offset)
  * process's open file list. 
  *
  * TODO: take the path length */
-intreg_t sys_open(struct proc *p, const char *path, int oflag, int mode)
+static intreg_t sys_open(struct proc *p, const char *path, int oflag, int mode)
 {
        int fd = 0;
        struct file *file;
@@ -879,7 +857,7 @@ intreg_t sys_open(struct proc *p, const char *path, int oflag, int mode)
        return fd;
 }
 
-intreg_t sys_close(struct proc *p, int fd)
+static intreg_t sys_close(struct proc *p, int fd)
 {
        struct file *file = put_file_from_fd(&p->open_files, fd);
        if (!file) {
@@ -895,6 +873,11 @@ intreg_t sys_close(struct proc *p, int fd)
        return 0;
 }
 
+/* kept around til we remove the last ufe */
+#define ufe(which,a0,a1,a2,a3) \
+       frontend_syscall_errno(p,APPSERVER_SYSCALL_##which,\
+                          (int)(a0),(int)(a1),(int)(a2),(int)(a3))
+
 #define NEWLIB_STAT_SIZE 64
 intreg_t sys_fstat(struct proc* p, int fd, void* buf)
 {
@@ -968,9 +951,17 @@ intreg_t sys_chmod(struct proc* p, const char* path, int mode)
        return ret;
 }
 
-intreg_t sys_lseek(struct proc* p, int fd, int offset, int whence)
+static intreg_t sys_lseek(struct proc *p, int fd, off_t offset, int whence)
 {
-       return ufe(lseek,fd,offset,whence,0);
+       off_t ret;
+       struct file *file = get_file_from_fd(&p->open_files, fd);
+       if (!file) {
+               set_errno(current_tf, EBADF);
+               return -1;
+       }
+       ret = file->f_op->llseek(file, offset, whence);
+       kref_put(&file->f_kref);
+       return ret;
 }
 
 intreg_t sys_link(struct proc* p, const char* _old, const char* _new)
@@ -1126,7 +1117,6 @@ intreg_t syscall(struct proc *p, uintreg_t syscallno, uintreg_t a1,
                [SYS_eth_get_mac_addr] = (syscall_t)sys_eth_get_mac_addr,
                [SYS_eth_recv_check] = (syscall_t)sys_eth_recv_check,
        #endif
-               // Syscalls serviced by the appserver for now.
                [SYS_read] = (syscall_t)sys_read,
                [SYS_write] = (syscall_t)sys_write,
                [SYS_open] = (syscall_t)sys_open,
index eb095dd..e33ef3b 100644 (file)
@@ -643,8 +643,8 @@ ssize_t generic_file_read(struct file *file, char *buf, size_t count,
                error = file_load_page(file, i, &page);
                assert(!error); /* TODO: handle ENOMEM and friends */
                copy_amt = MIN(PGSIZE - page_off, buf_end - buf);
-               /* TODO: think about this.  if it's a user buffer, we're relying on
-                * current to detect whose it is (which should work for async calls).
+               /* TODO: (UMEM) think about this.  if it's a user buffer, we're relying
+                * on current to detect whose it is (which should work for async calls).
                 * Also, need to propagate errors properly...  Probably should do a
                 * user_mem_check, then free, and also to make a distinction between
                 * when the kernel wants a read/write (TODO: KFOP) */
@@ -693,10 +693,11 @@ ssize_t generic_file_write(struct file *file, const char *buf, size_t count,
                error = file_load_page(file, i, &page);
                assert(!error); /* TODO: handle ENOMEM and friends */
                copy_amt = MIN(PGSIZE - page_off, buf_end - buf);
-               /* TODO: think about this.  if it's a user buffer, we're relying on
-                * current to detect whose it is (which should work for async calls). */
+               /* TODO: (UMEM) (KFOP) think about this.  if it's a user buffer, we're
+                * relying on current to detect whose it is (which should work for async
+                * calls). */
                if (current) {
-                       memcpy_to_user(current, page2kva(page) + page_off, buf, copy_amt);
+                       memcpy_from_user(current, page2kva(page) + page_off, buf, copy_amt);
                } else {
                        memcpy(page2kva(page) + page_off, buf, copy_amt);
                }
index 80be621..9182112 100644 (file)
@@ -1,8 +1,9 @@
-#include <stdio.h> 
+#include <rstdio.h> 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <arch/arch.h>
+#include <unistd.h>
 
 int main() 
 { 
@@ -14,5 +15,17 @@ int main()
        fclose(file); 
 
        int fd = open("/bin/test.txt", O_RDWR | O_CREAT );
+       char rbuf[256] = {0}, wbuf[256] = {0};
+       int retval;
+       retval = read(fd, rbuf, 16);
+       printf("Tried to read, got %d bytes of buf: %s\n", retval, rbuf);
+       strcpy(wbuf, "paul <3's the new 61c");
+       retval = write(fd, wbuf, 22);
+       printf("Tried to write, wrote %d bytes\n", retval);
+       printf("Trying to seek to 0\n");
+       lseek(fd, 0, SEEK_SET);
+       retval = read(fd, rbuf, 64);
+       printf("Tried to read again, got %d bytes of buf: %s\n", retval, rbuf);
+
        breakpoint();
 }