Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision fb6f1a5becf4ed481c7d009a226723cae1c82b9d)
+++ uspace/srv/loader/main.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -125,24 +125,15 @@
 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t len;
-	
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	cwd = malloc(len + 1);
-	if (!cwd) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, cwd, len);
-	cwd[len] = '\0';
-	
-	ipc_answer_0(rid, EOK);
+	char *buf;
+	int rc = async_string_receive(&buf, 0, NULL);
+	
+	if (rc == EOK) {
+		if (cwd != NULL)
+			free(cwd);
+		
+		cwd = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -154,31 +145,15 @@
 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t len;
-	char *name_buf;
-	
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	name_buf = malloc(len + 1);
-	if (!name_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, name_buf, len);
-	ipc_answer_0(rid, EOK);
-	
-	if (pathname != NULL) {
-		free(pathname);
-		pathname = NULL;
-	}
-	
-	name_buf[len] = '\0';
-	pathname = name_buf;
+	char *buf;
+	int rc = async_string_receive(&buf, 0, NULL);
+	
+	if (rc == EOK) {
+		if (pathname != NULL)
+			free(pathname);
+		
+		pathname = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -190,73 +165,60 @@
 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t buf_size, arg_size;
-	char *p;
-	int n;
-	
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (arg_buf != NULL) {
-		free(arg_buf);
-		arg_buf = NULL;
-	}
-	
-	if (argv != NULL) {
-		free(argv);
-		argv = NULL;
-	}
-	
-	arg_buf = malloc(buf_size + 1);
-	if (!arg_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, arg_buf, buf_size);
-	
-	arg_buf[buf_size] = '\0';
-	
-	/*
-	 * Count number of arguments
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	/* Allocate argv */
-	argv = malloc((n + 1) * sizeof(char *));
-	
-	if (argv == NULL) {
-		free(arg_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-
-	/*
-	 * Fill argv with argument pointers
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		argv[n] = p;
-		
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	argc = n;
-	argv[n] = NULL;
-
-	ipc_answer_0(rid, EOK);
+	char *buf;
+	size_t buf_size;
+	int rc = async_string_receive(&buf, 0, &buf_size);
+	
+	if (rc == EOK) {
+		/*
+		 * Count number of arguments
+		 */
+		char *cur = buf;
+		int count = 0;
+		
+		while (cur < buf + buf_size) {
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		
+		/*
+		 * Allocate new argv
+		 */
+		char **_argv = (char **) malloc((count + 1) * sizeof(char *));
+		if (_argv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new argv with argument pointers
+		 */
+		cur = buf;
+		count = 0;
+		while (cur < buf + buf_size) {
+			_argv[count] = cur;
+			
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		_argv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (arg_buf != NULL)
+			free(arg_buf);
+		
+		if (argv != NULL)
+			free(argv);
+		
+		argc = count;
+		arg_buf = buf;
+		argv = _argv;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -268,57 +230,43 @@
 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
+	void *buf;
 	size_t buf_size;
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if ((buf_size % sizeof(fdi_node_t)) != 0) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (fil_buf != NULL) {
-		free(fil_buf);
-		fil_buf = NULL;
-	}
-	
-	if (filv != NULL) {
-		free(filv);
-		filv = NULL;
-	}
-	
-	fil_buf = malloc(buf_size);
-	if (!fil_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, fil_buf, buf_size);
-	
-	int count = buf_size / sizeof(fdi_node_t);
-	
-	/* Allocate filvv */
-	filv = malloc((count + 1) * sizeof(fdi_node_t *));
-	
-	if (filv == NULL) {
-		free(fil_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	/*
-	 * Fill filv with argument pointers
-	 */
-	int i;
-	for (i = 0; i < count; i++)
-		filv[i] = &fil_buf[i];
-	
-	filc = count;
-	filv[count] = NULL;
+	int rc = async_data_receive(&buf, 0, sizeof(fdi_node_t), &buf_size);
+	
+	if (rc == EOK) {
+		int count = buf_size / sizeof(fdi_node_t);
+		
+		/*
+		 * Allocate new filv
+		 */
+		fdi_node_t **_filv = (fdi_node_t *) malloc((count + 1) * sizeof(fdi_node_t *));
+		if (_filv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new filv with argument pointers
+		 */
+		int i;
+		for (i = 0; i < count; i++)
+			_filv[i] = &((fdi_node_t *) buf)[i];
+		
+		_filv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (fil_buf != NULL)
+			free(fil_buf);
+		
+		if (filv != NULL)
+			free(filv);
+		
+		filc = count;
+		fil_buf = (fdi_node_t *) buf;
+		filv = _filv;
+	}
 	
 	ipc_answer_0(rid, EOK);
