[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 2/6] lib/vfscore: Fix dup2()



If newfd is open, then POSIX says we have to close it - that's what this
patch aims to achieve. Given that dup2/dup3 explicitly wants to reserver a
file descriptor, we also introduce the vfscore_reserve_fd() function. We
also add a tiny fix in vfscore_alloc_fd() because it should also be able to
allocate file descriptor 0 - that's what stdio initialization needs among
other things.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
 lib/vfscore/fd.c                   | 22 +++++++++++++++++++---
 lib/vfscore/include/vfscore/file.h |  1 +
 lib/vfscore/main.c                 | 14 +++++++++++++-
 lib/vfscore/stdio.c                |  4 ++++
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/lib/vfscore/fd.c b/lib/vfscore/fd.c
index 7efed741..6db366a9 100644
--- a/lib/vfscore/fd.c
+++ b/lib/vfscore/fd.c
@@ -61,7 +61,7 @@ int vfscore_alloc_fd(void)
        flags = ukplat_lcpu_save_irqf();
        ret = uk_find_next_zero_bit(fdtable.bitmap, FDTABLE_MAX_FILES, 0);
 
-       if (!ret) {
+       if (ret == FDTABLE_MAX_FILES) {
                ret = -ENFILE;
                goto exit;
        }
@@ -73,6 +73,24 @@ exit:
        return ret;
 }
 
+int vfscore_reserve_fd(int fd)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       flags = ukplat_lcpu_save_irqf();
+       if (uk_test_bit(fd, fdtable.bitmap)) {
+               ret = -EBUSY;
+               goto exit;
+       }
+
+       uk_bitmap_set(fdtable.bitmap, fd, 1);
+
+exit:
+       ukplat_lcpu_restore_irqf(flags);
+       return ret;
+}
+
 int vfscore_put_fd(int fd)
 {
        struct vfscore_file *fp;
@@ -188,8 +206,6 @@ static void fdtable_init(void)
 {
        memset(&fdtable, 0, sizeof(fdtable));
 
-       /* reserve stdin, stdout and stderr */
-       uk_bitmap_set(fdtable.bitmap, 0, 3);
        init_stdio();
 }
 
diff --git a/lib/vfscore/include/vfscore/file.h 
b/lib/vfscore/include/vfscore/file.h
index c698201d..be239744 100644
--- a/lib/vfscore/include/vfscore/file.h
+++ b/lib/vfscore/include/vfscore/file.h
@@ -66,6 +66,7 @@ struct vfscore_file {
 #define FD_UNLOCK(fp)     uk_mutex_unlock(&(fp->f_lock))
 
 int vfscore_alloc_fd(void);
+int vfscore_reserve_fd(int fd);
 int vfscore_put_fd(int fd);
 int vfscore_install_fd(int fd, struct vfscore_file *file);
 struct vfscore_file *vfscore_get_file(int fd);
diff --git a/lib/vfscore/main.c b/lib/vfscore/main.c
index d6145a2b..4beda603 100644
--- a/lib/vfscore/main.c
+++ b/lib/vfscore/main.c
@@ -1379,7 +1379,7 @@ UK_TRACEPOINT(trace_vfs_dup3_err, "%d", int);
  */
 int dup3(int oldfd, int newfd, int flags)
 {
-       struct vfscore_file *fp;
+       struct vfscore_file *fp, *fp_new;
        int error;
 
        trace_vfs_dup3(oldfd, newfd, flags);
@@ -1401,6 +1401,18 @@ int dup3(int oldfd, int newfd, int flags)
        if (error)
                goto out_errno;
 
+       error = fget(newfd, &fp_new);
+       if (error == 0) {
+               /* if newfd is open, then close it */
+               error = close(newfd);
+               if (error)
+                       goto out_errno;
+       }
+
+       error = vfscore_reserve_fd(newfd);
+       if (error)
+               goto out_errno;
+
        error = vfscore_install_fd(newfd, fp);
        if (error) {
                fdrop(fp);
diff --git a/lib/vfscore/stdio.c b/lib/vfscore/stdio.c
index 578b20bb..62a7a607 100644
--- a/lib/vfscore/stdio.c
+++ b/lib/vfscore/stdio.c
@@ -211,6 +211,10 @@ static struct vfscore_file  stdio_file = {
 
 void init_stdio(void)
 {
+       int fd;
+
+       fd = vfscore_alloc_fd();
+       UK_ASSERT(fd == 0);
        vfscore_install_fd(0, &stdio_file);
        if (dup2(0, 1) != 1)
                uk_pr_err("failed to dup to stdin\n");
-- 
2.20.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.