chdir and fchdir need to return a 'long'
authorKevin Klues <klueska@cs.berkeley.edu>
Wed, 27 Aug 2014 03:19:28 +0000 (20:19 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Wed, 27 Aug 2014 03:19:28 +0000 (20:19 -0700)
I made them return an intreg_t because other syscalls use this type
(which is a little weird), but no matter what we use, we need to make
sure the value returned is sign extended properly to the size of a long.

This is necessary because Go has a generic syscall wrapper that examines
the return value and checks to see if it is "-1" before allocating a new
AkaError struct and returning errno and errrstr up the stack. On amd64,
when a syscall just returns an 'int', the upper bits are 0'd out and we
interpret the value as 2^32, not -1 (which indicates a success). We also
cannot simply donwcast the return value to 32 bits before doing the
comparison because some system calls (e.g. mmap) can have valid values
that have all lower 32 bits set to 1.

This isn't a problem for glibc because it doesn't have a generic wrapper
around all syscall. It can down cast the return value to the proper type
in the libc wrapper before doing the check of whether or not to return
an error.

kern/src/syscall.c

index d5a6d00..ce19a33 100644 (file)
@@ -1489,7 +1489,7 @@ intreg_t sys_readlink(struct proc *p, char *path, size_t path_l,
        return ret;
 }
 
-static int sys_chdir(struct proc *p, pid_t pid, const char *path, size_t path_l)
+static intreg_t sys_chdir(struct proc *p, pid_t pid, const char *path, size_t path_l)
 {
        int retval;
        char *t_path;
@@ -1508,7 +1508,7 @@ static int sys_chdir(struct proc *p, pid_t pid, const char *path, size_t path_l)
        return retval;
 }
 
-static int sys_fchdir(struct proc *p, pid_t pid, int fd)
+static intreg_t sys_fchdir(struct proc *p, pid_t pid, int fd)
 {
        struct file *file;
        int retval;