Index: uspace/lib/c/generic/elf/elf_mod.c
===================================================================
--- uspace/lib/c/generic/elf/elf_mod.c	(revision 38d150e6238ab44c861f6486e46454e07caeb0f0)
+++ uspace/lib/c/generic/elf/elf_mod.c	(revision bde5c044624f5375df5235c6f6f2f4a7286fbe1a)
@@ -137,8 +137,9 @@
 	elf_header_t *header = &header_buf;
 	aoff64_t pos = 0;
+	size_t nr;
 	int i, rc;
 
-	rc = vfs_read(elf->fd, &pos, header, sizeof(elf_header_t));
-	if (rc != sizeof(elf_header_t)) {
+	rc = vfs_read(elf->fd, &pos, header, sizeof(elf_header_t), &nr);
+	if (rc != EOK || nr != sizeof(elf_header_t)) {
 		DPRINTF("Read error.\n"); 
 		return EE_INVALID;
@@ -199,6 +200,6 @@
 		pos = header->e_phoff + i * sizeof(elf_segment_header_t);
 		rc = vfs_read(elf->fd, &pos, &segment_hdr,
-		    sizeof(elf_segment_header_t));
-		if (rc != sizeof(elf_segment_header_t)) {
+		    sizeof(elf_segment_header_t), &nr);
+		if (rc != EOK || nr != sizeof(elf_segment_header_t)) {
 			DPRINTF("Read error.\n");
 			return EE_INVALID;
@@ -218,6 +219,6 @@
 		pos = header->e_shoff + i * sizeof(elf_section_header_t);
 		rc = vfs_read(elf->fd, &pos, &section_hdr,
-		    sizeof(elf_section_header_t));
-		if (rc != sizeof(elf_section_header_t)) {
+		    sizeof(elf_section_header_t), &nr);
+		if (rc != EOK || nr != sizeof(elf_section_header_t)) {
 			DPRINTF("Read error.\n");
 			return EE_INVALID;
@@ -330,5 +331,6 @@
 	size_t mem_sz;
 	aoff64_t pos;
-	ssize_t rc;
+	int rc;
+	size_t nr;
 
 	bias = elf->bias;
@@ -388,6 +390,6 @@
 	 */
 	pos = entry->p_offset;
-	rc = vfs_read(elf->fd, &pos, seg_ptr, entry->p_filesz);
-	if (rc < 0) {
+	rc = vfs_read(elf->fd, &pos, seg_ptr, entry->p_filesz, &nr);
+	if (rc != EOK || nr != entry->p_filesz) {
 		DPRINTF("read error\n");
 		return EE_INVALID;
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 38d150e6238ab44c861f6486e46454e07caeb0f0)
+++ uspace/lib/c/generic/io/io.c	(revision bde5c044624f5375df5235c6f6f2f4a7286fbe1a)
@@ -430,17 +430,19 @@
 static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
 {
+	int rc;
+	size_t nread;
+
 	if (size == 0 || nmemb == 0)
 		return 0;
 
-	ssize_t rd = vfs_read(stream->fd, &stream->pos, buf, size * nmemb);
-	if (rd < 0) {
-		errno = rd;
+	rc = vfs_read(stream->fd, &stream->pos, buf, size * nmemb, &nread);
+	if (rc != EOK) {
+		errno = rc;
 		stream->error = true;
-		rd = 0;
-	} else if (rd == 0) {
+	} else if (nread == 0) {
 		stream->eof = true;
 	}
-	
-	return (rd / size);
+
+	return (nread / size);
 }
 
@@ -457,30 +459,29 @@
 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
 {
+	int rc;
+	size_t nwritten;
+
 	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) {
+		rc = kio_write(buf, size * nmemb, &nwritten);
+		if (rc != EOK) {
 			stream->error = true;
-			wr = 0;
-		} else {
-			wr = nwritten;
+			nwritten = 0;
 		}
 	} else {
-		wr = vfs_write(stream->fd, &stream->pos, buf, size * nmemb);
-		if (wr < 0) {
-			errno = wr;
+		rc = vfs_write(stream->fd, &stream->pos, buf, size * nmemb,
+		    &nwritten);
+		if (rc != EOK) {
+			errno = rc;
 			stream->error = true;
-			wr = 0;
 		}
 	}
 
-	if (wr > 0)
+	if (nwritten > 0)
 		stream->need_sync = true;
-	
-	return (wr / size);
+
+	return (nwritten / size);
 }
 
@@ -491,10 +492,12 @@
 static void _ffillbuf(FILE *stream)
 {
-	ssize_t rc;
+	int rc;
+	size_t nread;
 
 	stream->buf_head = stream->buf_tail = stream->buf;
 
-	rc = vfs_read(stream->fd, &stream->pos, stream->buf, stream->buf_size);
-	if (rc < 0) {
+	rc = vfs_read(stream->fd, &stream->pos, stream->buf, stream->buf_size,
+	    &nread);
+	if (rc != EOK) {
 		errno = rc;
 		stream->error = true;
@@ -502,10 +505,10 @@
 	}
 
-	if (rc == 0) {
+	if (nread == 0) {
 		stream->eof = true;
 		return;
 	}
 
-	stream->buf_head += rc;
+	stream->buf_head += nread;
 	stream->buf_state = _bs_read;
 }
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 38d150e6238ab44c861f6486e46454e07caeb0f0)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision bde5c044624f5375df5235c6f6f2f4a7286fbe1a)
@@ -86,5 +86,5 @@
  * and consume system resources.
  *
- * Functions that return int return a negative error code on error and do not
+ * Functions that return int return an error code on error and do not
  * set errno. Depending on function, success is signalled by returning either
  * EOK or a non-negative file handle.
@@ -104,11 +104,12 @@
  * 	aoff64_t pos = 42;
  * 	char buf[512];
- * 	ssize_t size = vfs_read(file, &pos, buf, sizeof(buf));
- * 	if (size < 0) {
+ *	size_t nread;
+ * 	rc = vfs_read(file, &pos, buf, sizeof(buf), &nread);
+ * 	if (rc != EOK) {
  * 		vfs_put(file);
- * 		return size;
+ * 		return rc;
  * 	}
  *
- *	// buf is now filled with data from file
+ *	// buf is now filled with nread bytes from file
  *
  *	vfs_put(file);
@@ -808,12 +809,14 @@
  * @param buf		Buffer, @a nbytes bytes long
  * @param nbytes	Number of bytes to read
- *
- * @return              On success, non-negative number of bytes read
- * @return              On failure, a negative error code
- */
-ssize_t vfs_read(int file, aoff64_t *pos, void *buf, size_t nbyte)
+ * @param nread		Place to store number of bytes actually read
+ *
+ * @return              On success, EOK and @a *nread is filled with number
+ *			of bytes actually read.
+ * @return              On failure, an error code
+ */
+int vfs_read(int file, aoff64_t *pos, void *buf, size_t nbyte, size_t *nread)
 {
 	ssize_t cnt = 0;
-	size_t nread = 0;
+	size_t nr = 0;
 	uint8_t *bp = (uint8_t *) buf;
 	int rc;
@@ -821,14 +824,18 @@
 	do {
 		bp += cnt;
-		nread += cnt;
+		nr += cnt;
 		*pos += cnt;
-		rc = vfs_read_short(file, *pos, bp, nbyte - nread, &cnt);
-	} while (rc == EOK && cnt > 0 && (nbyte - nread - cnt) > 0);
-	
-	if (rc != EOK)
+		rc = vfs_read_short(file, *pos, bp, nbyte - nr, &cnt);
+	} while (rc == EOK && cnt > 0 && (nbyte - nr - cnt) > 0);
+	
+	if (rc != EOK) {
+		*nread = nr;
 		return rc;
-	
+	}
+	
+	nr += cnt;
 	*pos += cnt;
-	return nread + cnt;
+	*nread = nr;
+	return EOK;
 }
 
@@ -1247,12 +1254,15 @@
  * @param buf           Data, @a nbytes bytes long
  * @param nbytes        Number of bytes to write
- *
- * @return		On success, non-negative number of bytes written
- * @return              On failure, a negative error code
- */
-ssize_t vfs_write(int file, aoff64_t *pos, const void *buf, size_t nbyte)
+ * @param nwritten	Place to store number of bytes written
+ *
+ * @return		On success, EOK, @a *nwr is filled with number
+ *			of bytes written
+ * @return              On failure, an error code
+ */
+int vfs_write(int file, aoff64_t *pos, const void *buf, size_t nbyte,
+    size_t *nwritten)
 {
 	ssize_t cnt = 0;
-	ssize_t nwritten = 0;
+	ssize_t nwr = 0;
 	const uint8_t *bp = (uint8_t *) buf;
 	int rc;
@@ -1260,14 +1270,18 @@
 	do {
 		bp += cnt;
-		nwritten += cnt;
+		nwr += cnt;
 		*pos += cnt;
-		rc = vfs_write_short(file, *pos, bp, nbyte - nwritten, &cnt);
-	} while (rc == EOK && ((ssize_t )nbyte - nwritten - cnt) > 0);
-
-	if (rc != EOK)
+		rc = vfs_write_short(file, *pos, bp, nbyte - nwr, &cnt);
+	} while (rc == EOK && ((ssize_t )nbyte - nwr - cnt) > 0);
+
+	if (rc != EOK) {
+		*nwritten = nwr;
 		return rc;
-
+	}
+
+	nwr += cnt;
 	*pos += cnt;
-	return nbyte;
+	*nwritten = nwr;
+	return EOK;
 }
 
