Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libblock/libblock.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -47,5 +47,5 @@
 #include <as.h>
 #include <assert.h>
-#include <fibril_sync.h>
+#include <fibril_synch.h>
 #include <adt/list.h>
 #include <adt/hash_table.h>
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libblock/libblock.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -36,9 +36,9 @@
 
 #ifndef LIBBLOCK_LIBBLOCK_H_
-#define	LIBBLOCK_LIBBLOCK_H_ 
+#define LIBBLOCK_LIBBLOCK_H_
 
 #include <stdint.h>
 #include "../../srv/vfs/vfs.h"
-#include <fibril_sync.h>
+#include <fibril_synch.h>
 #include <adt/hash_table.h>
 #include <adt/list.h>
Index: uspace/lib/libc/Makefile.build
===================================================================
--- uspace/lib/libc/Makefile.build	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/Makefile.build	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -50,4 +50,5 @@
 	generic/as.c \
 	generic/cap.c \
+	generic/clipboard.c \
 	generic/devmap.c \
 	generic/event.c \
@@ -56,5 +57,5 @@
 	generic/string.c \
 	generic/fibril.c \
-	generic/fibril_sync.c \
+	generic/fibril_synch.c \
 	generic/pcb.c \
 	generic/smc.c \
Index: uspace/lib/libc/arch/amd64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/amd64/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -37,4 +37,8 @@
 #ifndef LIBC_amd64_ATOMIC_H_
 #define LIBC_amd64_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val) {
Index: uspace/lib/libc/arch/arm32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/arm32/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -37,4 +37,50 @@
 #define LIBC_arm32_ATOMIC_H_
 
+#define LIBC_ARCH_ATOMIC_H_
+#define CAS 
+
+#include <atomicdflt.h>
+#include <bool.h>
+#include <sys/types.h>
+
+extern uintptr_t *ras_page;
+
+static inline bool cas(atomic_t *val, long ov, long nv)
+{
+	long ret = 0;
+
+	/*
+	 * The following instructions between labels 1 and 2 constitute a
+	 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
+	 * the kernel will restart it.
+	 */
+	asm volatile (
+		"1:\n"
+		"	adr %[ret], 1b\n"
+		"	str %[ret], %[rp0]\n"
+		"	adr %[ret], 2f\n"
+		"	str %[ret], %[rp1]\n"
+		"	ldr %[ret], %[addr]\n"
+		"	cmp %[ret], %[ov]\n"
+		"	streq %[nv], %[addr]\n"
+		"2:\n"
+		"	moveq %[ret], #1\n"
+		"	movne %[ret], #0\n"
+		: [ret] "+&r" (ret),
+		  [rp0] "=m" (ras_page[0]),
+		  [rp1] "=m" (ras_page[1]),
+		  [addr] "+m" (val->count)
+		: [ov] "r" (ov),
+		  [nv] "r" (nv)
+		: "memory"
+	);
+
+	ras_page[0] = 0;
+	asm volatile ("" ::: "memory");	
+	ras_page[1] = 0xffffffff;
+
+	return (bool) ret;
+}
+
 /** Atomic addition.
  *
@@ -46,20 +92,31 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	int ret;
-	volatile long * mem = &(val->count);
+	long ret = 0;
 
+	/*
+	 * The following instructions between labels 1 and 2 constitute a
+	 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
+	 * the kernel will restart it.
+	 */
 	asm volatile (
-	"1:\n"
-		"ldr r2, [%1]\n"
-		"add r3, r2, %2\n"
-		"str r3, %0\n"
-		"swp r3, r3, [%1]\n"
-		"cmp r3, r2\n"
-		"bne 1b\n"
+		"1:\n"
+		"	adr %[ret], 1b\n"
+		"	str %[ret], %[rp0]\n"
+		"	adr %[ret], 2f\n"
+		"	str %[ret], %[rp1]\n"
+		"	ldr %[ret], %[addr]\n"
+		"	add %[ret], %[ret], %[imm]\n"
+		"	str %[ret], %[addr]\n"
+		"2:\n"
+		: [ret] "+&r" (ret),
+		  [rp0] "=m" (ras_page[0]),
+		  [rp1] "=m" (ras_page[1]),
+		  [addr] "+m" (val->count)
+		: [imm] "r" (i)
+	);
 
-		: "=m" (ret)
-		: "r" (mem), "r" (i)
-		: "r3", "r2"
-	);
+	ras_page[0] = 0;
+	asm volatile ("" ::: "memory");	
+	ras_page[1] = 0xffffffff;
 
 	return ret;
Index: uspace/lib/libc/arch/arm32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/arm32/src/entry.s	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/arm32/src/entry.s	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -36,6 +36,11 @@
 #
 # r1 contains the PCB pointer
+# r2 contains the RAS page address
 #
 __entry:
+	# Store the RAS page address into the ras_page variable
+	ldr r0, =ras_page
+	str r2, [r0]
+
 	# Pass pcb_ptr to __main as the first argument (in r0)
 	mov r0, r1
@@ -43,2 +48,9 @@
 
 	bl __exit
+
+.data
+
+.global ras_page
+ras_page:
+	.long 0
+
Index: uspace/lib/libc/arch/arm32/src/syscall.c
===================================================================
--- uspace/lib/libc/arch/arm32/src/syscall.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/arm32/src/syscall.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -60,6 +60,7 @@
 	register sysarg_t __arm_reg_r5 asm("r5") = p6;
 	register sysarg_t __arm_reg_r6 asm("r6") = id;
-
-	asm volatile ( "swi"
+	
+	asm volatile (
+		"swi 0"
 		: "=r" (__arm_reg_r0)
 		: "r" (__arm_reg_r0),
@@ -71,5 +72,5 @@
 		  "r" (__arm_reg_r6)
 	);
-
+	
 	return __arm_reg_r0;
 }
Index: uspace/lib/libc/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia32/Makefile.inc	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/ia32/Makefile.inc	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -39,4 +39,5 @@
 	arch/$(UARCH)/src/setjmp.S
 
+GCC_CFLAGS += -march=pentium
 LFLAGS += -N
 
Index: uspace/lib/libc/arch/ia32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/ia32/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -35,4 +35,8 @@
 #ifndef LIBC_ia32_ATOMIC_H_
 #define LIBC_ia32_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val) {
Index: uspace/lib/libc/arch/ia64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/ia64/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -35,4 +35,8 @@
 #ifndef LIBC_ia64_ATOMIC_H_
 #define LIBC_ia64_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val)
Index: uspace/lib/libc/arch/mips32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/mips32/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -36,4 +36,8 @@
 #ifndef LIBC_mips32_ATOMIC_H_
 #define LIBC_mips32_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 
 #define atomic_inc(x)	((void) atomic_add(x, 1))
Index: uspace/lib/libc/arch/ppc32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/ppc32/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -35,4 +35,8 @@
 #ifndef LIBC_ppc32_ATOMIC_H_
 #define LIBC_ppc32_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val)
Index: uspace/lib/libc/arch/sparc64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/arch/sparc64/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -36,4 +36,7 @@
 #define LIBC_sparc64_ATOMIC_H_
 
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 #include <sys/types.h>
 
Index: uspace/lib/libc/generic/async.c
===================================================================
--- uspace/lib/libc/generic/async.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/async.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -392,4 +392,18 @@
 	/* If nothing in queue, wait until something arrives */
 	while (list_empty(&conn->msg_queue)) {
+		if (conn->close_callid) {
+			/*
+			 * Handle the case when the connection was already
+			 * closed by the client but the server did not notice
+			 * the first IPC_M_PHONE_HUNGUP call and continues to
+			 * call async_get_call_timeout(). Repeat
+			 * IPC_M_PHONE_HUNGUP until the caller notices. 
+			 */
+			memset(call, 0, sizeof(ipc_call_t));
+			IPC_SET_METHOD(*call, IPC_M_PHONE_HUNGUP);
+			futex_up(&async_futex);
+			return conn->close_callid;
+		}
+
 		if (usecs)
 			async_insert_timeout(&conn->wdata);
@@ -528,5 +542,5 @@
 	list_initialize(&conn->msg_queue);
 	conn->callid = callid;
-	conn->close_callid = false;
+	conn->close_callid = 0;
 	
 	if (call)
@@ -1331,4 +1345,97 @@
 }
 
+/** Wrapper for receiving blobs via the async_data_write_*
+ *
+ * This wrapper only makes it more comfortable to use async_data_write_*
+ * functions to receive blobs.
+ *
+ * @param blob     Pointer to data pointer (which should be later disposed
+ *                 by free()). If the operation fails, the pointer is not
+ *                 touched.
+ * @param max_size Maximum size (in bytes) of the blob to receive. 0 means
+ *                 no limit.
+ * @param received If not NULL, the size of the received data is stored here.
+ *
+ * @return Zero on success or a value from @ref errno.h on failure.
+ *
+ */
+int async_data_blob_receive(char **blob, const size_t max_size, size_t *received)
+{
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_write_receive(&callid, &size)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	if ((max_size > 0) && (size > max_size)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	char *data = (char *) malloc(size);
+	if (data == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		return ENOMEM;
+	}
+	
+	int rc = async_data_write_finalize(callid, data, size);
+	if (rc != EOK) {
+		free(data);
+		return rc;
+	}
+	
+	*blob = data;
+	if (received != NULL)
+		*received = size;
+	
+	return EOK;
+}
+
+/** Wrapper for receiving strings via the async_data_write_*
+ *
+ * This wrapper only makes it more comfortable to use async_data_write_*
+ * functions to receive strings.
+ *
+ * @param str      Pointer to string pointer (which should be later disposed
+ *                 by free()). If the operation fails, the pointer is not
+ *                 touched.
+ * @param max_size Maximum size (in bytes) of the string to receive. 0 means
+ *                 no limit.
+ *
+ * @return Zero on success or a value from @ref errno.h on failure.
+ *
+ */
+int async_data_string_receive(char **str, const size_t max_size)
+{
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_write_receive(&callid, &size)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	if ((max_size > 0) && (size > max_size)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	char *data = (char *) malloc(size + 1);
+	if (data == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		return ENOMEM;
+	}
+	
+	int rc = async_data_write_finalize(callid, data, size);
+	if (rc != EOK) {
+		free(data);
+		return rc;
+	}
+	
+	data[size] = 0;
+	*str = data;
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/libc/generic/clipboard.c
===================================================================
--- uspace/lib/libc/generic/clipboard.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/generic/clipboard.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * @brief System clipboard API.
+ *
+ * The clipboard data is managed by the clipboard service and it is shared by
+ * the entire system.
+ *
+ */
+
+#include <clipboard.h>
+#include <ipc/services.h>
+#include <ipc/clipboard.h>
+#include <async.h>
+#include <string.h>
+#include <errno.h>
+#include <malloc.h>
+
+static int clip_phone = -1;
+
+/** Connect to clipboard server
+ *
+ */
+static void clip_connect(void)
+{
+	while (clip_phone < 0)
+		clip_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_CLIPBOARD, 0, 0);
+}
+
+/** Copy string to clipboard.
+ *
+ * Sets the clipboard contents to @a str. Passing an empty string or NULL
+ * makes the clipboard empty.
+ *
+ * @param str String to put to clipboard or NULL.
+ *
+ * @return Zero on success or negative error code.
+ *
+ */
+int clipboard_put_str(const char *str)
+{
+	size_t size = str_size(str);
+	
+	if (size == 0) {
+		async_serialize_start();
+		clip_connect();
+		
+		ipcarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
+		
+		async_serialize_end();
+		
+		return (int) rc;
+	} else {
+		async_serialize_start();
+		clip_connect();
+		
+		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_BLOB, NULL);
+		ipcarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
+		if (rc != EOK) {
+			ipcarg_t rc_orig;
+			async_wait_for(req, &rc_orig);
+			async_serialize_end();
+			if (rc_orig == EOK)
+				return (int) rc;
+			else
+				return (int) rc_orig;
+		}
+		
+		async_wait_for(req, &rc);
+		async_serialize_end();
+		
+		return (int) rc;
+	}
+}
+
+/** Get a copy of clipboard contents.
+ *
+ * Returns a new string that can be deallocated with free().
+ *
+ * @param str Here pointer to the newly allocated string is stored.
+ *
+ * @return Zero on success or negative error code.
+ *
+ */
+int clipboard_get_str(char **str)
+{
+	/* Loop until clipboard read succesful */
+	while (true) {
+		async_serialize_start();
+		clip_connect();
+		
+		ipcarg_t size;
+		ipcarg_t tag;
+		ipcarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
+		
+		async_serialize_end();
+		
+		if (rc != EOK)
+			return (int) rc;
+		
+		char *sbuf;
+		
+		switch (tag) {
+		case CLIPBOARD_TAG_NONE:
+			sbuf = malloc(1);
+			if (sbuf == NULL)
+				return ENOMEM;
+			
+			sbuf[0] = 0;
+			*str = sbuf;
+			return EOK;
+		case CLIPBOARD_TAG_BLOB:
+			sbuf = malloc(size + 1);
+			if (sbuf == NULL)
+				return ENOMEM;
+			
+			async_serialize_start();
+			
+			aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
+			rc = async_data_read_start(clip_phone, (void *) sbuf, size);
+			if (rc == EOVERFLOW) {
+				/*
+				 * The data in the clipboard has changed since
+				 * the last call of CLIPBOARD_CONTENT
+				 */
+				async_serialize_end();
+				break;
+			}
+			
+			if (rc != EOK) {
+				ipcarg_t rc_orig;
+				async_wait_for(req, &rc_orig);
+				async_serialize_end();
+				if (rc_orig == EOK)
+					return (int) rc;
+				else
+					return (int) rc_orig;
+			}
+			
+			async_wait_for(req, &rc);
+			async_serialize_end();
+			
+			if (rc == EOK) {
+				sbuf[size] = 0;
+				*str = sbuf;
+			}
+			
+			return rc;
+		default:
+			return EINVAL;
+		}
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/libc/generic/devmap.c
===================================================================
--- uspace/lib/libc/generic/devmap.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/devmap.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -35,4 +35,6 @@
 #include <async.h>
 #include <errno.h>
+#include <malloc.h>
+#include <bool.h>
 
 static int devmap_phone_driver = -1;
@@ -105,6 +107,5 @@
 	aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -126,9 +127,10 @@
 /** Register new device.
  *
- * @param name   Device name.
- * @param handle Output: Handle to the created instance of device.
+ * @param namespace Namespace name.
+ * @param fqdn      Fully qualified device name.
+ * @param handle    Output: Handle to the created instance of device.
  *
  */
-int devmap_device_register(const char *name, dev_handle_t *handle)
+int devmap_device_register(const char *fqdn, dev_handle_t *handle)
 {
 	int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
@@ -143,6 +145,5 @@
 	    &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -167,5 +168,5 @@
 }
 
-int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
+int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags)
 {
 	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
@@ -180,6 +181,5 @@
 	    &answer);
 	
-	ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
-	
+	ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -202,4 +202,55 @@
 	
 	return retval;
+}
+
+int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
+	
+	if (phone < 0)
+		return phone;
+	
+	async_serialize_start();
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
+	    &answer);
+	
+	ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		return retval;
+	}
+	
+	async_wait_for(req, &retval);
+	
+	async_serialize_end();
+	
+	if (retval != EOK) {
+		if (handle != NULL)
+			*handle = (dev_handle_t) -1;
+		return retval;
+	}
+	
+	if (handle != NULL)
+		*handle = (dev_handle_t) IPC_GET_ARG1(answer);
+	
+	return retval;
+}
+
+devmap_handle_type_t devmap_handle_probe(dev_handle_t handle)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return phone;
+	
+	ipcarg_t type;
+	int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
+	if (retval != EOK)
+		return DEV_HANDLE_NONE;
+	
+	return (devmap_handle_type_t) type;
 }
 
@@ -227,5 +278,5 @@
 	
 	ipcarg_t null_id;
-	int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
+	int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
 	if (retval != EOK)
 		return -1;
@@ -241,16 +292,11 @@
 		return;
 	
-	async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
-}
-
-ipcarg_t devmap_device_get_count(void)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
+	async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id);
+}
+
+static size_t devmap_count_namespaces_internal(int phone)
+{
 	ipcarg_t count;
-	int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
+	int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
 	if (retval != EOK)
 		return 0;
@@ -259,31 +305,135 @@
 }
 
-ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
-	async_serialize_start();
-	
-	ipc_call_t answer;
-	aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
-	
-	ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
-	
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return 0;
-	}
-	
-	async_wait_for(req, &retval);
-	
-	async_serialize_end();
-	
+static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle)
+{
+	ipcarg_t count;
+	int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
 	if (retval != EOK)
 		return 0;
 	
-	return IPC_GET_ARG1(answer);
-}
+	return count;
+}
+
+size_t devmap_count_namespaces(void)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	return devmap_count_namespaces_internal(phone);
+}
+
+size_t devmap_count_devices(dev_handle_t ns_handle)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	return devmap_count_devices_internal(phone, ns_handle);
+}
+
+size_t devmap_get_namespaces(dev_desc_t **data)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	/* Loop until namespaces read succesful */
+	while (true) {
+		size_t count = devmap_count_namespaces_internal(phone);
+		if (count == 0)
+			return 0;
+		
+		dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
+		if (devs == NULL)
+			return 0;
+		
+		async_serialize_start();
+		
+		ipc_call_t answer;
+		aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
+		
+		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		if (rc == EOVERFLOW) {
+			/*
+			 * Number of namespaces has changed since
+			 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
+			 */
+			async_serialize_end();
+			free(devs);
+			continue;
+		}
+		
+		if (rc != EOK) {
+			async_wait_for(req, NULL);
+			async_serialize_end();
+			free(devs);
+			return 0;
+		}
+		
+		ipcarg_t retval;
+		async_wait_for(req, &retval);
+		async_serialize_end();
+		
+		if (retval != EOK)
+			return 0;
+		
+		*data = devs;
+		return count;
+	}
+}
+
+size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data)
+{
+	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
+	
+	if (phone < 0)
+		return 0;
+	
+	/* Loop until namespaces read succesful */
+	while (true) {
+		size_t count = devmap_count_devices_internal(phone, ns_handle);
+		if (count == 0)
+			return 0;
+		
+		dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
+		if (devs == NULL)
+			return 0;
+		
+		async_serialize_start();
+		
+		ipc_call_t answer;
+		aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
+		
+		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		if (rc == EOVERFLOW) {
+			/*
+			 * Number of devices has changed since
+			 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
+			 */
+			async_serialize_end();
+			free(devs);
+			continue;
+		}
+		
+		if (rc != EOK) {
+			async_wait_for(req, NULL);
+			async_serialize_end();
+			free(devs);
+			return 0;
+		}
+		
+		ipcarg_t retval;
+		async_wait_for(req, &retval);
+		async_serialize_end();
+		
+		if (retval != EOK)
+			return 0;
+		
+		*data = devs;
+		return count;
+	}
+}
Index: uspace/lib/libc/generic/fibril_sync.c
===================================================================
--- uspace/lib/libc/generic/fibril_sync.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ 	(revision )
@@ -1,308 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <fibril_sync.h>
-#include <fibril.h>
-#include <async.h>
-#include <async_priv.h>
-#include <adt/list.h>
-#include <futex.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <assert.h>
-
-static void optimize_execution_power(void)
-{
-	/*
-	 * When waking up a worker fibril previously blocked in fibril
-	 * synchronization, chances are that there is an idle manager fibril
-	 * waiting for IPC, that could start executing the awakened worker
-	 * fibril right away. We try to detect this and bring the manager
-	 * fibril back to fruitful work.
-	 */
-	if (atomic_get(&threads_in_ipc_wait) > 0)
-		ipc_poke();
-}
-
-void fibril_mutex_initialize(fibril_mutex_t *fm)
-{
-	fm->counter = 1;
-	list_initialize(&fm->waiters);
-}
-
-void fibril_mutex_lock(fibril_mutex_t *fm)
-{
-	futex_down(&async_futex);
-	if (fm->counter-- <= 0) {
-		awaiter_t wdata;
-
-		wdata.fid = fibril_get_id();
-		wdata.active = false;
-		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
-		list_append(&wdata.wu_event.link, &fm->waiters);
-		fibril_switch(FIBRIL_TO_MANAGER);
-	} else {
-		futex_up(&async_futex);
-	}
-}
-
-bool fibril_mutex_trylock(fibril_mutex_t *fm)
-{
-	bool locked = false;
-	
-	futex_down(&async_futex);
-	if (fm->counter > 0) {
-		fm->counter--;
-		locked = true;
-	}
-	futex_up(&async_futex);
-	
-	return locked;
-}
-
-static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
-{
-	assert(fm->counter <= 0);
-	if (fm->counter++ < 0) {
-		link_t *tmp;
-		awaiter_t *wdp;
-	
-		assert(!list_empty(&fm->waiters));
-		tmp = fm->waiters.next;
-		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
-		wdp->active = true;
-		wdp->wu_event.inlist = false;
-		list_remove(&wdp->wu_event.link);
-		fibril_add_ready(wdp->fid);
-		optimize_execution_power();
-	}
-}
-
-void fibril_mutex_unlock(fibril_mutex_t *fm)
-{
-	futex_down(&async_futex);
-	_fibril_mutex_unlock_unsafe(fm);
-	futex_up(&async_futex);
-}
-
-void fibril_rwlock_initialize(fibril_rwlock_t *frw)
-{
-	frw->writers = 0;
-	frw->readers = 0;
-	list_initialize(&frw->waiters);
-}
-
-void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
-{
-	futex_down(&async_futex);
-	if (frw->writers) {
-		fibril_t *f = (fibril_t *) fibril_get_id();
-		awaiter_t wdata;
-
-		wdata.fid = (fid_t) f;
-		wdata.active = false;
-		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
-		f->flags &= ~FIBRIL_WRITER;
-		list_append(&wdata.wu_event.link, &frw->waiters);
-		fibril_switch(FIBRIL_TO_MANAGER);
-	} else {
-		frw->readers++;
-		futex_up(&async_futex);
-	}
-}
-
-void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
-{
-	futex_down(&async_futex);
-	if (frw->writers || frw->readers) {
-		fibril_t *f = (fibril_t *) fibril_get_id();
-		awaiter_t wdata;
-
-		wdata.fid = (fid_t) f;
-		wdata.active = false;
-		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
-		f->flags |= FIBRIL_WRITER;
-		list_append(&wdata.wu_event.link, &frw->waiters);
-		fibril_switch(FIBRIL_TO_MANAGER);
-	} else {
-		frw->writers++;
-		futex_up(&async_futex);
-	}
-}
-
-static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
-{
-	futex_down(&async_futex);
-	assert(frw->readers || (frw->writers == 1));
-	if (frw->readers) {
-		if (--frw->readers)
-			goto out;
-	} else {
-		frw->writers--;
-	}
-	
-	assert(!frw->readers && !frw->writers);
-	
-	while (!list_empty(&frw->waiters)) {
-		link_t *tmp = frw->waiters.next;
-		awaiter_t *wdp;
-		fibril_t *f;
-		
-		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
-		f = (fibril_t *) wdp->fid;
-		
-		if (f->flags & FIBRIL_WRITER) {
-			if (frw->readers)
-				break;
-			wdp->active = true;
-			wdp->wu_event.inlist = false;
-			list_remove(&wdp->wu_event.link);
-			fibril_add_ready(wdp->fid);
-			frw->writers++;
-			optimize_execution_power();
-			break;
-		} else {
-			wdp->active = true;
-			wdp->wu_event.inlist = false;
-			list_remove(&wdp->wu_event.link);
-			fibril_add_ready(wdp->fid);
-			frw->readers++;
-			optimize_execution_power();
-		}
-	}
-out:
-	futex_up(&async_futex);
-}
-
-void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
-{
-	_fibril_rwlock_common_unlock(frw);
-}
-
-void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
-{
-	_fibril_rwlock_common_unlock(frw);
-}
-
-void fibril_condvar_initialize(fibril_condvar_t *fcv)
-{
-	list_initialize(&fcv->waiters);
-}
-
-int
-fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm,
-    suseconds_t timeout)
-{
-	awaiter_t wdata;
-
-	if (timeout < 0)
-		return ETIMEOUT;
-
-	wdata.fid = fibril_get_id();
-	wdata.active = false;
-	
-	wdata.to_event.inlist = timeout > 0;
-	wdata.to_event.occurred = false;
-	link_initialize(&wdata.to_event.link);
-
-	wdata.wu_event.inlist = true;
-	link_initialize(&wdata.wu_event.link);
-
-	futex_down(&async_futex);
-	if (timeout) {
-		gettimeofday(&wdata.to_event.expires, NULL);
-		tv_add(&wdata.to_event.expires, timeout);
-		async_insert_timeout(&wdata);
-	}
-	list_append(&wdata.wu_event.link, &fcv->waiters);
-	_fibril_mutex_unlock_unsafe(fm);
-	fibril_switch(FIBRIL_TO_MANAGER);
-	fibril_mutex_lock(fm);
-
-	/* async_futex not held after fibril_switch() */
-	futex_down(&async_futex);
-	if (wdata.to_event.inlist)
-		list_remove(&wdata.to_event.link);
-	if (wdata.wu_event.inlist)
-		list_remove(&wdata.wu_event.link);
-	futex_up(&async_futex);
-	
-	return wdata.to_event.occurred ? ETIMEOUT : EOK;
-}
-
-void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
-{
-	int rc;
-
-	rc = fibril_condvar_wait_timeout(fcv, fm, 0);
-	assert(rc == EOK);
-}
-
-static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
-{
-	link_t *tmp;
-	awaiter_t *wdp;
-
-	futex_down(&async_futex);
-	while (!list_empty(&fcv->waiters)) {
-		tmp = fcv->waiters.next;
-		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
-		list_remove(&wdp->wu_event.link);
-		wdp->wu_event.inlist = false;
-		if (!wdp->active) {
-			wdp->active = true;
-			fibril_add_ready(wdp->fid);
-			optimize_execution_power();
-			if (once)
-				break;
-		}
-	}
-	futex_up(&async_futex);
-}
-
-void fibril_condvar_signal(fibril_condvar_t *fcv)
-{
-	_fibril_condvar_wakeup_common(fcv, true);
-}
-
-void fibril_condvar_broadcast(fibril_condvar_t *fcv)
-{
-	_fibril_condvar_wakeup_common(fcv, false);
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/fibril_synch.c
===================================================================
--- uspace/lib/libc/generic/fibril_synch.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/generic/fibril_synch.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <fibril_synch.h>
+#include <fibril.h>
+#include <async.h>
+#include <async_priv.h>
+#include <adt/list.h>
+#include <futex.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <assert.h>
+
+static void optimize_execution_power(void)
+{
+	/*
+	 * When waking up a worker fibril previously blocked in fibril
+	 * synchronization, chances are that there is an idle manager fibril
+	 * waiting for IPC, that could start executing the awakened worker
+	 * fibril right away. We try to detect this and bring the manager
+	 * fibril back to fruitful work.
+	 */
+	if (atomic_get(&threads_in_ipc_wait) > 0)
+		ipc_poke();
+}
+
+void fibril_mutex_initialize(fibril_mutex_t *fm)
+{
+	fm->counter = 1;
+	list_initialize(&fm->waiters);
+}
+
+void fibril_mutex_lock(fibril_mutex_t *fm)
+{
+	futex_down(&async_futex);
+	if (fm->counter-- <= 0) {
+		awaiter_t wdata;
+
+		wdata.fid = fibril_get_id();
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
+		list_append(&wdata.wu_event.link, &fm->waiters);
+		fibril_switch(FIBRIL_TO_MANAGER);
+	} else {
+		futex_up(&async_futex);
+	}
+}
+
+bool fibril_mutex_trylock(fibril_mutex_t *fm)
+{
+	bool locked = false;
+	
+	futex_down(&async_futex);
+	if (fm->counter > 0) {
+		fm->counter--;
+		locked = true;
+	}
+	futex_up(&async_futex);
+	
+	return locked;
+}
+
+static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
+{
+	assert(fm->counter <= 0);
+	if (fm->counter++ < 0) {
+		link_t *tmp;
+		awaiter_t *wdp;
+	
+		assert(!list_empty(&fm->waiters));
+		tmp = fm->waiters.next;
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		wdp->active = true;
+		wdp->wu_event.inlist = false;
+		list_remove(&wdp->wu_event.link);
+		fibril_add_ready(wdp->fid);
+		optimize_execution_power();
+	}
+}
+
+void fibril_mutex_unlock(fibril_mutex_t *fm)
+{
+	futex_down(&async_futex);
+	_fibril_mutex_unlock_unsafe(fm);
+	futex_up(&async_futex);
+}
+
+void fibril_rwlock_initialize(fibril_rwlock_t *frw)
+{
+	frw->writers = 0;
+	frw->readers = 0;
+	list_initialize(&frw->waiters);
+}
+
+void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
+{
+	futex_down(&async_futex);
+	if (frw->writers) {
+		fibril_t *f = (fibril_t *) fibril_get_id();
+		awaiter_t wdata;
+
+		wdata.fid = (fid_t) f;
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
+		f->flags &= ~FIBRIL_WRITER;
+		list_append(&wdata.wu_event.link, &frw->waiters);
+		fibril_switch(FIBRIL_TO_MANAGER);
+	} else {
+		frw->readers++;
+		futex_up(&async_futex);
+	}
+}
+
+void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
+{
+	futex_down(&async_futex);
+	if (frw->writers || frw->readers) {
+		fibril_t *f = (fibril_t *) fibril_get_id();
+		awaiter_t wdata;
+
+		wdata.fid = (fid_t) f;
+		wdata.active = false;
+		wdata.wu_event.inlist = true;
+		link_initialize(&wdata.wu_event.link);
+		f->flags |= FIBRIL_WRITER;
+		list_append(&wdata.wu_event.link, &frw->waiters);
+		fibril_switch(FIBRIL_TO_MANAGER);
+	} else {
+		frw->writers++;
+		futex_up(&async_futex);
+	}
+}
+
+static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
+{
+	futex_down(&async_futex);
+	assert(frw->readers || (frw->writers == 1));
+	if (frw->readers) {
+		if (--frw->readers)
+			goto out;
+	} else {
+		frw->writers--;
+	}
+	
+	assert(!frw->readers && !frw->writers);
+	
+	while (!list_empty(&frw->waiters)) {
+		link_t *tmp = frw->waiters.next;
+		awaiter_t *wdp;
+		fibril_t *f;
+		
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		f = (fibril_t *) wdp->fid;
+		
+		if (f->flags & FIBRIL_WRITER) {
+			if (frw->readers)
+				break;
+			wdp->active = true;
+			wdp->wu_event.inlist = false;
+			list_remove(&wdp->wu_event.link);
+			fibril_add_ready(wdp->fid);
+			frw->writers++;
+			optimize_execution_power();
+			break;
+		} else {
+			wdp->active = true;
+			wdp->wu_event.inlist = false;
+			list_remove(&wdp->wu_event.link);
+			fibril_add_ready(wdp->fid);
+			frw->readers++;
+			optimize_execution_power();
+		}
+	}
+out:
+	futex_up(&async_futex);
+}
+
+void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
+{
+	_fibril_rwlock_common_unlock(frw);
+}
+
+void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
+{
+	_fibril_rwlock_common_unlock(frw);
+}
+
+void fibril_condvar_initialize(fibril_condvar_t *fcv)
+{
+	list_initialize(&fcv->waiters);
+}
+
+int
+fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm,
+    suseconds_t timeout)
+{
+	awaiter_t wdata;
+
+	if (timeout < 0)
+		return ETIMEOUT;
+
+	wdata.fid = fibril_get_id();
+	wdata.active = false;
+	
+	wdata.to_event.inlist = timeout > 0;
+	wdata.to_event.occurred = false;
+	link_initialize(&wdata.to_event.link);
+
+	wdata.wu_event.inlist = true;
+	link_initialize(&wdata.wu_event.link);
+
+	futex_down(&async_futex);
+	if (timeout) {
+		gettimeofday(&wdata.to_event.expires, NULL);
+		tv_add(&wdata.to_event.expires, timeout);
+		async_insert_timeout(&wdata);
+	}
+	list_append(&wdata.wu_event.link, &fcv->waiters);
+	_fibril_mutex_unlock_unsafe(fm);
+	fibril_switch(FIBRIL_TO_MANAGER);
+	fibril_mutex_lock(fm);
+
+	/* async_futex not held after fibril_switch() */
+	futex_down(&async_futex);
+	if (wdata.to_event.inlist)
+		list_remove(&wdata.to_event.link);
+	if (wdata.wu_event.inlist)
+		list_remove(&wdata.wu_event.link);
+	futex_up(&async_futex);
+	
+	return wdata.to_event.occurred ? ETIMEOUT : EOK;
+}
+
+void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
+{
+	int rc;
+
+	rc = fibril_condvar_wait_timeout(fcv, fm, 0);
+	assert(rc == EOK);
+}
+
+static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
+{
+	link_t *tmp;
+	awaiter_t *wdp;
+
+	futex_down(&async_futex);
+	while (!list_empty(&fcv->waiters)) {
+		tmp = fcv->waiters.next;
+		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+		list_remove(&wdp->wu_event.link);
+		wdp->wu_event.inlist = false;
+		if (!wdp->active) {
+			wdp->active = true;
+			fibril_add_ready(wdp->fid);
+			optimize_execution_power();
+			if (once)
+				break;
+		}
+	}
+	futex_up(&async_futex);
+}
+
+void fibril_condvar_signal(fibril_condvar_t *fcv)
+{
+	_fibril_condvar_wakeup_common(fcv, true);
+}
+
+void fibril_condvar_broadcast(fibril_condvar_t *fcv)
+{
+	_fibril_condvar_wakeup_common(fcv, false);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/generic/futex.c
===================================================================
--- uspace/lib/libc/generic/futex.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/futex.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -36,49 +36,5 @@
 #include <atomic.h>
 #include <libc.h>
-#include <stdio.h>
 #include <sys/types.h>
-#include <kernel/synch/synch.h>
-
-/*
- * Note about race conditions.
- * Because of non-atomic nature of operations performed sequentially on the
- * futex counter and the futex wait queue, there is a race condition:
- *
- * (wq->missed_wakeups == 1) && (futex->count = 1)
- *
- * Scenario 1 (wait queue timeout vs. futex_up()):
- * 1. assume wq->missed_wakeups == 0 && futex->count == -1
- *    (ie. thread A sleeping, thread B in the critical section)
- * 2. A receives timeout and gets removed from the wait queue
- * 3. B wants to leave the critical section and calls futex_up()
- * 4. B thus changes futex->count from -1 to 0
- * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread
- * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 1
- * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it
- *    from 0 to 1
- *
- * Scenario 2 (conditional down operation vs. futex_up)
- * 1. assume wq->missed_wakeups == 0 && futex->count == 0
- *    (i.e. thread A is in the critical section)
- * 2. thread B performs futex_trydown() operation and changes futex->count from
- *    0 to -1
- *    B is now obliged to call SYS_FUTEX_SLEEP syscall
- * 3. A wants to leave the critical section and does futex_up()
- * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP
- *    syscall
- * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep
- * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from
- *    0 to 1
- * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it
- *    from 0 to 1
- *
- * Both scenarios allow two threads to be in the critical section
- * simultaneously. One without kernel intervention and the other through
- * wq->missed_wakeups being 1.
- *
- * To mitigate this problem, futex_down_timeout() detects that the syscall
- * didn't sleep in the wait queue, fixes the futex counter and RETRIES the
- * whole operation again.
- */
 
 /** Initialize futex counter.
@@ -92,81 +48,28 @@
 }
 
-int futex_down(futex_t *futex)
-{
-	return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
-}
-
-int futex_trydown(futex_t *futex)
-{
-	return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,
-	    SYNCH_FLAGS_NON_BLOCKING);
-}
-
 /** Try to down the futex.
  *
  * @param futex		Futex.
- * @param usec		Microseconds to wait. Zero value means sleep without
- * 			timeout.
- * @param flags		Select mode of operation. See comment for
- * 			waitq_sleep_timeout(). 
+ * @return		Non-zero if the futex was acquired.
+ * @return		Zero if the futex was not acquired.
+ */
+int futex_trydown(futex_t *futex)
+{
+	return cas(futex, 1, 0);
+}
+
+/** Down the futex.
  *
- * @return		ENOENT if there is no such virtual address. One of
- * 			ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or
- * 			ESYNCH_TIMEOUT if the lock was not acquired because of
- * 			a timeout or ESYNCH_WOULD_BLOCK if the operation could
- * 			not be carried out atomically (if requested so).
+ * @param futex		Futex.
+ * @return		ENOENT if there is no such virtual address.
+ * @return		Zero in the uncontended case. 
+ * @return		Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
  */
-int futex_down_timeout(futex_t *futex, uint32_t usec, int flags)
+int futex_down(futex_t *futex)
 {
-	int rc;
-	
-	while (atomic_predec(futex) < 0) {
-		rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count,
-		    (sysarg_t) usec, (sysarg_t) flags);
-		
-		switch (rc) {
-		case ESYNCH_OK_ATOMIC:
-			/*
-			 * Because of a race condition between timeout and
-			 * futex_up() and between conditional
-			 * futex_down_timeout() and futex_up(), we have to give
-			 * up and try again in this special case.
-			 */
-			atomic_inc(futex);
-			break;
+	if (atomic_predec(futex) < 0)
+		return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
 
-		case ESYNCH_TIMEOUT:
-			atomic_inc(futex);
-			return ESYNCH_TIMEOUT;
-			break;
-
-		case ESYNCH_WOULD_BLOCK:
-			/*
-			 * The conditional down operation should be implemented
-			 * this way. The userspace-only variant tends to
-			 * accumulate missed wakeups in the kernel futex wait
-			 * queue.
-			 */
-			atomic_inc(futex);
-			return ESYNCH_WOULD_BLOCK;
-			break;
-
-		case ESYNCH_OK_BLOCKED:
-			/*
-			 * Enter the critical section.
-			 * The futex counter has already been incremented for
-			 * us.
-			 */
-			return ESYNCH_OK_BLOCKED;
-			break;
-		default:
-			return rc;
-		}
-	}
-
-	/*
-	 * Enter the critical section.
-	 */
-	return ESYNCH_OK_ATOMIC;
+	return 0;
 }
 
@@ -174,14 +77,10 @@
  *
  * @param futex		Futex.
- *
- * @return		ENOENT if there is no such virtual address. Otherwise
- * 			zero.
+ * @return		ENOENT if there is no such virtual address.
+ * @return		Zero in the uncontended case.
  */
 int futex_up(futex_t *futex)
 {
-	long val;
-	
-	val = atomic_postinc(futex);
-	if (val < 0)
+	if (atomic_postinc(futex) < 0)
 		return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
 		
Index: uspace/lib/libc/generic/io/console.c
===================================================================
--- uspace/lib/libc/generic/io/console.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/io/console.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -94,4 +94,17 @@
 }
 
+int console_get_pos(int phone, int *col, int *row)
+{
+	ipcarg_t col_v;
+	ipcarg_t row_v;
+	int rc;
+
+	rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
+
+	*col = (int) col_v;
+	*row = (int) row_v;
+	return rc;
+}
+
 void console_goto(int phone, int col, int row)
 {
Index: uspace/lib/libc/generic/io/io.c
===================================================================
--- uspace/lib/libc/generic/io/io.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/io/io.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -341,9 +341,14 @@
 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	size_t left = size * nmemb;
-	size_t done = 0;
-	
+	size_t left, done;
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
 	/* Make sure no data is pending write. */
 	_fflushbuf(stream);
+
+	left = size * nmemb;
+	done = 0;
 	
 	while ((left > 0) && (!stream->error) && (!stream->eof)) {
@@ -365,7 +370,13 @@
 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	size_t left = size * nmemb;
-	size_t done = 0;
-	
+	size_t left;
+	size_t done;
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
+	left = size * nmemb;
+	done = 0;
+
 	while ((left > 0) && (!stream->error)) {
 		ssize_t wr;
@@ -421,5 +432,8 @@
 	uint8_t b;
 	bool need_flush;
-	
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
 	/* If not buffered stream, write out directly. */
 	if (stream->btype == _IONBF) {
@@ -480,5 +494,5 @@
 	
 	if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
-		size_t wr = fwrite(buf, sz, 1, stream);
+		size_t wr = fwrite(buf, 1, sz, stream);
 		
 		if (wr < sz)
Index: uspace/lib/libc/generic/io/klog.c
===================================================================
--- uspace/lib/libc/generic/io/klog.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/io/klog.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -42,5 +42,10 @@
 size_t klog_write(const void *buf, size_t size)
 {
-	return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
+	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
+	
+	if (ret >= 0)
+		return (size_t) ret;
+	
+	return 0;
 }
 
Index: uspace/lib/libc/generic/string.c
===================================================================
--- uspace/lib/libc/generic/string.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/string.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -471,5 +471,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dst   Destination buffer.
+ * @param dest   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -505,5 +505,5 @@
  * have to be null-terminated.
  *
- * @param dst   Destination buffer.
+ * @param dest   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -537,5 +537,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dst   Destination buffer.
+ * @param dest   Destination buffer.
  * @param count Size of the destination buffer.
  * @param src   Source string.
@@ -549,36 +549,113 @@
 }
 
-/** Copy NULL-terminated wide string to string
- *
- * Copy source wide string @a src to destination buffer @a dst.
- * No more than @a size bytes are written. NULL-terminator is always
- * written after the last succesfully copied character (i.e. if the
- * destination buffer is has at least 1 byte, it will be always
- * NULL-terminated).
- *
- * @param src   Source wide string.
- * @param dst   Destination buffer.
- * @param count Size of the destination buffer.
- *
- */
-void wstr_nstr(char *dst, const wchar_t *src, size_t size)
-{
-	/* No space for the NULL-terminator in the buffer */
-	if (size == 0)
-		return;
-	
+/** Convert wide string to string.
+ *
+ * Convert wide string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed.
+ *
+ * @param dest	Destination buffer.
+ * @param size	Size of the destination buffer.
+ * @param src	Source wide string.
+ */
+void wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
 	wchar_t ch;
-	size_t src_idx = 0;
-	size_t dst_off = 0;
-	
+	size_t src_idx;
+	size_t dest_off;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+	
+	src_idx = 0;
+	dest_off = 0;
+
 	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dst, &dst_off, size) != EOK)
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-	
-	if (dst_off >= size)
-		dst[size - 1] = 0;
-	else
-		dst[dst_off] = 0;
+
+	dest[dest_off] = '\0';
+}
+
+/** Convert wide string to new string.
+ *
+ * Convert wide string @a src to string. Space for the new string is allocated
+ * on the heap.
+ *
+ * @param src	Source wide string.
+ * @return	New string.
+ */
+char *wstr_to_astr(const wchar_t *src)
+{
+	char dbuf[STR_BOUNDS(1)];
+	char *str;
+	wchar_t ch;
+
+	size_t src_idx;
+	size_t dest_off;
+	size_t dest_size;
+
+	/* Compute size of encoded string. */
+
+	src_idx = 0;
+	dest_size = 0;
+
+	while ((ch = src[src_idx++]) != 0) {
+		dest_off = 0;
+		if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK)
+			break;
+		dest_size += dest_off;
+	}
+
+	str = malloc(dest_size + 1);
+	if (str == NULL)
+		return NULL;
+
+	/* Encode string. */
+
+	src_idx = 0;
+	dest_off = 0;
+
+	while ((ch = src[src_idx++]) != 0) {
+		if (chr_encode(ch, str, &dest_off, dest_size) != EOK)
+			break;
+	}
+
+	str[dest_size] = '\0';
+	return str;
+}
+
+
+/** Convert string to wide string.
+ *
+ * Convert string @a src to wide string. The output is written to the
+ * buffer specified by @a dest and @a dlen. @a dlen must be non-zero
+ * and the wide string written will always be null-terminated.
+ *
+ * @param dest	Destination buffer.
+ * @param dlen	Length of destination buffer (number of wchars).
+ * @param src	Source string.
+ */
+void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+{
+	size_t offset;
+	size_t di;
+	wchar_t c;
+
+	assert(dlen > 0);
+
+	offset = 0;
+	di = 0;
+
+	do {
+		if (di >= dlen - 1)
+			break;
+
+		c = str_decode(src, &offset, STR_NO_LIMIT);
+		dest[di++] = c;
+	} while (c != '\0');
+
+	dest[dlen - 1] = '\0';
 }
 
@@ -819,4 +896,31 @@
 }
 
+char *str_dup(const char *src)
+{
+	size_t size = str_size(src);
+	void *dest = malloc(size + 1);
+	
+	if (dest == NULL)
+		return (char *) NULL;
+	
+	return (char *) memcpy(dest, src, size + 1);
+}
+
+char *str_ndup(const char *src, size_t max_size)
+{
+	size_t size = str_size(src);
+	if (size > max_size)
+		size = max_size;
+	
+	char *dest = (char *) malloc(size + 1);
+	
+	if (dest == NULL)
+		return (char *) NULL;
+	
+	memcpy(dest, src, size);
+	dest[size] = 0;
+	return dest;
+}
+
 
 /** Convert initial part of string to unsigned long according to given base.
@@ -843,15 +947,4 @@
 }
 
-char *str_dup(const char *src)
-{
-	size_t size = str_size(src);
-	void *dest = malloc(size + 1);
-
-	if (dest == NULL)
-		return (char *) NULL;
-
-	return (char *) memcpy(dest, src, size + 1);
-}
-
 char *strtok(char *s, const char *delim)
 {
Index: uspace/lib/libc/generic/time.c
===================================================================
--- uspace/lib/libc/generic/time.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/time.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -31,5 +31,5 @@
  */
 /** @file
- */ 
+ */
 
 #include <sys/time.h>
@@ -40,7 +40,7 @@
 #include <unistd.h>
 #include <atomic.h>
-#include <futex.h>
 #include <sysinfo.h>
 #include <ipc/services.h>
+#include <libc.h>
 
 #include <sysinfo.h>
@@ -189,27 +189,20 @@
 
 /** Wait unconditionally for specified number of microseconds */
-int usleep(unsigned long usec)
-{
-	atomic_t futex = FUTEX_INITIALIZER;
-
-	futex_initialize(&futex, 0);
-	futex_down_timeout(&futex, usec, 0);
+int usleep(useconds_t usec)
+{
+	(void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
 	return 0;
 }
 
 /** Wait unconditionally for specified number of seconds */
-unsigned int sleep(unsigned int seconds)
-{
-	atomic_t futex = FUTEX_INITIALIZER;
-
-	futex_initialize(&futex, 0);
-	
+unsigned int sleep(unsigned int sec)
+{
 	/* Sleep in 1000 second steps to support
 	   full argument range */
-	while (seconds > 0) {
-		unsigned int period = (seconds > 1000) ? 1000 : seconds;
+	while (sec > 0) {
+		unsigned int period = (sec > 1000) ? 1000 : sec;
 	
-		futex_down_timeout(&futex, period * 1000000, 0);
-		seconds -= period;
+		usleep(period * 1000000);
+		sec -= period;
 	}
 	return 0;
Index: uspace/lib/libc/generic/vfs/canonify.c
===================================================================
--- uspace/lib/libc/generic/vfs/canonify.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/vfs/canonify.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -142,5 +142,5 @@
 	t->start[-1] = '\0';
 }
-/** Eat the extra '/'..
+/** Eat the extra '/'.
  *
  * @param t		The current TK_SLASH token.
@@ -288,9 +288,15 @@
  *
  * A file system path is canonical, if the following holds:
- * 1) the path is absolute (i.e. a/b/c is not canonical)
- * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical)
- * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical)
- * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical)
- * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical) 
+ *
+ * 1) the path is absolute
+ *    (i.e. a/b/c is not canonical)
+ * 2) there is no trailing slash in the path if it has components
+ *    (i.e. /a/b/c/ is not canonical)
+ * 3) there is no extra slash in the path
+ *    (i.e. /a//b/c is not canonical)
+ * 4) there is no '.' component in the path
+ *    (i.e. /a/./b/c is not canonical)
+ * 5) there is no '..' component in the path
+ *    (i.e. /a/b/../c is not canonical)
  *
  * This function makes a potentially non-canonical file system path canonical.
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -117,5 +117,5 @@
 }
 
-int mount(const char *fs_name, const char *mp, const char *dev,
+int mount(const char *fs_name, const char *mp, const char *fqdn,
     const char *opts, unsigned int flags)
 {
@@ -126,5 +126,5 @@
 	dev_handle_t dev_handle;
 	
-	res = devmap_device_get_handle(dev, &dev_handle, flags);
+	res = devmap_device_get_handle(fqdn, &dev_handle, flags);
 	if (res != EOK)
 		return res;
@@ -703,8 +703,8 @@
 	rc = fstat(fildes, &stat);
 
-	if (!stat.devfs_stat.device)
+	if (!stat.device)
 		return -1;
 	
-	return devmap_device_connect(stat.devfs_stat.device, 0);
+	return devmap_device_connect(stat.device, 0);
 }
 
Index: uspace/lib/libc/include/async.h
===================================================================
--- uspace/lib/libc/include/async.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/async.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -284,4 +284,7 @@
 extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
 
+extern int async_data_blob_receive(char **, const size_t, size_t *);
+extern int async_data_string_receive(char **, const size_t);
+
 #endif
 
Index: uspace/lib/libc/include/atomic.h
===================================================================
--- uspace/lib/libc/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/atomic.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -36,19 +36,5 @@
 #define LIBC_ATOMIC_H_
 
-typedef struct atomic {
-	volatile long count;
-} atomic_t;
-
 #include <libarch/atomic.h>
-
-static inline void atomic_set(atomic_t *val, long i)
-{
-        val->count = i;
-}
-
-static inline long atomic_get(atomic_t *val)
-{
-        return val->count;
-}
 
 #endif
Index: uspace/lib/libc/include/atomicdflt.h
===================================================================
--- uspace/lib/libc/include/atomicdflt.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/include/atomicdflt.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ATOMICDFLT_H_
+#define LIBC_ATOMICDFLT_H_
+
+#ifndef LIBC_ARCH_ATOMIC_H_
+#error This file cannot be included directly, include atomic.h instead.
+#endif
+
+#include <bool.h>
+
+typedef struct atomic {
+	volatile long count;
+} atomic_t;
+
+static inline void atomic_set(atomic_t *val, long i)
+{
+        val->count = i;
+}
+
+static inline long atomic_get(atomic_t *val)
+{
+        return val->count;
+}
+
+#ifndef CAS 
+static inline bool cas(atomic_t *val, long ov, long nv)
+{
+	return __sync_bool_compare_and_swap(&val->count, ov, nv);
+}
+#endif
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/clipboard.h
===================================================================
--- uspace/lib/libc/include/clipboard.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/include/clipboard.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_CLIPBOARD_H_
+#define LIBC_CLIPBOARD_H_
+
+extern int clipboard_put_str(const char *);
+extern int clipboard_get_str(char **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/devmap.h
===================================================================
--- uspace/lib/libc/include/devmap.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/devmap.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -38,4 +38,5 @@
 #include <ipc/devmap.h>
 #include <async.h>
+#include <bool.h>
 
 extern int devmap_get_phone(devmap_interface_t, unsigned int);
@@ -46,4 +47,7 @@
 
 extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
+extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int);
+extern devmap_handle_type_t devmap_handle_probe(dev_handle_t);
+
 extern int devmap_device_connect(dev_handle_t, unsigned int);
 
@@ -51,6 +55,9 @@
 extern void devmap_null_destroy(int);
 
-extern ipcarg_t devmap_device_get_count(void);
-extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
+extern size_t devmap_count_namespaces(void);
+extern size_t devmap_count_devices(dev_handle_t);
+
+extern size_t devmap_get_namespaces(dev_desc_t **);
+extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **);
 
 #endif
Index: uspace/lib/libc/include/fibril_sync.h
===================================================================
--- uspace/lib/libc/include/fibril_sync.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ 	(revision )
@@ -1,107 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_FIBRIL_SYNC_H_
-#define LIBC_FIBRIL_SYNC_H_
-
-#include <async.h>
-#include <fibril.h>
-#include <adt/list.h>
-#include <libarch/tls.h>
-#include <sys/time.h>
-
-typedef struct {
-	int counter;
-	link_t waiters;
-} fibril_mutex_t;
-
-#define FIBRIL_MUTEX_INITIALIZE(name) \
-	fibril_mutex_t name = {	\
-		.counter = 1, \
-		.waiters = { \
-			.prev = &name.waiters, \
-			.next = &name.waiters, \
-		} \
-	}
-
-typedef struct {
-	unsigned writers;
-	unsigned readers;
-	link_t waiters;
-} fibril_rwlock_t;
-
-#define FIBRIL_RWLOCK_INITIALIZE(name) \
-	fibril_rwlock_t name = { \
-		.readers = 0, \
-		.writers = 0, \
-		.waiters = { \
-			.prev = &name.waiters, \
-			.next = &name.waiters, \
-		} \
-	}
-
-typedef struct {
-	link_t waiters;
-} fibril_condvar_t;
-
-#define FIBRIL_CONDVAR_INITIALIZE(name) \
-	fibril_condvar_t name = { \
-		.waiters = { \
-			.next = &name.waiters, \
-			.prev = &name.waiters, \
-		} \
-	}
-
-extern void fibril_mutex_initialize(fibril_mutex_t *);
-extern void fibril_mutex_lock(fibril_mutex_t *);
-extern bool fibril_mutex_trylock(fibril_mutex_t *);
-extern void fibril_mutex_unlock(fibril_mutex_t *);
-
-extern void fibril_rwlock_initialize(fibril_rwlock_t *);
-extern void fibril_rwlock_read_lock(fibril_rwlock_t *);
-extern void fibril_rwlock_write_lock(fibril_rwlock_t *);
-extern void fibril_rwlock_read_unlock(fibril_rwlock_t *);
-extern void fibril_rwlock_write_unlock(fibril_rwlock_t *);
-
-extern void fibril_condvar_initialize(fibril_condvar_t *);
-extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *,
-    suseconds_t);
-extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
-extern void fibril_condvar_signal(fibril_condvar_t *);
-extern void fibril_condvar_broadcast(fibril_condvar_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/libc/include/fibril_synch.h
===================================================================
--- uspace/lib/libc/include/fibril_synch.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/include/fibril_synch.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_FIBRIL_SYNCH_H_
+#define LIBC_FIBRIL_SYNCH_H_
+
+#include <async.h>
+#include <fibril.h>
+#include <adt/list.h>
+#include <libarch/tls.h>
+#include <sys/time.h>
+
+typedef struct {
+	int counter;
+	link_t waiters;
+} fibril_mutex_t;
+
+#define FIBRIL_MUTEX_INITIALIZE(name) \
+	fibril_mutex_t name = {	\
+		.counter = 1, \
+		.waiters = { \
+			.prev = &name.waiters, \
+			.next = &name.waiters, \
+		} \
+	}
+
+typedef struct {
+	unsigned writers;
+	unsigned readers;
+	link_t waiters;
+} fibril_rwlock_t;
+
+#define FIBRIL_RWLOCK_INITIALIZE(name) \
+	fibril_rwlock_t name = { \
+		.readers = 0, \
+		.writers = 0, \
+		.waiters = { \
+			.prev = &name.waiters, \
+			.next = &name.waiters, \
+		} \
+	}
+
+typedef struct {
+	link_t waiters;
+} fibril_condvar_t;
+
+#define FIBRIL_CONDVAR_INITIALIZE(name) \
+	fibril_condvar_t name = { \
+		.waiters = { \
+			.next = &name.waiters, \
+			.prev = &name.waiters, \
+		} \
+	}
+
+extern void fibril_mutex_initialize(fibril_mutex_t *);
+extern void fibril_mutex_lock(fibril_mutex_t *);
+extern bool fibril_mutex_trylock(fibril_mutex_t *);
+extern void fibril_mutex_unlock(fibril_mutex_t *);
+
+extern void fibril_rwlock_initialize(fibril_rwlock_t *);
+extern void fibril_rwlock_read_lock(fibril_rwlock_t *);
+extern void fibril_rwlock_write_lock(fibril_rwlock_t *);
+extern void fibril_rwlock_read_unlock(fibril_rwlock_t *);
+extern void fibril_rwlock_write_unlock(fibril_rwlock_t *);
+
+extern void fibril_condvar_initialize(fibril_condvar_t *);
+extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *,
+    suseconds_t);
+extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
+extern void fibril_condvar_signal(fibril_condvar_t *);
+extern void fibril_condvar_broadcast(fibril_condvar_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/futex.h
===================================================================
--- uspace/lib/libc/include/futex.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/futex.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -46,5 +46,4 @@
 extern int futex_down(futex_t *futex);
 extern int futex_trydown(futex_t *futex);
-extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);
 extern int futex_up(futex_t *futex);
 
Index: uspace/lib/libc/include/io/console.h
===================================================================
--- uspace/lib/libc/include/io/console.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/io/console.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -69,4 +69,5 @@
 
 extern int console_get_size(int phone, int *cols, int *rows);
+extern int console_get_pos(int phone, int *col, int *row);
 extern void console_goto(int phone, int col, int row);
 
Index: uspace/lib/libc/include/ipc/clipboard.h
===================================================================
--- uspace/lib/libc/include/ipc/clipboard.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
+++ uspace/lib/libc/include/ipc/clipboard.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_CLIPBOARD_H_
+#define LIBC_IPC_CLIPBOARD_H_
+
+#include <ipc/ipc.h>
+
+typedef enum {
+	CLIPBOARD_PUT_DATA = IPC_FIRST_USER_METHOD,
+	CLIPBOARD_GET_DATA,
+	CLIPBOARD_CONTENT
+} clipboard_request_t;
+
+typedef enum {
+	CLIPBOARD_TAG_NONE,
+	CLIPBOARD_TAG_BLOB
+} clipboard_tag_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/ipc/console.h
===================================================================
--- uspace/lib/libc/include/ipc/console.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/ipc/console.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -43,4 +43,5 @@
 	CONSOLE_GET_COLOR_CAP,
 	CONSOLE_GET_EVENT,
+	CONSOLE_GET_POS,
 	CONSOLE_GOTO,
 	CONSOLE_CLEAR,
Index: uspace/lib/libc/include/ipc/devmap.h
===================================================================
--- uspace/lib/libc/include/ipc/devmap.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/ipc/devmap.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -43,14 +43,23 @@
 
 typedef enum {
+	DEV_HANDLE_NONE,
+	DEV_HANDLE_NAMESPACE,
+	DEV_HANDLE_DEVICE
+} devmap_handle_type_t;
+
+typedef enum {
 	DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
 	DEVMAP_DRIVER_UNREGISTER,
 	DEVMAP_DEVICE_REGISTER,
 	DEVMAP_DEVICE_UNREGISTER,
-	DEVMAP_DEVICE_GET_NAME,
 	DEVMAP_DEVICE_GET_HANDLE,
-	DEVMAP_DEVICE_NULL_CREATE,
-	DEVMAP_DEVICE_NULL_DESTROY,
-	DEVMAP_DEVICE_GET_COUNT,
-	DEVMAP_DEVICE_GET_DEVICES
+	DEVMAP_NAMESPACE_GET_HANDLE,
+	DEVMAP_HANDLE_PROBE,
+	DEVMAP_NULL_CREATE,
+	DEVMAP_NULL_DESTROY,
+	DEVMAP_GET_NAMESPACE_COUNT,
+	DEVMAP_GET_DEVICE_COUNT,
+	DEVMAP_GET_NAMESPACES,
+	DEVMAP_GET_DEVICES
 } devmap_request_t;
 
Index: uspace/lib/libc/include/ipc/services.h
===================================================================
--- uspace/lib/libc/include/ipc/services.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/ipc/services.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -41,5 +41,4 @@
 	SERVICE_LOAD = 1,
 	SERVICE_PCI,
-	SERVICE_KEYBOARD,
 	SERVICE_VIDEO,
 	SERVICE_CONSOLE,
@@ -47,5 +46,6 @@
 	SERVICE_DEVMAP,
 	SERVICE_FHC,
-	SERVICE_OBIO
+	SERVICE_OBIO,
+	SERVICE_CLIPBOARD
 } services_t;
 
Index: uspace/lib/libc/include/string.h
===================================================================
--- uspace/lib/libc/include/string.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/string.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -73,5 +73,7 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
-extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
+extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
+extern char *wstr_to_astr(const wchar_t *src);
+extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
 
 extern char *str_chr(const char *str, wchar_t ch);
@@ -82,4 +84,5 @@
 
 extern char *str_dup(const char *);
+extern char *str_ndup(const char *, size_t max_size);
 
 /*
Index: uspace/lib/libc/include/sys/stat.h
===================================================================
--- uspace/lib/libc/include/sys/stat.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/sys/stat.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -42,15 +42,12 @@
 
 struct stat {
-	fs_handle_t	fs_handle;
-	dev_handle_t	dev_handle;
-	fs_index_t	index;
-	unsigned	lnkcnt;
-	bool		is_file;
-	off_t		size;
-	union {
-		struct {
-			dev_handle_t	device;
-		} devfs_stat;
-	};
+	fs_handle_t fs_handle;
+	dev_handle_t dev_handle;
+	fs_index_t index;
+	unsigned int lnkcnt;
+	bool is_file;
+	bool is_directory;
+	off_t size;
+	dev_handle_t device;
 };
 
Index: uspace/lib/libc/include/unistd.h
===================================================================
--- uspace/lib/libc/include/unistd.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libc/include/unistd.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -51,4 +51,6 @@
 #endif
 
+typedef uint32_t useconds_t;
+
 extern int dup2(int oldfd, int newfd);
 
@@ -68,6 +70,6 @@
 
 extern void _exit(int status) __attribute__ ((noreturn));
-extern int usleep(unsigned long usec);
-extern unsigned int sleep(unsigned int seconds);
+extern int usleep(useconds_t uses);
+extern unsigned int sleep(unsigned int se);
 
 #endif
Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libfs/libfs.c	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jakub Jermar 
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -27,13 +27,13 @@
  */
 
-/** @addtogroup libfs 
+/** @addtogroup libfs
  * @{
- */ 
+ */
 /**
  * @file
- * Glue code which is commonod to all FS implementations. 
- */
-
-#include "libfs.h" 
+ * Glue code which is common to all FS implementations.
+ */
+
+#include "libfs.h"
 #include "../../srv/vfs/vfs.h"
 #include <errno.h>
@@ -67,13 +67,14 @@
  * code.
  *
- * @param vfs_phone	Open phone for communication with VFS.
- * @param reg		File system registration structure. It will be
- * 			initialized by this function.
- * @param info		VFS info structure supplied by the file system
- *			implementation.
- * @param conn		Connection fibril for handling all calls originating in
- *			VFS.
- *
- * @return		EOK on success or a non-zero error code on errror.
+ * @param vfs_phone Open phone for communication with VFS.
+ * @param reg       File system registration structure. It will be
+ *                  initialized by this function.
+ * @param info      VFS info structure supplied by the file system
+ *                  implementation.
+ * @param conn      Connection fibril for handling all calls originating in
+ *                  VFS.
+ *
+ * @return EOK on success or a non-zero error code on errror.
+ *
  */
 int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
@@ -87,5 +88,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
-
+	
 	/*
 	 * Send our VFS info structure to VFS.
@@ -96,10 +97,10 @@
 		return rc;
 	}
-
+	
 	/*
 	 * Ask VFS for callback connection.
 	 */
 	ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
-
+	
 	/*
 	 * Allocate piece of address space for PLB.
@@ -110,5 +111,5 @@
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Request sharing the Path Lookup Buffer with VFS.
@@ -136,5 +137,5 @@
 	 */
 	async_set_client_connection(conn);
-
+	
 	return IPC_GET_RETVAL(answer);
 }
@@ -154,18 +155,20 @@
 	int res;
 	ipcarg_t rc;
-
+	
 	ipc_call_t call;
 	ipc_callid_t callid;
-
-	/* accept the phone */
+	
+	/* Accept the phone */
 	callid = async_get_call(&call);
 	int mountee_phone = (int)IPC_GET_ARG1(call);
 	if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
-	    mountee_phone < 0) {
+	    (mountee_phone < 0)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
 		return;
 	}
-	ipc_answer_0(callid, EOK);	/* acknowledge the mountee_phone */
+	
+	/* Acknowledge the mountee_phone */
+	ipc_answer_0(callid, EOK);
 	
 	res = async_data_write_receive(&callid, NULL);
@@ -176,8 +179,8 @@
 		return;
 	}
-
+	
 	fs_node_t *fn;
 	res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
-	if (res != EOK || !fn) {
+	if ((res != EOK) || (!fn)) {
 		ipc_hangup(mountee_phone);
 		ipc_answer_0(callid, combine_rc(res, ENOENT));
@@ -185,5 +188,5 @@
 		return;
 	}
-
+	
 	if (fn->mp_data.mp_active) {
 		ipc_hangup(mountee_phone);
@@ -193,5 +196,5 @@
 		return;
 	}
-
+	
 	rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
 	if (rc != EOK) {
@@ -215,4 +218,5 @@
 		fn->mp_data.phone = mountee_phone;
 	}
+	
 	/*
 	 * Do not release the FS node so that it stays in memory.
@@ -238,24 +242,24 @@
     ipc_call_t *request)
 {
-	unsigned first = IPC_GET_ARG1(*request);
-	unsigned last = IPC_GET_ARG2(*request);
-	unsigned next = first;
+	unsigned int first = IPC_GET_ARG1(*request);
+	unsigned int last = IPC_GET_ARG2(*request);
+	unsigned int next = first;
 	dev_handle_t dev_handle = IPC_GET_ARG3(*request);
 	int lflag = IPC_GET_ARG4(*request);
-	fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
+	fs_index_t index = IPC_GET_ARG5(*request);
 	char component[NAME_MAX + 1];
 	int len;
 	int rc;
-
+	
 	if (last < next)
 		last += PLB_SIZE;
-
+	
 	fs_node_t *par = NULL;
 	fs_node_t *cur = NULL;
 	fs_node_t *tmp = NULL;
-
+	
 	rc = ops->root_get(&cur, dev_handle);
 	on_error(rc, goto out_with_answer);
-
+	
 	if (cur->mp_data.mp_active) {
 		ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
@@ -265,42 +269,45 @@
 		return;
 	}
-
+	
+	/* Eat slash */
 	if (ops->plb_get_char(next) == '/')
-		next++;		/* eat slash */
+		next++;
 	
 	while (next <= last) {
 		bool has_children;
-
+		
 		rc = ops->has_children(&has_children, cur);
 		on_error(rc, goto out_with_answer);
 		if (!has_children)
 			break;
-
-		/* collect the component */
+		
+		/* Collect the component */
 		len = 0;
-		while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
+		while ((next <= last) && (ops->plb_get_char(next) != '/')) {
 			if (len + 1 == NAME_MAX) {
-				/* component length overflow */
+				/* Component length overflow */
 				ipc_answer_0(rid, ENAMETOOLONG);
 				goto out;
 			}
 			component[len++] = ops->plb_get_char(next);
-			next++;	/* process next character */
+			/* Process next character */
+			next++;
 		}
-
+		
 		assert(len);
 		component[len] = '\0';
-		next++;		/* eat slash */
-
-		/* match the component */
+		/* Eat slash */
+		next++;
+		
+		/* Match the component */
 		rc = ops->match(&tmp, cur, component);
 		on_error(rc, goto out_with_answer);
-
-		if (tmp && tmp->mp_data.mp_active) {
+		
+		if ((tmp) && (tmp->mp_data.mp_active)) {
 			if (next > last)
 				next = last = first;
 			else
 				next--;
-				
+			
 			ipc_forward_slow(rid, tmp->mp_data.phone,
 			    VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
@@ -312,19 +319,21 @@
 			return;
 		}
-
-		/* handle miss: match amongst siblings */
+		
+		/* Handle miss: match amongst siblings */
 		if (!tmp) {
 			if (next <= last) {
-				/* there are unprocessed components */
+				/* There are unprocessed components */
 				ipc_answer_0(rid, ENOENT);
 				goto out;
 			}
-			/* miss in the last component */
-			if (lflag & (L_CREATE | L_LINK)) { 
-				/* request to create a new link */
+			
+			/* Miss in the last component */
+			if (lflag & (L_CREATE | L_LINK)) {
+				/* Request to create a new link */
 				if (!ops->is_directory(cur)) {
 					ipc_answer_0(rid, ENOTDIR);
 					goto out;
 				}
+				
 				fs_node_t *fn;
 				if (lflag & L_CREATE)
@@ -335,4 +344,5 @@
 					    index);
 				on_error(rc, goto out_with_answer);
+				
 				if (fn) {
 					rc = ops->link(cur, fn, component);
@@ -349,33 +359,34 @@
 						(void) ops->node_put(fn);
 					}
-				} else {
+				} else
 					ipc_answer_0(rid, ENOSPC);
-				}
+				
 				goto out;
-			} 
+			}
+			
 			ipc_answer_0(rid, ENOENT);
 			goto out;
 		}
-
+		
 		if (par) {
 			rc = ops->node_put(par);
 			on_error(rc, goto out_with_answer);
 		}
-
-		/* descend one level */
+		
+		/* Descend one level */
 		par = cur;
 		cur = tmp;
 		tmp = NULL;
 	}
-
-	/* handle miss: excessive components */
+	
+	/* Handle miss: excessive components */
 	if (next <= last) {
 		bool has_children;
-
 		rc = ops->has_children(&has_children, cur);
 		on_error(rc, goto out_with_answer);
+		
 		if (has_children)
 			goto skip_miss;
-
+		
 		if (lflag & (L_CREATE | L_LINK)) {
 			if (!ops->is_directory(cur)) {
@@ -383,24 +394,28 @@
 				goto out;
 			}
-
-			/* collect next component */
+			
+			/* Collect next component */
 			len = 0;
 			while (next <= last) {
 				if (ops->plb_get_char(next) == '/') {
-					/* more than one component */
+					/* More than one component */
 					ipc_answer_0(rid, ENOENT);
 					goto out;
 				}
+				
 				if (len + 1 == NAME_MAX) {
-					/* component length overflow */
+					/* Component length overflow */
 					ipc_answer_0(rid, ENAMETOOLONG);
 					goto out;
 				}
+				
 				component[len++] = ops->plb_get_char(next);
-				next++;	/* process next character */
+				/* Process next character */
+				next++;
 			}
+			
 			assert(len);
 			component[len] = '\0';
-				
+			
 			fs_node_t *fn;
 			if (lflag & L_CREATE)
@@ -409,4 +424,5 @@
 				rc = ops->node_get(&fn, dev_handle, index);
 			on_error(rc, goto out_with_answer);
+			
 			if (fn) {
 				rc = ops->link(cur, fn, component);
@@ -423,22 +439,25 @@
 					(void) ops->node_put(fn);
 				}
-			} else {
+			} else
 				ipc_answer_0(rid, ENOSPC);
-			}
+			
 			goto out;
 		}
+		
 		ipc_answer_0(rid, ENOENT);
 		goto out;
 	}
+	
 skip_miss:
-
-	/* handle hit */
+	
+	/* Handle hit */
 	if (lflag & L_UNLINK) {
-		unsigned old_lnkcnt = ops->lnkcnt_get(cur);
+		unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
 		rc = ops->unlink(par, cur, component);
-		ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
+		ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,
 		    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
 		goto out;
 	}
+	
 	if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
 	    (lflag & L_LINK)) {
@@ -446,27 +465,35 @@
 		goto out;
 	}
+	
 	if ((lflag & L_FILE) && (ops->is_directory(cur))) {
 		ipc_answer_0(rid, EISDIR);
 		goto out;
 	}
+	
 	if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
 		ipc_answer_0(rid, ENOTDIR);
 		goto out;
 	}
-
+	
 out_with_answer:
+	
 	if (rc == EOK) {
-		ipc_answer_5(rid, EOK, fs_handle, dev_handle,
+		if (lflag & L_OPEN)
+			rc = ops->node_open(cur);
+		
+		ipc_answer_5(rid, rc, fs_handle, dev_handle,
 		    ops->index_get(cur), ops->size_get(cur),
 		    ops->lnkcnt_get(cur));
-	} else {
+	} else
 		ipc_answer_0(rid, rc);
-	}
-
+	
 out:
+	
 	if (par)
 		(void) ops->node_put(par);
+	
 	if (cur)
 		(void) ops->node_put(cur);
+	
 	if (tmp)
 		(void) ops->node_put(tmp);
@@ -478,19 +505,19 @@
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	
 	fs_node_t *fn;
-	int rc;
-
-	rc = ops->node_get(&fn, dev_handle, index);
+	int rc = ops->node_get(&fn, dev_handle, index);
 	on_error(rc, answer_and_return(rid, rc));
-
+	
 	ipc_callid_t callid;
 	size_t size;
-	if (!async_data_read_receive(&callid, &size) ||
-	    size != sizeof(struct stat)) {
+	if ((!async_data_read_receive(&callid, &size)) ||
+	    (size != sizeof(struct stat))) {
+		ops->node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
 		return;
 	}
-
+	
 	struct stat stat;
 	memset(&stat, 0, sizeof(struct stat));
@@ -499,8 +526,12 @@
 	stat.dev_handle = dev_handle;
 	stat.index = index;
-	stat.lnkcnt = ops->lnkcnt_get(fn); 
+	stat.lnkcnt = ops->lnkcnt_get(fn);
 	stat.is_file = ops->is_file(fn);
+	stat.is_directory = ops->is_directory(fn);
 	stat.size = ops->size_get(fn);
-
+	stat.device = ops->device_get(fn);
+	
+	ops->node_put(fn);
+	
 	async_data_read_finalize(callid, &stat, sizeof(struct stat));
 	ipc_answer_0(rid, EOK);
@@ -509,8 +540,8 @@
 /** Open VFS triplet.
  *
- * @param ops       libfs operations structure with function pointers to
- *                  file system implementation
- * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
- * @param request   VFS_OUT_OPEN_NODE request data itself.
+ * @param ops     libfs operations structure with function pointers to
+ *                file system implementation
+ * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
+ * @param request VFS_OUT_OPEN_NODE request data itself.
  *
  */
@@ -531,5 +562,6 @@
 	}
 	
-	ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
+	rc = ops->node_open(fn);
+	ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn),
 	    (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
 	
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ uspace/lib/libfs/libfs.h	(revision eacb957f6c30d6c807f9a5ca0a3e535e59262c52)
@@ -64,4 +64,5 @@
 	int (* match)(fs_node_t **, fs_node_t *, const char *);
 	int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
+	int (* node_open)(fs_node_t *);
 	int (* node_put)(fs_node_t *);
 	int (* create)(fs_node_t **, dev_handle_t, int);
@@ -76,8 +77,9 @@
 	fs_index_t (* index_get)(fs_node_t *);
 	size_t (* size_get)(fs_node_t *);
-	unsigned (* lnkcnt_get)(fs_node_t *);
+	unsigned int (* lnkcnt_get)(fs_node_t *);
 	char (* plb_get_char)(unsigned pos);
 	bool (* is_directory)(fs_node_t *);
 	bool (* is_file)(fs_node_t *);
+	dev_handle_t (* device_get)(fs_node_t *);
 } libfs_ops_t;
 
