diff --git a/src/kernel/core/fs/fd.c b/src/kernel/core/fs/fd.c index 73ed84efa2..e04ab3cd65 100644 --- a/src/kernel/core/fs/fd.c +++ b/src/kernel/core/fs/fd.c @@ -1,8 +1,8 @@ /* Operations on file descriptors -** -** Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the Haiku License. -*/ + * + * Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ #include @@ -62,14 +62,14 @@ alloc_fd(void) int -new_fd(struct io_context *context, struct file_descriptor *descriptor) +new_fd_etc(struct io_context *context, struct file_descriptor *descriptor, int firstIndex) { int fd = -1; uint32 i; mutex_lock(&context->io_mutex); - for (i = 0; i < context->table_size; i++) { + for (i = firstIndex; i < context->table_size; i++) { if (!context->fds[i]) { fd = i; break; @@ -90,6 +90,13 @@ err: } +int +new_fd(struct io_context *context, struct file_descriptor *descriptor) +{ + return new_fd_etc(context, descriptor, 0); +} + + /** Reduces the descriptor's reference counter, and frees all resources * if necessary. */ @@ -124,7 +131,7 @@ get_fd(struct io_context *context, int fd) if ((uint32)fd < context->table_size) descriptor = context->fds[fd]; - + if (descriptor != NULL) // fd is valid atomic_add(&descriptor->ref_count, 1); @@ -289,7 +296,7 @@ fd_is_valid(int fd, bool kernel) struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd); if (descriptor == NULL) return false; - + put_fd(descriptor); return true; } diff --git a/src/kernel/core/fs/vfs.cpp b/src/kernel/core/fs/vfs.cpp index 9655daa85f..dfc997a4c5 100755 --- a/src/kernel/core/fs/vfs.cpp +++ b/src/kernel/core/fs/vfs.cpp @@ -2938,6 +2938,12 @@ common_fcntl(int fd, int op, uint32 argument, bool kernel) status = descriptor->open_mode; break; + case F_DUPFD: + status = new_fd_etc(get_current_io_context(kernel), descriptor, (int)argument); + if (status >= 0) + atomic_add(&descriptor->ref_count, 1); + break; + // ToDo: add support for more ops default: