Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 8e3498b351ae109f7ad16592a1f108e3bd44c829)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision a99cbc1e2f454ad3c85123d255ae6bc002a5085c)
@@ -128,5 +128,5 @@
 static int root_fd = -1;
 
-static int get_parent_and_child(const char *path, char **child)
+static int get_parent_and_child(const char *path, int *parent, char **child)
 {
 	size_t size;
@@ -136,14 +136,18 @@
 
 	char *slash = str_rchr(apath, L'/');
-	int parent;
 	if (slash == apath) {
-		parent = vfs_root();
+		*parent = vfs_root();
+		if (*parent < 0) {
+			free(apath);
+			return EBADF;
+		}
 		*child = apath;
+		return EOK;
 	} else {
 		*slash = '\0';
-		parent = vfs_lookup(apath, WALK_DIRECTORY);
-		if (parent < 0) {
+		int rc = vfs_lookup(apath, WALK_DIRECTORY, parent);
+		if (rc != EOK) {
 			free(apath);
-			return parent;
+			return rc;
 		}
 		*slash = '/';
@@ -151,10 +155,11 @@
 		free(apath);
 		if (!*child) {
-			vfs_put(parent);
+			vfs_put(*parent);
 			return ENOMEM;
 		}
-	}
-
-	return parent;
+
+		return rc;
+	}
+
 }
 
@@ -233,10 +238,17 @@
  * @return              New file handle on success or a negative error code
  */
-int vfs_clone(int file_from, int file_to, bool high)
-{
+int vfs_clone(int file_from, int file_to, bool high, int *handle)
+{
+	assert(handle != NULL);
+
 	async_exch_t *vfs_exch = vfs_exchange_begin();
-	int rc = async_req_3_0(vfs_exch, VFS_IN_CLONE, (sysarg_t) file_from,
-	    (sysarg_t) file_to, (sysarg_t) high);
+	sysarg_t ret;
+	int rc = async_req_3_1(vfs_exch, VFS_IN_CLONE, (sysarg_t) file_from,
+	    (sysarg_t) file_to, (sysarg_t) high, &ret);
 	vfs_exchange_end(vfs_exch);
+
+	if (rc == EOK) {
+		*handle = ret;
+	}
 	return rc;
 }
@@ -277,8 +289,9 @@
 		return ENOMEM;
 	
-	int fd = vfs_lookup(abs, WALK_DIRECTORY);
-	if (fd < 0) {
+	int fd;
+	int rc = vfs_lookup(abs, WALK_DIRECTORY, &fd);
+	if (rc != EOK) {
 		free(abs);
-		return fd;
+		return rc;
 	}
 	
@@ -491,8 +504,8 @@
 {
 	int flags = (kind == KIND_DIRECTORY) ? WALK_DIRECTORY : WALK_REGULAR;
-	int file = vfs_walk(parent, child, WALK_MUST_CREATE | flags);
-
-	if (file < 0)
-		return file;
+	int file = -1;
+	int rc = vfs_walk(parent, child, WALK_MUST_CREATE | flags, &file);
+	if (rc != EOK)
+		return rc;
 
 	if (linkedfd)
@@ -521,14 +534,15 @@
 {
 	char *child;
-	int parent = get_parent_and_child(path, &child);
-	if (parent < 0)
-		return parent;
-
-	int rc = vfs_link(parent, child, kind, linkedfd);
+	int parent;
+	int rc = get_parent_and_child(path, &parent, &child);
+	if (rc != EOK)
+		return rc;
+
+	rc = vfs_link(parent, child, kind, linkedfd);
 
 	free(child);
 	vfs_put(parent);
 	return rc;
-}	
+}
 
 /** Lookup a path relative to the local root
@@ -536,9 +550,9 @@
  * @param path  Path to be looked up
  * @param flags Walk flags
- *
- * @return      File handle representing the result on success or a negative
- *              error code on error
- */
-int vfs_lookup(const char *path, int flags)
+ * @param[out] handle Pointer to variable where handle is to be written.
+ *
+ * @return      EOK on success or an error code.
+ */
+int vfs_lookup(const char *path, int flags, int *handle)
 {
 	size_t size;
@@ -546,4 +560,5 @@
 	if (!p)
 		return ENOMEM;
+
 	int root = vfs_root();
 	if (root < 0) {
@@ -551,5 +566,6 @@
 		return ENOENT;
 	}
-	int rc = vfs_walk(root, p, flags);
+
+	int rc = vfs_walk(root, p, flags, handle);
 	vfs_put(root);
 	free(p);
@@ -564,20 +580,23 @@
  * @param flags Walk flags
  * @param mode  Mode in which to open file in
+ * @param[out] handle Pointer to variable where handle is to be written.
  *
  * @return      EOK on success or a negative error code
  */
-int vfs_lookup_open(const char *path, int flags, int mode)
-{
-	int file = vfs_lookup(path, flags);
-	if (file < 0)
-		return file;
-
-	int rc = vfs_open(file, mode);
+int vfs_lookup_open(const char *path, int flags, int mode, int *handle)
+{
+	int file;
+	int rc = vfs_lookup(path, flags, &file);
+	if (rc != EOK)
+		return rc;
+
+	rc = vfs_open(file, mode);
 	if (rc != EOK) {
 		vfs_put(file);
 		return rc;
 	}
-	
-	return file;
+
+	*handle = file;
+	return EOK;
 }
 
@@ -707,11 +726,10 @@
 		}
 		
-		int mpfd = vfs_walk(root_fd, mpa, WALK_DIRECTORY);
-		if (mpfd >= 0) {
+		int mpfd;
+		rc = vfs_walk(root_fd, mpa, WALK_DIRECTORY, &mpfd);
+		if (rc == EOK) {
 			rc = vfs_mount(mpfd, fs_name, service_id, opts, flags,
 			    instance, NULL);
 			vfs_put(mpfd);
-		} else {
-			rc = mpfd;
 		}
 	}
@@ -775,8 +793,9 @@
  * @param high   If true, the received file handle will be allocated from high
  *               indices
+ * @param[out] handle  Received handle.
  *
  * @return       EOK on success or a negative error code
  */
-int vfs_receive_handle(bool high)
+int vfs_receive_handle(bool high, int *handle)
 {
 	ipc_callid_t callid;
@@ -795,7 +814,9 @@
 	async_exchange_end(vfs_exch);
 
-	if (rc != EOK)
-		return rc;
-	return ret;
+	if (rc == EOK) {
+		*handle = (int) ret;
+	}
+
+	return rc;
 }
 
@@ -976,16 +997,20 @@
 /** Return a new file handle representing the local root
  *
- * @return      A clone of the local root file handle or a negative error code
+ * @return      A clone of the local root file handle or -1
  */
 int vfs_root(void)
 {
-	fibril_mutex_lock(&root_mutex);	
-	int r;
-	if (root_fd < 0)
-		r = ENOENT;
-	else
-		r = vfs_clone(root_fd, -1, true);
+	fibril_mutex_lock(&root_mutex);
+	int fd;
+	if (root_fd < 0) {
+		fd = -1;
+	} else {
+		int rc = vfs_clone(root_fd, -1, true, &fd);
+		if (rc != EOK) {
+			fd = -1;
+		}
+	}
 	fibril_mutex_unlock(&root_mutex);
-	return r;
+	return fd;
 }
 
@@ -997,12 +1022,22 @@
  *
  * @param nroot The new local root file handle
- */
-void vfs_root_set(int nroot)
-{
+ *
+ * @return  Error code
+ */
+int vfs_root_set(int nroot)
+{
+	int new_root;
+	int rc = vfs_clone(nroot, -1, true, &new_root);
+	if (rc != EOK) {
+		return rc;
+	}
+
 	fibril_mutex_lock(&root_mutex);
 	if (root_fd >= 0)
 		vfs_put(root_fd);
-	root_fd = vfs_clone(nroot, -1, true);
+	root_fd = new_root;
 	fibril_mutex_unlock(&root_mutex);
+
+	return EOK;
 }
 
@@ -1050,9 +1085,10 @@
 int vfs_stat_path(const char *path, struct stat *stat)
 {
-	int file = vfs_lookup(path, 0);
-	if (file < 0)
-		return file;
-	
-	int rc = vfs_stat(file, stat);
+	int file;
+	int rc = vfs_lookup(path, 0, &file);
+	if (rc != EOK)
+		return rc;
+	
+	rc = vfs_stat(file, stat);
 
 	vfs_put(file);
@@ -1095,9 +1131,10 @@
 int vfs_statfs_path(const char *path, struct statfs *st)
 {
-	int file = vfs_lookup(path, 0);
-	if (file < 0)
-		return file;
-	
-	int rc = vfs_statfs(file, st);
+	int file;
+	int rc = vfs_lookup(path, 0, &file);
+	if (rc != EOK)
+		return rc;
+	
+	rc = vfs_statfs(file, st);
 
 	vfs_put(file);
@@ -1165,16 +1202,18 @@
 int vfs_unlink_path(const char *path)
 {
-	int expect = vfs_lookup(path, 0);
-	if (expect < 0)
-		return expect;
+	int expect;
+	int rc = vfs_lookup(path, 0, &expect);
+	if (rc != EOK)
+		return rc;
 
 	char *child;
-	int parent = get_parent_and_child(path, &child);
-	if (parent < 0) {
+	int parent;
+	rc = get_parent_and_child(path, &parent, &child);
+	if (rc != EOK) {
 		vfs_put(expect);
-		return parent;
-	}
-
-	int rc = vfs_unlink(parent, child, expect);
+		return rc;
+	}
+
+	rc = vfs_unlink(parent, child, expect);
 	
 	free(child);
@@ -1206,9 +1245,10 @@
 int vfs_unmount_path(const char *mpp)
 {
-	int mp = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY);
-	if (mp < 0)
-		return mp;
-	
-	int rc = vfs_unmount(mp);
+	int mp;
+	int rc = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY, &mp);
+	if (rc != EOK)
+		return rc;
+	
+	rc = vfs_unmount(mp);
 	vfs_put(mp);
 	return rc;
@@ -1220,9 +1260,9 @@
  * @param path          Parent-relative path to be walked
  * @param flags         Flags influencing the walk
- *
- * @retrun              File handle representing the result on success or
- *                      a negative error code on error
- */
-int vfs_walk(int parent, const char *path, int flags)
+ * @param[out] handle   File handle representing the result on success.
+ *
+ * @return              Error code.
+ */
+int vfs_walk(int parent, const char *path, int flags, int *handle)
 {
 	async_exch_t *exch = vfs_exchange_begin();
@@ -1242,5 +1282,6 @@
 		return (int) rc;
 	
-	return (int) IPC_GET_ARG1(answer);
+	*handle = (int) IPC_GET_ARG1(answer);
+	return EOK;
 }
 
