sys_chdir() / fchdir() take a pid (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 26 Aug 2014 22:02:33 +0000 (15:02 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 26 Aug 2014 22:02:33 +0000 (15:02 -0700)
This is so parents (or any process that controls another) can change the
working directory (PWD, DOT, etc) of another process, including itself.

This does slow down chdir a little, due to the sync on pid lookup and decref,
but scalable chdir() isn't a big deal at this point.

Copy over chdir.c and fchdir.c and rebuild glibc.  Or just make clean it.

kern/src/syscall.c
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/chdir.c
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/fchdir.c

index 13be1c6..e57a642 100644 (file)
@@ -1489,34 +1489,45 @@ intreg_t sys_readlink(struct proc *p, char *path, size_t path_l,
        return ret;
 }
 
-intreg_t sys_chdir(struct proc *p, const char *path, size_t path_l)
+static int sys_chdir(struct proc *p, pid_t pid, const char *path, size_t path_l)
 {
        int retval;
-       char *t_path = user_strdup_errno(p, path, path_l);
-       if (!t_path)
+       char *t_path;
+       struct proc *target = get_controllable_proc(p, pid);
+       if (!target)
                return -1;
-       /* TODO: 9ns support */
-       retval = do_chdir(&p->fs_env, t_path);
-       user_memdup_free(p, t_path);
-       if (retval) {
-               set_errno(-retval);
+       t_path = user_strdup_errno(p, path, path_l);
+       if (!t_path) {
+               proc_decref(target);
                return -1;
        }
-       return 0;
+       /* TODO: 9ns support */
+       retval = do_chdir(&target->fs_env, t_path);
+       /* do_chdir doesn't set errno (though fchdir does) */
+       if (retval)
+               set_errno(-retval);
+       user_memdup_free(p, t_path);
+       proc_decref(target);
+       return retval;
 }
 
-intreg_t sys_fchdir(struct proc *p, int fd)
+static int sys_fchdir(struct proc *p, pid_t pid, int fd)
 {
        struct file *file;
        int retval;
+       struct proc *target = get_controllable_proc(p, pid);
+       if (!target)
+               return -1;
        file = get_file_from_fd(&p->open_files, fd);
        if (!file) {
                /* TODO: 9ns */
                set_errno(EBADF);
+               proc_decref(target);
                return -1;
        }
-       retval = do_fchdir(&p->fs_env, file);
+       retval = do_fchdir(&target->fs_env, file);
        kref_put(&file->f_kref);
+       proc_decref(target);
        return retval;
 }
 
index e770160..9ebadd4 100644 (file)
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <sys/types.h>
 #include <string.h>
 #include <ros/syscall.h>
 
@@ -33,6 +34,6 @@ __chdir (path)
     return -1;
   }
 
-  return ros_syscall(SYS_chdir, path, strlen(path), 0, 0, 0, 0);
+  return ros_syscall(SYS_chdir, getpid(), path, strlen(path), 0, 0, 0);
 }
 weak_alias (__chdir, chdir)
index fafd860..1bd8259 100644 (file)
 #include <errno.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <sys/types.h>
 
 /* Change the current directory to FD.  */
 int
 fchdir (fd)
      int fd;
 {
-  return ros_syscall(SYS_fchdir, fd, 0, 0, 0, 0, 0);
+  return ros_syscall(SYS_fchdir, getpid(), fd, 0, 0, 0, 0);
 }
 strong_alias (fchdir,__fchdir)