Index: uspace/lib/posix/assert.h
===================================================================
--- uspace/lib/posix/assert.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/assert.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -40,10 +40,5 @@
 
 #ifndef NDEBUG
-	#define assert(expr) \
-		do { \
-			if (!(expr)) { \
-				assert_abort(#expr, __FILE__, __LINE__); \
-			} \
-		} while (0)
+	#define assert(expr) ((expr) ? (void) 0 : assert_abort(#expr, __FILE__, __LINE__))
 #else
 	#define assert(expr) ((void) 0)
Index: uspace/lib/posix/ctype.c
===================================================================
--- uspace/lib/posix/ctype.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/ctype.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -94,5 +94,5 @@
 int posix_isprint(int c)
 {
-	return !posix_iscntrl(c);
+	return posix_isascii(c) && !posix_iscntrl(c);
 }
 
Index: uspace/lib/posix/fnmatch.c
===================================================================
--- uspace/lib/posix/fnmatch.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/fnmatch.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -525,4 +525,5 @@
 static char *_casefold(const char *s)
 {
+	assert(s != NULL);
 	char *result = strdup(s);
 	for (char *i = result; *i != '\0'; ++i) {
@@ -542,4 +543,7 @@
 int posix_fnmatch(const char *pattern, const char *string, int flags)
 {
+	assert(pattern != NULL);
+	assert(string != NULL);
+
 	// TODO: don't fold everything in advance, but only when needed
 
Index: uspace/lib/posix/internal/common.h
===================================================================
--- uspace/lib/posix/internal/common.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/internal/common.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -43,4 +43,14 @@
     __func__, __FILE__, __LINE__), abort())
 
+/* A little helper macro to avoid typing this over and over. */
+#define errnify(func, ...) ({ \
+	int rc = func(__VA_ARGS__); \
+	if (rc < 0) { \
+		errno = -rc; \
+		rc = -1; \
+	} \
+	rc; \
+})
+
 #endif /* LIBPOSIX_COMMON_H_ */
 
Index: uspace/lib/posix/pwd.c
===================================================================
--- uspace/lib/posix/pwd.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/pwd.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -39,6 +39,4 @@
 #include "errno.h"
 
-// TODO: documentation
-
 static bool entry_read = false;
 
@@ -46,6 +44,6 @@
 static const struct posix_passwd dummy_pwd = {
 	.pw_name = (char *) "user",
-	.pw_uid = 1,
-	.pw_gid = 1,
+	.pw_uid = 0,
+	.pw_gid = 0,
 	.pw_dir = (char *) "/",
 	.pw_shell = (char *) "/app/bdsh"
@@ -115,4 +113,7 @@
 {
 	assert(name != NULL);
+	assert(pwd != NULL);
+	assert(buffer != NULL);
+	assert(result != NULL);
 	
 	if (posix_strcmp(name, "user") != 0) {
@@ -121,5 +122,5 @@
 	}
 	
-	return posix_getpwuid_r(1, pwd, buffer, bufsize, result);
+	return posix_getpwuid_r(0, pwd, buffer, bufsize, result);
 }
 
@@ -132,5 +133,5 @@
 struct posix_passwd *posix_getpwuid(posix_uid_t uid)
 {
-	if (uid != 1) {
+	if (uid != 0) {
 		return NULL;
 	}
@@ -159,5 +160,5 @@
 	    '/', '\0', 'b', 'd', 's', 'h', '\0' };
 	
-	if (uid != 1) {
+	if (uid != 0) {
 		*result = NULL;
 		return 0;
@@ -171,6 +172,6 @@
 
 	pwd->pw_name = (char *) bf;
-	pwd->pw_uid = 1;
-	pwd->pw_gid = 1;
+	pwd->pw_uid = 0;
+	pwd->pw_gid = 0;
 	pwd->pw_dir = (char *) bf + 5;
 	pwd->pw_shell = (char *) bf + 7;
Index: uspace/lib/posix/pwd.h
===================================================================
--- uspace/lib/posix/pwd.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/pwd.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -35,6 +35,4 @@
 #ifndef POSIX_PWD_H_
 #define POSIX_PWD_H_
-
-// TODO: documentation
 
 #include "sys/types.h"
Index: uspace/lib/posix/signal.c
===================================================================
--- uspace/lib/posix/signal.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/signal.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -66,6 +66,8 @@
 
 /**
- * 
- * @param signo
+ * Default signal handler. Executes the default action for each signal,
+ * as reasonable within HelenOS.
+ *
+ * @param signo Signal number.
  */
 void __posix_default_signal_handler(int signo)
@@ -75,14 +77,14 @@
 		abort();
 	case SIGQUIT:
-		fprintf(stderr, "Quit signal raised. Exiting.");
+		fprintf(stderr, "Quit signal raised. Exiting.\n");
 		exit(EXIT_FAILURE);
 	case SIGINT:
-		fprintf(stderr, "Interrupt signal caught. Exiting.");
+		fprintf(stderr, "Interrupt signal caught. Exiting.\n");
 		exit(EXIT_FAILURE);
 	case SIGTERM:
-		fprintf(stderr, "Termination signal caught. Exiting.");
+		fprintf(stderr, "Termination signal caught. Exiting.\n");
 		exit(EXIT_FAILURE);
 	case SIGSTOP:
-		fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.");
+		fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.\n");
 		break;
 	case SIGKILL:
Index: uspace/lib/posix/stdio.c
===================================================================
--- uspace/lib/posix/stdio.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/stdio.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -50,4 +50,6 @@
 #include "libc/str.h"
 #include "libc/malloc.h"
+#include "libc/adt/list.h"
+#include "libc/sys/stat.h"
 
 
@@ -252,37 +254,52 @@
 	assert(mode != NULL);
 	assert(stream != NULL);
-
+	
+	/* Retieve the node. */
+	struct stat st;
+	int rc;
+	
 	if (filename == NULL) {
-		// TODO
-		
-		/* print error to stderr as well, to avoid hard to find problems
-		 * with buggy apps that expect this to work
-		 */
-		fprintf(stderr,
-		    "ERROR: Application wants to use freopen() to change mode of opened stream.\n"
-		    "       libposix does not support that yet, the application may function improperly.\n");
-		errno = ENOTSUP;
+		rc = fstat(stream->fd, &st);
+	} else {
+		rc = stat(filename, &st);
+	}
+	
+	if (rc != EOK) {
+		fclose(stream);
+		errno = -rc;
 		return NULL;
 	}
-
-	FILE* copy = malloc(sizeof(FILE));
-	if (copy == NULL) {
-		errno = ENOMEM;
+	
+	fdi_node_t node = {
+		.fs_handle = st.fs_handle,
+		.devmap_handle = st.devmap_handle,
+		.index = st.index
+	};
+	
+	/* Open a new stream. */
+	FILE* new = fopen_node(&node, mode);
+	if (new == NULL) {
+		fclose(stream);
+		/* fopen_node() sets errno. */
 		return NULL;
 	}
-	memcpy(copy, stream, sizeof(FILE));
-	fclose(copy); /* copy is now freed */
-	
-	copy = fopen(filename, mode); /* open new stream */
-	if (copy == NULL) {
-		/* fopen() sets errno */
-		return NULL;
-	}
-	
-	/* move the new stream to the original location */
-	memcpy(stream, copy, sizeof (FILE));
-	free(copy);
-	
-	/* update references in the file list */
+	
+	/* Close the original stream without freeing it (ignoring errors). */
+	if (stream->buf != NULL) {
+		fflush(stream);
+	}
+	if (stream->sess != NULL) {
+		async_hangup(stream->sess);
+	}
+	if (stream->fd >= 0) {
+		close(stream->fd);
+	}
+	list_remove(&stream->link);
+	
+	/* Move the new stream to the original location. */
+	memcpy(stream, new, sizeof (FILE));
+	free(new);
+	
+	/* Update references in the file list. */
 	stream->link.next->prev = &stream->link;
 	stream->link.prev->next = &stream->link;
@@ -676,14 +693,42 @@
 
 /**
- * Remove a file.
+ * Remove a file or directory.
  *
  * @param path Pathname of the file that shall be removed.
- * @return Zero on success, -1 otherwise.
+ * @return Zero on success, -1 (with errno set) otherwise.
  */
 int posix_remove(const char *path)
 {
-	// FIXME: unlink() and rmdir() seem to be equivalent at the moment,
-	//        but that does not have to be true forever
-	return unlink(path);
+	struct stat st;
+	int rc = stat(path, &st);
+	
+	if (rc != EOK) {
+		errno = -rc;
+		return -1;
+	}
+	
+	if (st.is_directory) {
+		rc = rmdir(path);
+	} else {
+		rc = unlink(path);
+	}
+	
+	if (rc != EOK) {
+		errno = -rc;
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Rename a file or directory.
+ *
+ * @param old
+ * @param new
+ * @return Zero on success, -1 (with errno set) otherwise.
+ */
+int posix_rename(const char *old, const char *new)
+{
+	return errnify(rename, old, new);
 }
 
Index: uspace/lib/posix/stdio.h
===================================================================
--- uspace/lib/posix/stdio.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/stdio.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -116,4 +116,7 @@
 extern int posix_remove(const char *path);
 
+/* Renaming Files */
+extern int posix_rename(const char *old, const char *new);
+
 /* Temporary Files */
 #undef L_tmpnam
@@ -170,4 +173,6 @@
 	#define remove posix_remove
 
+	#define rename posix_rename
+
 	#define tmpnam posix_tmpnam
 #endif
Index: uspace/lib/posix/sys/wait.c
===================================================================
--- uspace/lib/posix/sys/wait.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/sys/wait.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -39,4 +39,31 @@
 #include "wait.h"
 
+#include "../libc/task.h"
+#include "../assert.h"
+#include "../errno.h"
+#include "../limits.h"
+#include "../signal.h"
+
+int __posix_wifexited(int status) {
+	return status != INT_MIN;
+}
+
+int __posix_wexitstatus(int status) {
+	assert(__posix_wifexited(status));
+	return status;
+}
+
+int __posix_wifsignaled(int status) {
+	return status == INT_MIN;
+}
+
+int __posix_wtermsig(int status) {
+	assert(__posix_wifsignaled(status));
+	/* There is no way to distinguish reason
+	 * for unexpected termination at the moment.
+	 */
+	return SIGABRT;
+}
+
 /**
  * 
@@ -46,6 +73,7 @@
 posix_pid_t posix_wait(int *stat_ptr)
 {
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
+	/* HelenOS does not support this. */
+	errno = ENOSYS;
+	return (posix_pid_t) -1;
 }
 
@@ -59,6 +87,28 @@
 posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options)
 {
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
+	assert(stat_ptr != NULL);
+	assert(options == 0 /* None of the options are supported. */);
+	
+	task_exit_t texit;
+	int retval;
+	
+	int rc = task_wait((task_id_t) pid, &texit, &retval);
+	
+	if (rc < 0) {
+		/* Unable to retrieve status. */
+		errno = -rc;
+		return (posix_pid_t) -1;
+	}
+	
+	if (texit == TASK_EXIT_NORMAL) {
+		// FIXME: relies on application not returning this value
+		assert(retval != INT_MIN);
+		*stat_ptr = retval;
+	} else {
+		/* Reserve the lowest value for unexpected termination. */
+		*stat_ptr = INT_MIN;
+	}
+	
+	return pid;
 }
 
Index: uspace/lib/posix/sys/wait.h
===================================================================
--- uspace/lib/posix/sys/wait.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/sys/wait.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -38,4 +38,18 @@
 #include "types.h"
 
+#undef WIFEXITED
+#undef WEXITSTATUS
+#undef WIFSIGNALED
+#undef WTERMSIG
+#define WIFEXITED(status) __posix_wifexited(status)
+#define WEXITSTATUS(status) __posix_wexitstatus(status)
+#define WIFSIGNALED(status) __posix_wifsignaled(status)
+#define WTERMSIG(status) __posix_wtermsig(status)
+
+extern int __posix_wifexited(int status);
+extern int __posix_wexitstatus(int status);
+extern int __posix_wifsignaled(int status);
+extern int __posix_wtermsig(int status);
+
 extern posix_pid_t posix_wait(int *stat_ptr);
 extern posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options);
@@ -43,5 +57,5 @@
 #ifndef LIBPOSIX_INTERNAL
 	#define wait posix_wait
-	#define waitpid	posix_waitpid
+	#define waitpid posix_waitpid
 #endif
 
Index: uspace/lib/posix/unistd.c
===================================================================
--- uspace/lib/posix/unistd.c	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/unistd.c	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -110,9 +110,33 @@
 		return NULL;
 	}
+	
+	/* Save the original value to comply with the "no modification on
+	 * success" semantics.
+	 */
+	int orig_errno = errno;
+	errno = EOK;
+	
 	char *ret = getcwd(buf, size);
-	if (ret == NULL && errno == EOK) {
-		errno = ERANGE;
-	}
+	if (ret == NULL) {
+		/* Check errno to avoid shadowing other possible errors. */
+		if (errno == EOK) {
+			errno = ERANGE;
+		}
+	} else {
+		/* Success, restore previous errno value. */
+		errno = orig_errno;
+	}
+	
 	return ret;
+}
+
+/**
+ * Change the current working directory.
+ *
+ * @param path New working directory.
+ */
+int posix_chdir(const char *path)
+{
+	return errnify(chdir, path);
 }
 
@@ -157,4 +181,15 @@
 	/* There is currently no support for user accounts in HelenOS. */
 	return 0;
+}
+
+/**
+ * Close a file.
+ *
+ * @param fildes
+ * @return 0 on success, -1 on error.
+ */
+int posix_close(int fildes)
+{
+	return errnify(close, fildes);
 }
 
@@ -169,11 +204,44 @@
 ssize_t posix_read(int fildes, void *buf, size_t nbyte)
 {
-	int rc = read(fildes, buf, nbyte);
-	if (rc < 0) {
-		errno = -rc;
-		return -1;
-	} else {
-		return rc;
-	}
+	return errnify(read, fildes, buf, nbyte);
+}
+
+/**
+ * Write to a file.
+ *
+ * @param fildes File descriptor of the opened file.
+ * @param buf Buffer to write.
+ * @param nbyte Size of the buffer.
+ * @return Number of written bytes on success, -1 otherwise.
+ */
+ssize_t posix_write(int fildes, const void *buf, size_t nbyte)
+{
+	return errnify(write, fildes, buf, nbyte);
+}
+
+/**
+ * Requests outstanding data to be written to the underlying storage device.
+ *
+ * @param fildes
+ */
+int posix_fsync(int fildes)
+{
+	return errnify(fsync, fildes);
+}
+
+int posix_ftruncate(int fildes, posix_off_t length)
+{
+	return errnify(ftruncate, fildes, (aoff64_t) length);
+}
+
+/**
+ * Remove a directory.
+ *
+ * @param path Directory pathname.
+ * @return Zero on success, -1 otherwise.
+ */
+int posix_rmdir(const char *path)
+{
+	return errnify(rmdir, path);
 }
 
@@ -186,11 +254,15 @@
 int posix_unlink(const char *path)
 {
-	int rc = unlink(path);
-	if (rc < 0) {
-		errno = -rc;
-		return -1;
-	} else {
-		return rc;
-	}
+	return errnify(unlink, path);
+}
+
+int posix_dup(int fildes)
+{
+	return posix_fcntl(fildes, F_DUPFD, 0);
+}
+
+int posix_dup2(int fildes, int fildes2)
+{
+	return errnify(dup2, fildes, fildes2);
 }
 
@@ -204,13 +276,16 @@
 int posix_access(const char *path, int amode)
 {
-	if (amode == F_OK) {
-		/* Check file existence by attempt to open it. */
+	if (amode == F_OK || (amode & (X_OK | W_OK | R_OK))) {
+		/* HelenOS doesn't support permissions, permission checks
+		 * are equal to existence check.
+		 *
+		 * Check file existence by attempting to open it.
+		 */
 		int fd = open(path, O_RDONLY);
-		if (fd != -1) {
-			close(fd);
+		if (fd < 0) {
+			errno = -fd;
+			return -1;
 		}
-		return fd;
-	} else if (amode & (X_OK | W_OK | R_OK)) {
-		/* HelenOS doesn't support permissions, return success. */
+		close(fd);
 		return 0;
 	} else {
Index: uspace/lib/posix/unistd.h
===================================================================
--- uspace/lib/posix/unistd.h	(revision d85a01c1064b97b69ee6a694af20c69a67b9e08d)
+++ uspace/lib/posix/unistd.h	(revision 1814ee4d9e1d7165477752c7f3c9d99cf9eba2a7)
@@ -60,4 +60,5 @@
 /* Working Directory */
 extern char *posix_getcwd(char *buf, size_t size);
+extern int posix_chdir(const char *path);
 
 /* Query Memory Parameters */
@@ -69,9 +70,18 @@
 extern posix_gid_t posix_getgid(void);
 
-/* File Input/Output */
+/* File Manipulation */
+extern int posix_close(int fildes);
+
 extern ssize_t posix_read(int fildes, void *buf, size_t nbyte);
+extern ssize_t posix_write(int fildes, const void *buf, size_t nbyte);
 
-/* Deleting Files */
+extern int posix_fsync(int fildes);
+extern int posix_ftruncate(int fildes, posix_off_t length);
+
+extern int posix_rmdir(const char *path);
 extern int posix_unlink(const char *path);
+
+extern int posix_dup(int fildes);
+extern int posix_dup2(int fildes, int fildes2);
 
 /* Standard Streams */
@@ -144,4 +154,5 @@
 
 	#define getcwd posix_getcwd
+	#define chdir posix_chdir
 
 	#define isatty posix_isatty
@@ -154,7 +165,13 @@
 	#define getgid posix_getgid
 
+	#define close posix_close
 	#define read posix_read
-
+	#define write posix_write
+	#define fsync posix_fsync
+	#define ftruncate posix_ftruncate
+	#define rmdir posix_rmdir
 	#define unlink posix_unlink
+	#define dup posix_dup
+	#define dup2 posix_dup2
 
 	#define access posix_access
