sys_fcntl() supports dup
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Aug 2010 18:59:02 +0000 (11:59 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:53 +0000 (17:35 -0700)
Fixes a bug in fcntl too, not that anyone uses it.

kern/include/ros/fs.h
kern/include/vfs.h
kern/src/process.c
kern/src/syscall.c
kern/src/vfs.c
tests/spawn.c

index a837e2d..c54b1f2 100644 (file)
@@ -66,6 +66,7 @@ struct kstat {
 #define O_NOATIME              01000000        /* Do not set atime. */
 #define O_CLOEXEC              02000000        /* Set close_on_exec. */
 #define O_CREAT_FLAGS (O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC)
+#define O_FCNTL_FLAGS (O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK)
 
 /* File creation modes (access controls) */
 #define S_IRWXU 00700  /* user (file owner) has read, write and execute perms */
index 1a83fe8..c0ee51f 100644 (file)
@@ -473,7 +473,7 @@ int file_load_page(struct file *file, unsigned long index, struct page **pp);
 /* Process-related File management functions */
 struct file *get_file_from_fd(struct files_struct *open_files, int fd);
 struct file *put_file_from_fd(struct files_struct *open_files, int file_desc);
-int insert_file(struct files_struct *open_files, struct file *file);
+int insert_file(struct files_struct *open_files, struct file *file, int low_fd);
 void close_all_files(struct files_struct *open_files, bool cloexec);
 void clone_files(struct files_struct *src, struct files_struct *dst);
 int do_chdir(struct fs_struct *fs_env, char *path);
index 6ff105f..13a1a82 100644 (file)
@@ -333,9 +333,9 @@ error_t proc_alloc(struct proc **pp, struct proc *parent)
        p->open_files.fd = p->open_files.fd_array;
        p->open_files.open_fds = (struct fd_set*)&p->open_files.open_fds_init;
        /* Connect to stdin, stdout, stderr */
-       assert(insert_file(&p->open_files, dev_stdin) == 0);
-       assert(insert_file(&p->open_files, dev_stdout) == 1);
-       assert(insert_file(&p->open_files, dev_stderr) == 2);
+       assert(insert_file(&p->open_files, dev_stdin,  0) == 0);
+       assert(insert_file(&p->open_files, dev_stdout, 0) == 1);
+       assert(insert_file(&p->open_files, dev_stderr, 0) == 2);
 
        atomic_inc(&num_envs);
        frontend_proc_init(p);
index ba740ed..9e7e927 100644 (file)
@@ -835,7 +835,7 @@ static intreg_t sys_open(struct proc *p, const char *path, size_t path_l,
        user_memdup_free(p, t_path);
        if (!file)
                return -1;
-       fd = insert_file(&p->open_files, file); /* stores the ref to file */
+       fd = insert_file(&p->open_files, file, 0);      /* stores the ref to file */
        kref_put(&file->f_kref);
        if (fd < 0) {
                warn("File insertion failed");
@@ -943,7 +943,11 @@ intreg_t sys_fcntl(struct proc *p, int fd, int cmd, int arg)
        }
        switch (cmd) {
                case (F_DUPFD):
-                       printk("[kernel] dup not supported yet\n");
+                       retval = insert_file(&p->open_files, file, arg);
+                       if (retval < 0) {
+                               set_errno(-retval);
+                               retval = -1;
+                       }
                        break;
                case (F_GETFD):
                        /* GET and SETFD just care about CLOEXEC.  We don't have a separate
@@ -960,13 +964,14 @@ intreg_t sys_fcntl(struct proc *p, int fd, int cmd, int arg)
                        break;
                case (F_SETFL):
                        /* only allowed to set certain flags. */
-                       arg &= O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK;
+                       arg &= O_FCNTL_FLAGS;
+                       file->f_flags = (file->f_flags & ~O_FCNTL_FLAGS) | arg;
                        break;
                default:
                        warn("Unsupported fcntl cmd %d\n", cmd);
        }
        kref_put(&file->f_kref);
-       return 0;
+       return retval;
 }
 
 static intreg_t sys_access(struct proc *p, const char *path, size_t path_l,
index 2d4578d..0f57ee8 100644 (file)
@@ -1577,12 +1577,14 @@ struct file *put_file_from_fd(struct files_struct *open_files, int file_desc)
 }
 
 /* Inserts the file in the files_struct, returning the corresponding new file
- * descriptor, or an error code.  We currently grab the first open FD. */
-int insert_file(struct files_struct *open_files, struct file *file)
+ * descriptor, or an error code.  We start looking for open fds from low_fd. */
+int insert_file(struct files_struct *open_files, struct file *file, int low_fd)
 {
        int slot = -1;
+       if ((low_fd < 0) || (low_fd > NR_FILE_DESC_MAX))
+               return -EINVAL;
        spin_lock(&open_files->lock);
-       for (int i = 0; i < open_files->max_fdset; i++) {
+       for (int i = low_fd; i < open_files->max_fdset; i++) {
                if (GET_BITMASK_BIT(open_files->open_fds->fds_bits, i))
                        continue;
                slot = i;
index a16a677..76b5fb6 100644 (file)
@@ -7,8 +7,8 @@ int main(int argc, char **argv, char **envp)
 {
        char *p_argv[] = {0, 0, 0};
        char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
-       //#define FILENAME "/bin/hello"
-       #define FILENAME "/bin/hello-sym"
+       #define FILENAME "/bin/hello"
+       //#define FILENAME "/bin/hello-sym"
        char filename[] = FILENAME;
        #if 0
        /* try some bad combos */