Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision b33ec435b399c93c963dd892300dc1f6c5dac41e)
+++ uspace/srv/loader/main.c	(revision 27b76ca72fe73962d4f6bcdaeca5a243066e314f)
@@ -242,4 +242,5 @@
 	for (filc = 0; filc < count; filc++) {
 		ipc_callid_t callid;
+		int fd;
 
 		if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
@@ -248,4 +249,6 @@
 		}
 		async_state_change_finalize(callid, vfs_exch);
+		fd = fd_wait();
+		assert(fd == (int) filc);
 	}
 
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision b33ec435b399c93c963dd892300dc1f6c5dac41e)
+++ uspace/srv/vfs/vfs.c	(revision 27b76ca72fe73962d4f6bcdaeca5a243066e314f)
@@ -118,4 +118,8 @@
 		case VFS_IN_DUP:
 			vfs_dup(callid, &call);
+			break;
+		case VFS_IN_WAIT_HANDLE:
+			vfs_wait_handle(callid, &call);
+			break;
 		default:
 			async_answer_0(callid, ENOTSUP);
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision b33ec435b399c93c963dd892300dc1f6c5dac41e)
+++ uspace/srv/vfs/vfs.h	(revision 27b76ca72fe73962d4f6bcdaeca5a243066e314f)
@@ -189,4 +189,5 @@
 
 extern void vfs_pass_handle(sysarg_t, sysarg_t, int);
+extern int vfs_wait_handle_internal(void);
 
 extern vfs_file_t *vfs_file_get(int);
@@ -215,4 +216,5 @@
 extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
 extern void vfs_rename(ipc_callid_t, ipc_call_t *);
+extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision b33ec435b399c93c963dd892300dc1f6c5dac41e)
+++ uspace/srv/vfs/vfs_file.c	(revision 27b76ca72fe73962d4f6bcdaeca5a243066e314f)
@@ -43,4 +43,5 @@
 #include <fibril.h>
 #include <fibril_synch.h>
+#include <adt/list.h>
 #include "vfs.h"
 
@@ -50,6 +51,13 @@
 typedef struct {
 	fibril_mutex_t lock;
+	fibril_condvar_t cv;
+	list_t passed_handles;
 	vfs_file_t **files;
 } vfs_client_data_t;
+
+typedef struct {
+	link_t link;
+	int handle;
+} vfs_boxed_handle_t;
 
 static int _vfs_fd_free(vfs_client_data_t *, int);
@@ -85,4 +93,15 @@
 	
 	free(vfs_data->files);
+
+	while (!list_empty(&vfs_data->passed_handles)) {
+		link_t *lnk;
+		vfs_boxed_handle_t *bh;
+		
+		lnk = list_first(&vfs_data->passed_handles);
+		list_remove(lnk);
+
+		bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
+		free(bh);
+	}
 }
 
@@ -94,4 +113,6 @@
 	if (vfs_data) {
 		fibril_mutex_initialize(&vfs_data->lock);
+		fibril_condvar_initialize(&vfs_data->cv);
+		list_initialize(&vfs_data->passed_handles);
 		vfs_data->files = NULL;
 	}
@@ -331,11 +352,19 @@
 	vfs_file_t *donor_file = NULL;
 	vfs_file_t *acceptor_file = NULL;
+	vfs_boxed_handle_t *bh;
 	int acceptor_fd;
+
+	acceptor_data = async_get_client_data_by_hash(acceptor_hash);
+	if (!acceptor_data)
+		return;
+
+	bh = malloc(sizeof(vfs_boxed_handle_t));
+	assert(bh);
+
+	link_initialize(&bh->link);
+	bh->handle = -1;
 
 	donor_data = async_get_client_data_by_hash(donor_hash);
 	if (!donor_data)
-		return;
-	acceptor_data = async_get_client_data_by_hash(acceptor_hash);
-	if (!acceptor_data)
 		goto out;
 
@@ -347,4 +376,6 @@
 	if (acceptor_fd < 0)
 		goto out;
+
+	bh->handle = acceptor_fd;
 
 	/*
@@ -364,4 +395,9 @@
 
 out:
+	fibril_mutex_lock(&acceptor_data->lock);
+	list_append(&bh->link, &acceptor_data->passed_handles);
+	fibril_condvar_broadcast(&acceptor_data->cv);
+	fibril_mutex_unlock(&acceptor_data->lock);
+
 	if (donor_data)
 		async_put_client_data_by_hash(donor_hash);
@@ -372,4 +408,24 @@
 	if (acceptor_file)
 		_vfs_file_put(acceptor_data, acceptor_file);
+
+}
+
+int vfs_wait_handle_internal(void)
+{
+	vfs_client_data_t *vfs_data = VFS_DATA;	
+	int fd;
+	
+	fibril_mutex_lock(&vfs_data->lock);
+	while (list_empty(&vfs_data->passed_handles))
+		fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock);
+	link_t *lnk = list_first(&vfs_data->passed_handles);
+	list_remove(lnk);
+	fibril_mutex_unlock(&vfs_data->lock);
+
+	vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
+	fd = bh->handle;
+	free(bh);
+
+	return fd;
 }
 
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision b33ec435b399c93c963dd892300dc1f6c5dac41e)
+++ uspace/srv/vfs/vfs_ops.c	(revision 27b76ca72fe73962d4f6bcdaeca5a243066e314f)
@@ -1276,4 +1276,10 @@
 }
 
+void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
+{
+	int fd = vfs_wait_handle_internal();
+	async_answer_1(rid, EOK, fd);
+}
+
 /**
  * @}
