Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 59f388a67f9319d79d123a42feecf8a6efba764e)
+++ uspace/lib/c/generic/io/io.c	(revision e86a617a5eab0a2c0690620fc1130a3770cbd495)
@@ -35,4 +35,5 @@
 #include <stdio.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <assert.h>
 #include <str.h>
@@ -44,5 +45,4 @@
 #include <vfs/vfs.h>
 #include <vfs/vfs_sess.h>
-#include <vfs/inbox.h>
 #include <ipc/loc.h>
 #include <adt/list.h>
@@ -55,5 +55,4 @@
 static FILE stdin_null = {
 	.fd = -1,
-	.pos = 0, 
 	.error = true,
 	.eof = true,
@@ -70,5 +69,4 @@
 static FILE stdout_kio = {
 	.fd = -1,
-	.pos = 0, 
 	.error = false,
 	.eof = false,
@@ -85,5 +83,4 @@
 static FILE stderr_kio = {
 	.fd = -1,
-	.pos = 0, 
 	.error = false,
 	.eof = false,
@@ -104,16 +101,8 @@
 static LIST_INITIALIZE(files);
 
-void __stdio_init(void)
-{
-	/* The first three standard file descriptors are assigned for compatibility.
-	 * This will probably be removed later.
-	 */
-	 
-	int infd = inbox_get("stdin");
-	if (infd >= 0) {
-		int stdinfd = vfs_clone(infd, -1, false);
-		assert(stdinfd == 0);
-		vfs_open(stdinfd, MODE_READ);
-		stdin = fdopen(stdinfd, "r");
+void __stdio_init(int filc)
+{
+	if (filc > 0) {
+		stdin = fdopen(0, "r");
 	} else {
 		stdin = &stdin_null;
@@ -121,12 +110,6 @@
 	}
 	
-	int outfd = inbox_get("stdout");
-	if (outfd >= 0) {
-		int stdoutfd = vfs_clone(outfd, -1, false);
-		assert(stdoutfd <= 1);
-		while (stdoutfd < 1)
-			stdoutfd = vfs_clone(outfd, -1, false);
-		vfs_open(stdoutfd, MODE_APPEND);
-		stdout = fdopen(stdoutfd, "a");
+	if (filc > 1) {
+		stdout = fdopen(1, "w");
 	} else {
 		stdout = &stdout_kio;
@@ -134,12 +117,6 @@
 	}
 	
-	int errfd = inbox_get("stderr");
-	if (errfd >= 0) {
-		int stderrfd = vfs_clone(errfd, -1, false);
-		assert(stderrfd <= 2);
-		while (stderrfd < 2)
-			stderrfd = vfs_clone(errfd, -1, false);
-		vfs_open(stderrfd, MODE_APPEND);
-		stderr = fdopen(stderrfd, "a");
+	if (filc > 2) {
+		stderr = fdopen(2, "w");
 	} else {
 		stderr = &stderr_kio;
@@ -156,8 +133,8 @@
 }
 
-static bool parse_mode(const char *fmode, int *mode, bool *create, bool *truncate)
+static bool parse_mode(const char *mode, int *flags)
 {
 	/* Parse mode except first character. */
-	const char *mp = fmode;
+	const char *mp = mode;
 	if (*mp++ == 0) {
 		errno = EINVAL;
@@ -179,18 +156,12 @@
 		return false;
 	}
-
-	*create = false;
-	*truncate = false;
-	
-	/* Parse first character of fmode and determine mode for vfs_open(). */
-	switch (fmode[0]) {
+	
+	/* Parse first character of mode and determine flags for open(). */
+	switch (mode[0]) {
 	case 'r':
-		*mode = plus ? MODE_READ | MODE_WRITE : MODE_READ;
+		*flags = plus ? O_RDWR : O_RDONLY;
 		break;
 	case 'w':
-		*mode = plus ? MODE_READ | MODE_WRITE : MODE_WRITE;
-		*create = true;
-		if (!plus)
-			*truncate = true;
+		*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
 		break;
 	case 'a':
@@ -200,7 +171,5 @@
 			return false;
 		}
-
-		*mode = MODE_APPEND | (plus ? MODE_READ | MODE_WRITE : MODE_WRITE);
-		*create = true;
+		*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
 		break;
 	default:
@@ -276,11 +245,8 @@
  *
  */
-FILE *fopen(const char *path, const char *fmode)
-{
-	int mode;
-	bool create;
-	bool truncate;
-
-	if (!parse_mode(fmode, &mode, &create, &truncate))
+FILE *fopen(const char *path, const char *mode)
+{
+	int flags;
+	if (!parse_mode(mode, &flags))
 		return NULL;
 	
@@ -291,35 +257,12 @@
 		return NULL;
 	}
-
-	int flags = WALK_REGULAR;
-	if (create)
-		flags |= WALK_MAY_CREATE;
-	int file = vfs_lookup(path, flags);
-	if (file < 0) {
-		errno = file;
+	
+	stream->fd = open(path, flags, 0666);
+	if (stream->fd < 0) {
+		/* errno was set by open() */
 		free(stream);
 		return NULL;
 	}
-
-	int rc = vfs_open(file, mode);
-	if (rc != EOK) {
-		errno = rc;
-		vfs_put(file);
-		free(stream);
-		return NULL;
-	}
-	
-	if (truncate) {
-		rc = vfs_resize(file, 0);
-		if (rc != EOK) {
-			errno = rc;
-			vfs_put(file);
-			free(stream);
-			return NULL;
-		}
-	}
-
-	stream->fd = file;
-	stream->pos = 0;
+	
 	stream->error = false;
 	stream->eof = false;
@@ -345,5 +288,4 @@
 	
 	stream->fd = fd;
-	stream->pos = 0;
 	stream->error = false;
 	stream->eof = false;
@@ -370,5 +312,5 @@
 	
 	if (stream->fd >= 0)
-		rc = vfs_put(stream->fd);
+		rc = close(stream->fd);
 	
 	list_remove(&stream->link);
@@ -431,17 +373,27 @@
 static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
 {
+	size_t left, done;
+
 	if (size == 0 || nmemb == 0)
 		return 0;
 
-	ssize_t rd = vfs_read(stream->fd, &stream->pos, buf, size * nmemb);
-	if (rd < 0) {
-		errno = rd;
-		stream->error = true;
-		rd = 0;
-	} else if (rd == 0) {
-		stream->eof = true;
-	}
-	
-	return (rd / size);
+	left = size * nmemb;
+	done = 0;
+	
+	while ((left > 0) && (!stream->error) && (!stream->eof)) {
+		ssize_t rd = read(stream->fd, buf + done, left);
+		
+		if (rd < 0) {
+			/* errno was set by read() */
+			stream->error = true;
+		} else if (rd == 0) {
+			stream->eof = true;
+		} else {
+			left -= rd;
+			done += rd;
+		}
+	}
+	
+	return (done / size);
 }
 
@@ -458,30 +410,48 @@
 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
 {
+	size_t left;
+	size_t done;
+	int rc;
+
 	if (size == 0 || nmemb == 0)
 		return 0;
 
-	ssize_t wr;
-	if (stream->kio) {
-		size_t nwritten;
-		wr = kio_write(buf, size * nmemb, &nwritten);
-		if (wr != EOK) {
+	left = size * nmemb;
+	done = 0;
+
+	while ((left > 0) && (!stream->error)) {
+		ssize_t wr;
+		size_t uwr;
+		
+		if (stream->kio) {
+			uwr = 0;
+			rc = kio_write(buf + done, left, &uwr);
+			if (rc != EOK)
+				errno = rc;
+		} else {
+			wr = write(stream->fd, buf + done, left);
+			if (wr >= 0) {
+				uwr = (size_t)wr;
+				rc = EOK;
+			} else {
+				/* errno was set by write */
+				uwr = 0;
+				rc = errno;
+			}
+		}
+		
+		if (rc != EOK) {
+			/* errno was set above */
 			stream->error = true;
-			wr = 0;
 		} else {
-			wr = nwritten;
+			left -= uwr;
+			done += uwr;
 		}
-	} else {
-		wr = vfs_write(stream->fd, &stream->pos, buf, size * nmemb);
-		if (wr < 0) {
-			errno = wr;
-			stream->error = true;
-			wr = 0;
-		}
-	}
-
-	if (wr > 0)
+	}
+
+	if (done > 0)
 		stream->need_sync = true;
 	
-	return (wr / size);
+	return (done / size);
 }
 
@@ -496,7 +466,7 @@
 	stream->buf_head = stream->buf_tail = stream->buf;
 
-	rc = vfs_read(stream->fd, &stream->pos, stream->buf, stream->buf_size);
+	rc = read(stream->fd, stream->buf, stream->buf_size);
 	if (rc < 0) {
-		errno = rc;
+		/* errno was set by read() */
 		stream->error = true;
 		return;
@@ -523,6 +493,13 @@
 
 	/* If buffer has prefetched read data, we need to seek back. */
-	if (bytes_used > 0 && stream->buf_state == _bs_read)
-		stream->pos -= bytes_used;
+	if (bytes_used > 0 && stream->buf_state == _bs_read) {
+		off64_t rc;
+		rc = lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
+		if (rc == (off64_t)-1) {
+			/* errno was set by lseek */
+			stream->error = 1;
+			return;
+		}
+	}
 
 	/* If buffer has unwritten data, we need to write them out. */
@@ -796,34 +773,21 @@
 int fseek(FILE *stream, off64_t offset, int whence)
 {
-	int rc;
+	off64_t rc;
 
 	if (stream->error)
-		return -1;
+		return EOF;
 
 	_fflushbuf(stream);
 	if (stream->error) {
 		/* errno was set by _fflushbuf() */
-		return -1;
+		return EOF;
 	}
 
 	stream->ungetc_chars = 0;
 
-	struct stat st;
-	switch (whence) {
-	case SEEK_SET:
-		stream->pos = offset;
-		break;
-	case SEEK_CUR:
-		stream->pos += offset;
-		break;
-	case SEEK_END:
-		rc = vfs_stat(stream->fd, &st);
-		if (rc != EOK) {
-			errno = rc;
-			stream->error = true;
-			return -1;	
-		}
-		stream->pos = st.size + offset;
-		break;
+	rc = lseek(stream->fd, offset, whence);
+	if (rc == (off64_t) (-1)) {
+		/* errno has been set by lseek() */
+		return EOF;
 	}
 
@@ -834,8 +798,6 @@
 off64_t ftell(FILE *stream)
 {
-	/* The native position is too large for the C99-ish interface. */
-	if (stream->pos - stream->ungetc_chars > INT64_MAX)
-		return EOF;
-
+	off64_t pos;
+	
 	if (stream->error)
 		return EOF;
@@ -847,5 +809,11 @@
 	}
 
-	return stream->pos - stream->ungetc_chars;
+	pos = lseek(stream->fd, 0, SEEK_CUR);
+	if (pos == (off64_t) -1) {
+		/* errno was set by lseek */
+		return (off64_t) -1;
+	}
+	
+	return pos - stream->ungetc_chars;
 }
 
@@ -872,6 +840,4 @@
 	
 	if ((stream->fd >= 0) && (stream->need_sync)) {
-		int rc;
-
 		/**
 		 * Better than syncing always, but probably still not the
@@ -879,7 +845,6 @@
 		 */
 		stream->need_sync = false;
-		rc = vfs_sync(stream->fd);
-		if (rc != EOK) {
-			errno = rc;
+		if (fsync(stream->fd) != 0) {
+			/* errno was set by fsync() */
 			return EOF;
 		}
