Index: uspace/srv/hid/input/port/adb_mouse.c
===================================================================
--- uspace/srv/hid/input/port/adb_mouse.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/hid/input/port/adb_mouse.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -42,4 +42,5 @@
 #include <errno.h>
 #include <loc.h>
+#include <stdio.h>
 
 static mouse_dev_t *mouse_dev;
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/hw/irc/apic/apic.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -45,4 +45,5 @@
 #include <errno.h>
 #include <async.h>
+#include <stdio.h>
 
 #define NAME  "apic"
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/loader/main.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -61,4 +61,5 @@
 #include <elf/elf.h>
 #include <elf/elf_load.h>
+#include <vfs/vfs.h>
 
 #ifdef CONFIG_RTLD
@@ -89,9 +90,5 @@
 
 /** Number of preset files */
-static int filc = 0;
-/** Preset files vector */
-static fdi_node_t **filv = NULL;
-/** Buffer holding all preset files */
-static fdi_node_t *fil_buf = NULL;
+static unsigned int filc = 0;
 
 static elf_info_t prog_info;
@@ -239,45 +236,23 @@
 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
 {
-	fdi_node_t *buf;
-	size_t buf_size;
-	int rc = async_data_write_accept((void **) &buf, false, 0, 0,
-	    sizeof(fdi_node_t), &buf_size);
-	
-	if (rc == EOK) {
-		int count = buf_size / sizeof(fdi_node_t);
-		
-		/*
-		 * Allocate new filv
-		 */
-		fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
-		if (_filv == NULL) {
-			free(buf);
-			async_answer_0(rid, ENOMEM);
-			return;
+	size_t count = IPC_GET_ARG1(*request);
+
+	async_exch_t *vfs_exch = vfs_exchange_begin();
+
+	for (filc = 0; filc < count; filc++) {
+		ipc_callid_t callid;
+		int fd;
+
+		if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
+			async_answer_0(callid, EINVAL);
+			break;
 		}
-		
-		/*
-		 * Fill the new filv with argument pointers
-		 */
-		int i;
-		for (i = 0; i < count; i++)
-			_filv[i] = &buf[i];
-		
-		_filv[count] = NULL;
-		
-		/*
-		 * Copy temporary data to global variables
-		 */
-		if (fil_buf != NULL)
-			free(fil_buf);
-		
-		if (filv != NULL)
-			free(filv);
-		
-		filc = count;
-		fil_buf = buf;
-		filv = _filv;
-	}
-	
+		async_state_change_finalize(callid, vfs_exch);
+		fd = fd_wait();
+		assert(fd == (int) filc);
+	}
+
+	vfs_exchange_end(vfs_exch);
+
 	async_answer_0(rid, EOK);
 }
@@ -308,5 +283,4 @@
 	
 	pcb.filc = filc;
-	pcb.filv = filv;
 	
 	if (prog_info.interp == NULL) {
Index: uspace/srv/loc/loc.h
===================================================================
--- uspace/srv/loc/loc.h	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/loc/loc.h	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -36,4 +36,5 @@
 #define LOC_H_
 
+#include <ipc/loc.h>
 #include <async.h>
 #include <fibril_synch.h>
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -37,4 +37,6 @@
 
 #include <ipc/services.h>
+#include <abi/ipc/event.h>
+#include <event.h>
 #include <ns.h>
 #include <async.h>
@@ -45,4 +47,5 @@
 #include <as.h>
 #include <atomic.h>
+#include <vfs/vfs.h>
 #include "vfs.h"
 
@@ -80,7 +83,4 @@
 			vfs_open(callid, &call);
 			break;
-		case VFS_IN_OPEN_NODE:
-			vfs_open_node(callid, &call);
-			break;
 		case VFS_IN_CLOSE:
 			vfs_close(callid, &call);
@@ -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);
@@ -128,4 +132,21 @@
 	 * connection fibril terminates.
 	 */
+}
+
+enum {
+	VFS_TASK_STATE_CHANGE
+};
+
+static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	switch (IPC_GET_IMETHOD(*call)) {
+	case VFS_TASK_STATE_CHANGE:
+		if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
+			vfs_pass_handle(IPC_GET_ARG4(*call),
+			    IPC_GET_ARG5(*call), (int) IPC_GET_ARG2(*call));
+		break;
+	default:
+		break;
+	}
 }
 
@@ -170,4 +191,10 @@
 
 	/*
+	 * Set notification handler and subscribe to notifications.
+	 */
+	async_set_interrupt_received(notification_received);
+	event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
+
+	/*
 	 * Register at the naming service.
 	 */
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs.h	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -175,5 +175,4 @@
 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
     vfs_pair_t *, ...);
-extern int vfs_open_node_internal(vfs_lookup_res_t *);
 
 extern bool vfs_nodes_init(void);
@@ -189,4 +188,7 @@
 extern void vfs_client_data_destroy(void *);
 
+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);
 extern void vfs_file_put(vfs_file_t *);
@@ -197,4 +199,5 @@
 extern void vfs_node_addref(vfs_node_t *);
 extern void vfs_node_delref(vfs_node_t *);
+extern int vfs_open_node_remote(vfs_node_t *);
 
 extern void vfs_register(ipc_callid_t, ipc_call_t *);
@@ -202,5 +205,4 @@
 extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
 extern void vfs_open(ipc_callid_t, ipc_call_t *);
-extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
 extern void vfs_sync(ipc_callid_t, ipc_call_t *);
 extern void vfs_dup(ipc_callid_t, ipc_call_t *);
@@ -215,4 +217,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 d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs_file.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -43,4 +43,5 @@
 #include <fibril.h>
 #include <fibril_synch.h>
+#include <adt/list.h>
 #include "vfs.h"
 
@@ -50,38 +51,57 @@
 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);
+
 /** Initialize the table of open files. */
-static bool vfs_files_init(void)
-{
-	fibril_mutex_lock(&VFS_DATA->lock);
-	if (!FILES) {
-		FILES = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
-		if (!FILES) {
-			fibril_mutex_unlock(&VFS_DATA->lock);
+static bool vfs_files_init(vfs_client_data_t *vfs_data)
+{
+	fibril_mutex_lock(&vfs_data->lock);
+	if (!vfs_data->files) {
+		vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
+		if (!vfs_data->files) {
+			fibril_mutex_unlock(&vfs_data->lock);
 			return false;
 		}
-		memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
-	}
-	fibril_mutex_unlock(&VFS_DATA->lock);
+		memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
+	}
+	fibril_mutex_unlock(&vfs_data->lock);
 	return true;
 }
 
 /** Cleanup the table of open files. */
-static void vfs_files_done(void)
+static void vfs_files_done(vfs_client_data_t *vfs_data)
 {
 	int i;
 
-	if (!FILES)
+	if (!vfs_data->files)
 		return;
 
 	for (i = 0; i < MAX_OPEN_FILES; i++) {
-		if (FILES[i]) {
-			(void) vfs_fd_free(i);
-		}
-	}
-	
-	free(FILES);
+		if (vfs_data->files[i])
+			(void) _vfs_fd_free(vfs_data, i);
+	}
+	
+	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);
+	}
 }
 
@@ -93,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;
 	}
@@ -103,5 +125,5 @@
 	vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
 
-	vfs_files_done();
+	vfs_files_done(vfs_data);
 	free(vfs_data);
 }
@@ -131,7 +153,7 @@
  *			incremented.
  */
-static void vfs_file_addref(vfs_file_t *file)
-{
-	assert(fibril_mutex_is_locked(&VFS_DATA->lock));
+static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file)
+{
+	assert(fibril_mutex_is_locked(&vfs_data->lock));
 
 	file->refcnt++;
@@ -143,9 +165,9 @@
  *			decremented.
  */
-static int vfs_file_delref(vfs_file_t *file)
+static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file)
 {
 	int rc = EOK;
 
-	assert(fibril_mutex_is_locked(&VFS_DATA->lock));
+	assert(fibril_mutex_is_locked(&vfs_data->lock));
 
 	if (file->refcnt-- == 1) {
@@ -162,16 +184,7 @@
 }
 
-
-/** Allocate a file descriptor.
- *
- * @param desc If true, look for an available file descriptor
- *             in a descending order.
- *
- * @return First available file descriptor or a negative error
- *         code.
- */
-int vfs_fd_alloc(bool desc)
-{
-	if (!vfs_files_init())
+static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
+{
+	if (!vfs_files_init(vfs_data))
 		return ENOMEM;
 	
@@ -182,17 +195,17 @@
 		i = 0;
 	
-	fibril_mutex_lock(&VFS_DATA->lock);
+	fibril_mutex_lock(&vfs_data->lock);
 	while (true) {
-		if (!FILES[i]) {
-			FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
-			if (!FILES[i]) {
-				fibril_mutex_unlock(&VFS_DATA->lock);
+		if (!vfs_data->files[i]) {
+			vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
+			if (!vfs_data->files[i]) {
+				fibril_mutex_unlock(&vfs_data->lock);
 				return ENOMEM;
 			}
 			
-			memset(FILES[i], 0, sizeof(vfs_file_t));
-			fibril_mutex_initialize(&FILES[i]->lock);
-			vfs_file_addref(FILES[i]);
-			fibril_mutex_unlock(&VFS_DATA->lock);
+			memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
+			fibril_mutex_initialize(&vfs_data->files[i]->lock);
+			vfs_file_addref(vfs_data, vfs_data->files[i]);
+			fibril_mutex_unlock(&vfs_data->lock);
 			return (int) i;
 		}
@@ -210,7 +223,40 @@
 		}
 	}
-	fibril_mutex_unlock(&VFS_DATA->lock);
+	fibril_mutex_unlock(&vfs_data->lock);
 	
 	return EMFILE;
+}
+
+/** Allocate a file descriptor.
+ *
+ * @param desc If true, look for an available file descriptor
+ *             in a descending order.
+ *
+ * @return First available file descriptor or a negative error
+ *         code.
+ */
+int vfs_fd_alloc(bool desc)
+{
+	return _vfs_fd_alloc(VFS_DATA, desc);
+}
+
+static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)
+{
+	int rc;
+
+	if (!vfs_files_init(vfs_data))
+		return ENOMEM;
+
+	fibril_mutex_lock(&vfs_data->lock);	
+	if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {
+		fibril_mutex_unlock(&vfs_data->lock);
+		return EBADF;
+	}
+	
+	rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);
+	vfs_data->files[fd] = NULL;
+	fibril_mutex_unlock(&vfs_data->lock);
+	
+	return rc;
 }
 
@@ -224,20 +270,5 @@
 int vfs_fd_free(int fd)
 {
-	int rc;
-
-	if (!vfs_files_init())
-		return ENOMEM;
-
-	fibril_mutex_lock(&VFS_DATA->lock);	
-	if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) {
-		fibril_mutex_unlock(&VFS_DATA->lock);
-		return EBADF;
-	}
-	
-	rc = vfs_file_delref(FILES[fd]);
-	FILES[fd] = NULL;
-	fibril_mutex_unlock(&VFS_DATA->lock);
-	
-	return rc;
+	return _vfs_fd_free(VFS_DATA, fd);
 }
 
@@ -253,5 +284,5 @@
 int vfs_fd_assign(vfs_file_t *file, int fd)
 {
-	if (!vfs_files_init())
+	if (!vfs_files_init(VFS_DATA))
 		return ENOMEM;
 
@@ -263,5 +294,5 @@
 	
 	FILES[fd] = file;
-	vfs_file_addref(FILES[fd]);
+	vfs_file_addref(VFS_DATA, FILES[fd]);
 	fibril_mutex_unlock(&VFS_DATA->lock);
 	
@@ -269,29 +300,41 @@
 }
 
-/** Find VFS file structure for a given file descriptor.
- *
- * @param fd		File descriptor.
- *
- * @return		VFS file structure corresponding to fd.
- */
-vfs_file_t *vfs_file_get(int fd)
-{
-	if (!vfs_files_init())
+static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
+{
+	if (!vfs_files_init(vfs_data))
 		return NULL;
 	
-	fibril_mutex_lock(&VFS_DATA->lock);
+	fibril_mutex_lock(&vfs_data->lock);
 	if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
-		vfs_file_t *file = FILES[fd];
+		vfs_file_t *file = vfs_data->files[fd];
 		if (file != NULL) {
-			vfs_file_addref(file);
-			fibril_mutex_unlock(&VFS_DATA->lock);
+			vfs_file_addref(vfs_data, file);
+			fibril_mutex_unlock(&vfs_data->lock);
 			return file;
 		}
 	}
-	fibril_mutex_unlock(&VFS_DATA->lock);
+	fibril_mutex_unlock(&vfs_data->lock);
 	
 	return NULL;
 }
 
+/** Find VFS file structure for a given file descriptor.
+ *
+ * @param fd		File descriptor.
+ *
+ * @return		VFS file structure corresponding to fd.
+ */
+vfs_file_t *vfs_file_get(int fd)
+{
+	return _vfs_file_get(VFS_DATA, fd);
+}
+
+static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
+{
+	fibril_mutex_lock(&vfs_data->lock);
+	vfs_file_delref(vfs_data, file);
+	fibril_mutex_unlock(&vfs_data->lock);
+}
+
 /** Stop using a file structure.
  *
@@ -300,7 +343,90 @@
 void vfs_file_put(vfs_file_t *file)
 {
-	fibril_mutex_lock(&VFS_DATA->lock);
-	vfs_file_delref(file);
-	fibril_mutex_unlock(&VFS_DATA->lock);
+	_vfs_file_put(VFS_DATA, file);
+}
+
+void vfs_pass_handle(sysarg_t donor_hash, sysarg_t acceptor_hash, int donor_fd)
+{
+	vfs_client_data_t *donor_data = NULL;
+	vfs_client_data_t *acceptor_data = NULL;
+	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)
+		goto out;
+
+	donor_file = _vfs_file_get(donor_data, donor_fd);
+	if (!donor_file)
+		goto out;
+
+	acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
+	if (acceptor_fd < 0)
+		goto out;
+
+	bh->handle = acceptor_fd;
+
+	/*
+	 * Add a new reference to the underlying VFS node.
+	 */
+	vfs_node_addref(donor_file->node);
+	(void) vfs_open_node_remote(donor_file->node);
+
+	acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
+	assert(acceptor_file);
+
+	/*
+	 * Inherit attributes from the donor.
+	 */
+	acceptor_file->node = donor_file->node;
+	acceptor_file->append = donor_file->append;
+	acceptor_file->pos = donor_file->pos;
+
+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);
+	if (acceptor_data)
+		async_put_client_data_by_hash(acceptor_hash);
+	if (donor_file)
+		_vfs_file_put(donor_data, donor_file);
+	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_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs_lookup.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -201,37 +201,4 @@
 }
 
-/** Perform a node open operation.
- *
- * @return EOK on success or an error code from errno.h.
- *
- */
-int vfs_open_node_internal(vfs_lookup_res_t *result)
-{
-	async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
-	    (sysarg_t) result->triplet.service_id,
-	    (sysarg_t) result->triplet.index, &answer);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	vfs_exchange_release(exch);
-	
-	if (rc == EOK) {
-		result->size =
-		    MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));
-		result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);
-		if (IPC_GET_ARG4(answer) & L_FILE)
-			result->type = VFS_NODE_FILE;
-		else if (IPC_GET_ARG4(answer) & L_DIRECTORY)
-			result->type = VFS_NODE_DIRECTORY;
-		else
-			result->type = VFS_NODE_UNKNOWN;
-	}
-	
-	return rc;
-}
-
 /**
  * @}
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs_node.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -293,4 +293,26 @@
 }
 
+
+/** Perform a remote node open operation.
+ *
+ * @return EOK on success or an error code from errno.h.
+ *
+ */
+int vfs_open_node_remote(vfs_node_t *node)
+{
+	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
+	    (sysarg_t) node->service_id, (sysarg_t) node->index, &answer);
+	
+	vfs_exchange_release(exch);
+
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision d0dd7b558f0c1e5da6887176956a13225dd0f05e)
+++ uspace/srv/vfs/vfs_ops.c	(revision e4067367f0d875aefe61063c520f1d6824d1d8cd)
@@ -618,77 +618,4 @@
 }
 
-void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
-{
-	// FIXME: check for sanity of the supplied fs, dev and index
-	
-	/*
-	 * The interface is open_node(fs, dev, index, oflag).
-	 */
-	vfs_lookup_res_t lr;
-	
-	lr.triplet.fs_handle = IPC_GET_ARG1(*request);
-	lr.triplet.service_id = IPC_GET_ARG2(*request);
-	lr.triplet.index = IPC_GET_ARG3(*request);
-	int oflag = IPC_GET_ARG4(*request);
-	
-	fibril_rwlock_read_lock(&namespace_rwlock);
-	
-	int rc = vfs_open_node_internal(&lr);
-	if (rc != EOK) {
-		fibril_rwlock_read_unlock(&namespace_rwlock);
-		async_answer_0(rid, rc);
-		return;
-	}
-	
-	vfs_node_t *node = vfs_node_get(&lr);
-	fibril_rwlock_read_unlock(&namespace_rwlock);
-	
-	/* Truncate the file if requested and if necessary. */
-	if (oflag & O_TRUNC) {
-		fibril_rwlock_write_lock(&node->contents_rwlock);
-		if (node->size) {
-			rc = vfs_truncate_internal(node->fs_handle,
-			    node->service_id, node->index, 0);
-			if (rc) {
-				fibril_rwlock_write_unlock(&node->contents_rwlock);
-				vfs_node_put(node);
-				async_answer_0(rid, rc);
-				return;
-			}
-			node->size = 0;
-		}
-		fibril_rwlock_write_unlock(&node->contents_rwlock);
-	}
-	
-	/*
-	 * Get ourselves a file descriptor and the corresponding vfs_file_t
-	 * structure.
-	 */
-	int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
-	if (fd < 0) {
-		vfs_node_put(node);
-		async_answer_0(rid, fd);
-		return;
-	}
-	vfs_file_t *file = vfs_file_get(fd);
-	file->node = node;
-	if (oflag & O_APPEND)
-		file->append = true;
-	
-	/*
-	 * The following increase in reference count is for the fact that the
-	 * file is being opened and that a file structure is pointing to it.
-	 * It is necessary so that the file will not disappear when
-	 * vfs_node_put() is called. The reference will be dropped by the
-	 * respective VFS_IN_CLOSE.
-	 */
-	vfs_node_addref(node);
-	vfs_node_put(node);
-	vfs_file_put(file);
-	
-	/* Success! Return the new file descriptor to the client. */
-	async_answer_1(rid, EOK, fd);
-}
-
 void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
 {
@@ -1349,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);
+}
+
 /**
  * @}
