Fixes bug in close_all_files()
[akaros.git] / kern / src / vfs.c
index 2d4578d..743413b 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;
@@ -1612,8 +1614,9 @@ void close_all_files(struct files_struct *open_files, bool cloexec)
                         * have a valid fdset higher than files */
                        assert(i < open_files->max_files);
                        file = open_files->fd[i];
-                       if (cloexec && !(file->f_flags | O_CLOEXEC))
+                       if (cloexec && !(file->f_flags & O_CLOEXEC))
                                continue;
+                       /* Actually close the file */
                        open_files->fd[i] = 0;
                        assert(file);
                        kref_put(&file->f_kref);
@@ -1635,11 +1638,13 @@ void clone_files(struct files_struct *src, struct files_struct *dst)
                         * have a valid fdset higher than files */
                        assert(i < src->max_files);
                        file = src->fd[i];
-                       SET_BITMASK_BIT(dst->open_fds->fds_bits, i);
                        assert(i < dst->max_files && dst->fd[i] == 0);
+                       SET_BITMASK_BIT(dst->open_fds->fds_bits, i);
                        dst->fd[i] = file;
                        assert(file);
                        kref_get(&file->f_kref, 1);
+                       if (i >= dst->next_fd)
+                               dst->next_fd = i + 1;
                }
        }
        spin_unlock(&dst->lock);