[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |