Index: uspace/lib/libc/generic/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs.c	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/lib/libc/generic/vfs.c	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -95,5 +95,5 @@
 
 
-int open(const char *name, int oflag, ...)
+int open(const char *path, int oflag, ...)
 {
 	int res;
@@ -113,5 +113,5 @@
 	}
 	req = async_send_2(vfs_phone, VFS_OPEN, oflag, 0, &answer);
-	rc = ipc_data_write_start(vfs_phone, name, strlen(name));
+	rc = ipc_data_write_start(vfs_phone, path, strlen(path));
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
@@ -215,4 +215,25 @@
 }
 
+int ftruncate(int fildes, off_t length)
+{
+	int res;
+	ipcarg_t rc;
+	
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	if (vfs_phone < 0) {
+		res = vfs_connect();
+		if (res < 0) {
+			async_serialize_end();
+			futex_up(&vfs_phone_futex);
+			return res;
+		}
+	}
+	rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length);
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	return (int) rc;
+}
+
 /** @}
  */
Index: uspace/lib/libc/include/unistd.h
===================================================================
--- uspace/lib/libc/include/unistd.h	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/lib/libc/include/unistd.h	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -46,7 +46,8 @@
 #define SEEK_END	2
 
-extern ssize_t write(int fd, const void * buf, size_t count);
-extern ssize_t read(int fd, void * buf, size_t count);
+extern ssize_t write(int, const void *, size_t);
+extern ssize_t read(int, void *, size_t);
 extern off_t lseek(int, off_t, int);
+extern int ftruncate(int, off_t);
 
 extern void _exit(int status);
Index: uspace/srv/fs/tmpfs/tmpfs.h
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.h	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/srv/fs/tmpfs/tmpfs.h	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2007 Jakub Jermar
+ * Copyright (c) 2008 Jakub Jermar
  * All rights reserved.
  *
@@ -64,4 +64,5 @@
 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
+extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -369,5 +369,5 @@
 		return;
 	}
-	/* Clear any newly allocated memory in order to emulate gaps.  */
+	/* Clear any newly allocated memory in order to emulate gaps. */
 	memset(newdata + dentry->size, 0, delta);
 	dentry->size += delta;
@@ -377,4 +377,41 @@
 }
 
+void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
+{
+	int dev_handle = IPC_GET_ARG1(*request);
+	unsigned long index = IPC_GET_ARG2(*request);
+	size_t size = IPC_GET_ARG3(*request);
+
+	/*
+	 * Lookup the respective dentry.
+	 */
+	link_t *hlp;
+	hlp = hash_table_find(&dentries, &index);
+	if (!hlp) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+	tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
+	    dh_link);
+
+	if (size == dentry->size) {
+		ipc_answer_0(rid, EOK);
+		return;
+	}
+
+	void *newdata = realloc(dentry->data, size);
+	if (!newdata) {
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+	if (size > dentry->size) {
+		size_t delta = size - dentry->size;
+		memset(newdata + dentry->size, 0, delta);
+	}
+	dentry->size = size;
+	dentry->data = newdata;
+	ipc_answer_0(rid, EOK);
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/srv/vfs/vfs.c	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2007 Jakub Jermar
+ * Copyright (c) 2008 Jakub Jermar
  * All rights reserved.
  *
@@ -104,4 +104,6 @@
 			break;
 		case VFS_TRUNCATE:
+			vfs_truncate(callid, &call);
+			break;
 		case VFS_UNMOUNT:
 		case VFS_CLOSE:
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/srv/vfs/vfs.h	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -230,4 +230,5 @@
 extern void vfs_write(ipc_callid_t, ipc_call_t *);
 extern void vfs_seek(ipc_callid_t, ipc_call_t *);
+extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision eb27ce5a8fc10aea5ca8d1e35996165a9eb406d8)
+++ uspace/srv/vfs/vfs_ops.c	(revision 0ee4322fd8ff41e424fb8a9d65e8b6d189d22883)
@@ -690,4 +690,31 @@
 }
 
+void vfs_truncate(ipc_callid_t rid, ipc_call_t *request)
+{
+	int fd = IPC_GET_ARG1(*request);
+	size_t size = IPC_GET_ARG2(*request);
+	ipcarg_t rc;
+
+	vfs_file_t *file = vfs_file_get(fd);
+	if (!file) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+	futex_down(&file->lock);
+
+	rwlock_write_lock(&file->node->contents_rwlock);
+	int fs_phone = vfs_grab_phone(file->node->fs_handle);
+	rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)file->node->dev_handle,
+	    (ipcarg_t)file->node->index, (ipcarg_t)size);
+	vfs_release_phone(fs_phone);
+	if (rc == EOK)
+		file->node->size = size;
+	rwlock_write_unlock(&file->node->contents_rwlock);
+
+	futex_up(&file->lock);
+
+	return rc;	
+}
+
 atomic_t fs_head_futex = FUTEX_INITIALIZER;
 link_t fs_head;
