Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/amd64/Makefile.inc	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -58,4 +58,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
Index: boot/arch/arm32/loader/Makefile.common
===================================================================
--- boot/arch/arm32/loader/Makefile.common	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/arm32/loader/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -56,4 +56,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
Index: boot/arch/ia64/loader/Makefile.common
===================================================================
--- boot/arch/ia64/loader/Makefile.common	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/ia64/loader/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -56,4 +56,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
Index: boot/arch/mips32/loader/Makefile.common
===================================================================
--- boot/arch/mips32/loader/Makefile.common	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/mips32/loader/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -57,4 +57,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
Index: boot/arch/ppc32/loader/Makefile.common
===================================================================
--- boot/arch/ppc32/loader/Makefile.common	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/ppc32/loader/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -55,4 +55,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/tester/tester \
Index: boot/arch/sparc64/loader/Makefile.common
===================================================================
--- boot/arch/sparc64/loader/Makefile.common	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ boot/arch/sparc64/loader/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -54,4 +54,5 @@
 	$(USPACEDIR)/app/edit/edit \
 	$(USPACEDIR)/app/getvc/getvc \
+	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/trace/trace \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ uspace/Makefile	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -55,4 +55,5 @@
 	app/init \
 	app/getvc \
+	app/redir \
 	app/bdsh
 
Index: uspace/app/getvc/getvc.c
===================================================================
--- uspace/app/getvc/getvc.c	(revision 15b8e495a50e2460c084a79b7002f55d37a04f7e)
+++ uspace/app/getvc/getvc.c	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -71,10 +71,10 @@
 static task_id_t spawn(char *fname)
 {
-	char *argv[2];
+	char *args[2];
 	
-	argv[0] = fname;
-	argv[1] = NULL;
+	args[0] = fname;
+	args[1] = NULL;
 	
-	task_id_t id = task_spawn(fname, argv);
+	task_id_t id = task_spawn(fname, args);
 	
 	if (id == 0)
@@ -113,9 +113,13 @@
 	task_id_t id = spawn(argv[2]);
 	
-	task_exit_t texit;
-	int retval;
-	task_wait(id, &texit, &retval);
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return 0;
+	}
 	
-	return 0;
+	return -5;
 }
 
Index: uspace/app/redir/Makefile
===================================================================
--- uspace/app/redir/Makefile	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
+++ uspace/app/redir/Makefile	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/redir/Makefile.build
===================================================================
--- uspace/app/redir/Makefile.build	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
+++ uspace/app/redir/Makefile.build	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	redir.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/redir/Makefile.common
===================================================================
--- uspace/app/redir/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
+++ uspace/app/redir/Makefile.common	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = redir
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
+++ uspace/app/redir/redir.c	(revision c7dc8adcf6fd4f44525066e8405f51bb9f4817ee)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup redir Redirector
+ * @brief Redirect stdin/stdout/stderr.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <task.h>
+
+static void usage(void)
+{
+	printf("Usage: redirect [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ,,,]\n");
+}
+
+static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
+{
+	if (fclose(*stream))
+		return;
+	
+	*stream = NULL;
+	
+	int oldfd = open(path, flags);
+	if (oldfd < 0)
+		return;
+	
+	if (oldfd != fd) {
+		if (dup2(oldfd, fd) != fd)
+			return;
+		
+		if (close(oldfd))
+			return;
+	}
+	
+	*stream = fdopen(fd, mode);
+}
+
+static task_id_t spawn(int argc, char *argv[])
+{
+	char **args = (char *) calloc(argc + 1, sizeof(char *));
+	if (!args) {
+		printf("No memory available\n");
+		return 0;
+	}
+	
+	int i;
+	for (i = 0; i < argc; i++)
+		args[i] = argv[i];
+	
+	args[argc] = NULL;
+	
+	task_id_t id = task_spawn(argv[0], args);
+	
+	free(args);
+	
+	if (id == 0)
+		printf("Error spawning %s\n", argv[0]);
+	
+	return id;
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 3) {
+		usage();
+		return -1;
+	}
+	
+	int i;
+	for (i = 1; i < argc; i++) {
+		if (str_cmp(argv[i], "-i") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -2;
+			}
+			reopen(&stdin, 0, argv[i], O_RDONLY, "r");
+		} else if (str_cmp(argv[i], "-o") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -3;
+			}
+			reopen(&stdout, 1, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "-e") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -4;
+			}
+			reopen(&stderr, 2, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "--") == 0) {
+			i++;
+			break;
+		}
+	}
+	
+	if (i >= argc) {
+		usage();
+		return -5;
+	}
+	
+	/*
+	 * FIXME: fdopen() should actually detect that we are opening a console
+	 * and it should set line-buffering mode automatically.
+	 */
+	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+	
+	task_id_t id = spawn(argc - i, argv + i);
+	
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return retval;
+	}
+	
+	return -6;
+}
+
+/** @}
+ */
