Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision 4198f9c3ae7988eea2c8a649c01af1be31ded05d)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision 852b80130e0f28124d72af653ed0aef959db3053)
@@ -39,6 +39,6 @@
 #include <dirent.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <sys/stat.h>
-#include <stdio.h>
 #include <sys/types.h>
 #include <ipc/ipc.h>
@@ -315,46 +315,4 @@
 }
 
-int fd_phone(int fildes)
-{
-	futex_down(&vfs_phone_futex);
-	async_serialize_start();
-	vfs_connect();
-	
-	ipcarg_t device;
-	ipcarg_t rc = async_req_1_1(vfs_phone, VFS_IN_DEVICE, fildes, &device);
-	
-	async_serialize_end();
-	futex_up(&vfs_phone_futex);
-	
-	if (rc != EOK)
-		return -1;
-	
-	return devmap_device_connect((dev_handle_t) device, 0);
-}
-
-int fd_node(int fildes, fdi_node_t *node)
-{
-	futex_down(&vfs_phone_futex);
-	async_serialize_start();
-	vfs_connect();
-	
-	ipcarg_t fs_handle;
-	ipcarg_t dev_handle;
-	ipcarg_t index;
-	ipcarg_t rc = async_req_1_3(vfs_phone, VFS_IN_NODE, fildes, &fs_handle,
-	    &dev_handle, &index);
-	
-	async_serialize_end();
-	futex_up(&vfs_phone_futex);
-	
-	if (rc == EOK) {
-		node->fs_handle = (fs_handle_t) fs_handle;
-		node->dev_handle = (dev_handle_t) dev_handle;
-		node->index = (fs_index_t) index;
-	}
-	
-	return rc;
-}
-
 int fsync(int fildes)
 {
@@ -404,4 +362,29 @@
 	futex_up(&vfs_phone_futex);
 	return (int) rc;
+}
+
+int fstat(int fildes, struct stat *stat)
+{
+	ipcarg_t rc;
+	ipc_call_t answer;
+	aid_t req;
+
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
+	rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		return (ssize_t) rc;
+	}
+	async_wait_for(req, &rc);
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+
+	return rc;
 }
 
@@ -599,4 +582,33 @@
 }
 
+int fd_phone(int fildes)
+{
+	struct stat stat;
+	int rc;
+
+	rc = fstat(fildes, &stat);
+
+	if (!stat.devfs_stat.device)
+		return -1;
+	
+	return devmap_device_connect(stat.devfs_stat.device, 0);
+}
+
+int fd_node(int fildes, fdi_node_t *node)
+{
+	struct stat stat;
+	int rc;
+
+	rc = fstat(fildes, &stat);
+	
+	if (rc == EOK) {
+		node->fs_handle = stat.fs_handle;
+		node->dev_handle = stat.dev_handle;
+		node->index = stat.index;
+	}
+	
+	return rc;
+}
+
 /** @}
  */
Index: uspace/lib/libc/include/ipc/vfs.h
===================================================================
--- uspace/lib/libc/include/ipc/vfs.h	(revision 4198f9c3ae7988eea2c8a649c01af1be31ded05d)
+++ uspace/lib/libc/include/ipc/vfs.h	(revision 852b80130e0f28124d72af653ed0aef959db3053)
@@ -64,4 +64,5 @@
 	VFS_IN_SEEK,
 	VFS_IN_TRUNCATE,
+	VFS_IN_FSTAT,
 	VFS_IN_CLOSE,
 	VFS_IN_MOUNT,
@@ -73,4 +74,5 @@
 	VFS_IN_UNLINK,
 	VFS_IN_RENAME,
+	VFS_IN_STAT,
 	VFS_IN_NODE
 } vfs_in_request_t;
@@ -87,4 +89,5 @@
 	VFS_OUT_DEVICE,
 	VFS_OUT_SYNC,
+	VFS_OUT_STAT,
 	VFS_OUT_LOOKUP,
 	VFS_OUT_DESTROY,
Index: uspace/lib/libc/include/sys/stat.h
===================================================================
--- uspace/lib/libc/include/sys/stat.h	(revision 4198f9c3ae7988eea2c8a649c01af1be31ded05d)
+++ uspace/lib/libc/include/sys/stat.h	(revision 852b80130e0f28124d72af653ed0aef959db3053)
@@ -37,5 +37,23 @@
 
 #include <sys/types.h>
+#include <bool.h>
+#include <ipc/vfs.h>
+#include <ipc/devmap.h>
 
+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;
+	};
+};
+
+extern int fstat(int, struct stat *);
 extern int mkdir(const char *, mode_t);
 
