summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/sys/filedesc.h2
-rw-r--r--sys/kern/kern_descrip.c23
2 files changed, 25 insertions, 0 deletions
diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h
index f5f24db..94946a0 100644
--- a/sys/include/sys/filedesc.h
+++ b/sys/include/sys/filedesc.h
@@ -48,6 +48,8 @@ int fd_read(unsigned int fd, void *buf, size_t count);
int fd_alloc(struct filedesc **fd_out);
int fd_open(const char *pathname, int flags);
+
+int fd_dup(int fd);
struct filedesc *fd_get(unsigned int fdno);
#endif /* !_SYS_FILEDESC_H_ */
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c3d9b5c..da10f89 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -226,3 +226,26 @@ fd_open(const char *pathname, int flags)
filedes->vp = nd.vp;
return filedes->fdno;
}
+
+/*
+ * Duplicate a file descriptor. New file descriptor
+ * points to the same vnode.
+ */
+int
+fd_dup(int fd)
+{
+ int error;
+ struct filedesc *new_desc, *tmp;
+
+ tmp = fd_get(fd);
+ if (tmp == NULL)
+ return -EBADF;
+
+ if ((error = fd_alloc(&new_desc)) != 0)
+ return error;
+
+ /* Ref that vnode before we point to it */
+ vfs_vref(tmp->vp);
+ new_desc->vp = tmp->vp;
+ return new_desc->fdno;
+}