Index: uspace/lib/c/generic/dirent.c
===================================================================
--- uspace/lib/c/generic/dirent.c	(revision 222774a69b1583c34db4419abfda9fa6a1031f74)
+++ uspace/lib/c/generic/dirent.c	(revision 05c9d9203f1025eec520064f4b502c7cb16a6545)
@@ -47,5 +47,52 @@
 };
 
-/** Open directory.
+/** Like opendir_handle, but takes ownership of the handle if successful. */
+static DIR *opendir_internal(int handle)
+{
+	DIR *dirp = malloc(sizeof(DIR));
+	if (!dirp) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	errno_t rc = vfs_open(handle, MODE_READ);
+	if (rc != EOK) {
+		free(dirp);
+		errno = rc;
+		return NULL;
+	}
+
+	dirp->fd = handle;
+	dirp->pos = 0;
+	return dirp;
+}
+
+/** Open directory by its handle (a.k.a. file descriptor).
+ *
+ * @param handle Directory handle
+ * @return Non-NULL pointer on success. On error returns @c NULL and sets errno.
+ */
+DIR *opendir_handle(int handle)
+{
+	int my_handle;
+	// Clone the file handle, otherwise closedir would put the
+	// handle that was passed to us here by the caller and that we don't own.
+	errno_t rc = vfs_clone(handle, -1, false, &my_handle);
+	if (rc != EOK) {
+		errno = rc;
+		return NULL;
+	}
+
+	DIR *dirp = opendir_internal(my_handle);
+	if (!dirp) {
+		rc = errno;
+		vfs_put(my_handle);
+		errno = rc;
+		return NULL;
+	}
+	return dirp;
+}
+
+/** Open directory by its pathname.
  *
  * @param dirname Directory pathname
@@ -55,32 +102,22 @@
 DIR *opendir(const char *dirname)
 {
-	DIR *dirp = malloc(sizeof(DIR));
-	if (!dirp) {
-		errno = ENOMEM;
-		return NULL;
-	}
-
 	int fd;
 	errno_t rc = vfs_lookup(dirname, WALK_DIRECTORY, &fd);
 	if (rc != EOK) {
-		free(dirp);
 		errno = rc;
 		return NULL;
 	}
 
-	rc = vfs_open(fd, MODE_READ);
-	if (rc != EOK) {
-		free(dirp);
+	DIR *dirp = opendir_internal(fd);
+	if (!dirp) {
+		rc = errno;
 		vfs_put(fd);
 		errno = rc;
 		return NULL;
 	}
-
-	dirp->fd = fd;
-	dirp->pos = 0;
 	return dirp;
 }
 
-/** Read directory entry.
+/** Read current directory entry and advance to the next one.
  *
  * @param dirp Open directory
Index: uspace/lib/c/include/dirent.h
===================================================================
--- uspace/lib/c/include/dirent.h	(revision 222774a69b1583c34db4419abfda9fa6a1031f74)
+++ uspace/lib/c/include/dirent.h	(revision 05c9d9203f1025eec520064f4b502c7cb16a6545)
@@ -46,4 +46,5 @@
 typedef struct __dirstream DIR;
 
+extern DIR *opendir_handle(int handle);
 extern DIR *opendir(const char *);
 extern struct dirent *readdir(DIR *);
