[PATCH 05/20] app: Introduce libc support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Wed Mar 6 04:29:34 EST 2013


with dummy malloc or tslf malloc

and provide a pseudo libc to simplify application porting

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 apps/Kconfig               |   19 ++
 apps/Makefile              |   10 +-
 apps/include/appinfo.h     |    2 +
 apps/include/assert.h      |   32 +++
 apps/include/common.h      |   28 ++
 apps/include/ctype.h       |  100 +++++++
 apps/include/dirent.h      |   24 ++
 apps/include/errno.h       |   24 ++
 apps/include/fcntl.h       |   25 ++
 apps/include/getopt.h      |   76 ++++++
 apps/include/libc_config.h |  139 ++++++++++
 apps/include/limits.h      |   38 +++
 apps/include/malloc.h      |   30 +++
 apps/include/module.h      |    3 +
 apps/include/sections.h    |   29 ++
 apps/include/setjmp.h      |   25 ++
 apps/include/stddef.h      |    1 +
 apps/include/stdint.h      |   23 ++
 apps/include/stdio.h       |   70 +++++
 apps/include/stdlib.h      |   29 ++
 apps/include/string.h      |   53 ++++
 apps/include/sys/ioctl.h   |   12 +
 apps/include/sys/stat.h    |   14 +
 apps/include/sys/syscall.h |   14 +
 apps/include/sys/types.h   |   15 ++
 apps/include/time.h        |   27 ++
 apps/include/unistd.h      |   46 ++++
 apps/libc/Kconfig          |   25 ++
 apps/libc/Makefile         |   36 +++
 apps/libc/appinfo.c        |   35 +++
 apps/libc/dirent.c         |   59 +++++
 apps/libc/errno.c          |   19 ++
 apps/libc/fcntl.c          |   25 ++
 apps/libc/flags.c          |   76 ++++++
 apps/libc/getopt.c         |  127 +++++++++
 apps/libc/getopt_long.c    |  625 ++++++++++++++++++++++++++++++++++++++++++++
 apps/libc/malloc.c         |   50 ++++
 apps/libc/malloc.h         |    2 +
 apps/libc/private.h        |   18 ++
 apps/libc/stdio.c          |  275 +++++++++++++++++++
 apps/libc/stdlib.c         |   77 ++++++
 apps/libc/string.c         |  159 +++++++++++
 apps/libc/sys/Makefile     |    2 +
 apps/libc/sys/stat.c       |   25 ++
 apps/libc/syscalls.c       |  103 ++++++++
 apps/libc/time.c           |   41 +++
 apps/libc/unistd.c         |  108 ++++++++
 47 files changed, 2791 insertions(+), 4 deletions(-)
 create mode 100644 apps/include/assert.h
 create mode 100644 apps/include/common.h
 create mode 100644 apps/include/ctype.h
 create mode 100644 apps/include/dirent.h
 create mode 100644 apps/include/errno.h
 create mode 100644 apps/include/fcntl.h
 create mode 100644 apps/include/getopt.h
 create mode 100644 apps/include/libc_config.h
 create mode 100644 apps/include/limits.h
 create mode 100644 apps/include/malloc.h
 create mode 100644 apps/include/module.h
 create mode 100644 apps/include/sections.h
 create mode 100644 apps/include/setjmp.h
 create mode 100644 apps/include/stddef.h
 create mode 100644 apps/include/stdint.h
 create mode 100644 apps/include/stdio.h
 create mode 100644 apps/include/stdlib.h
 create mode 100644 apps/include/string.h
 create mode 100644 apps/include/sys/ioctl.h
 create mode 100644 apps/include/sys/stat.h
 create mode 100644 apps/include/sys/syscall.h
 create mode 100644 apps/include/sys/types.h
 create mode 100644 apps/include/time.h
 create mode 100644 apps/include/unistd.h
 create mode 100644 apps/libc/Kconfig
 create mode 100644 apps/libc/Makefile
 create mode 100644 apps/libc/appinfo.c
 create mode 100644 apps/libc/dirent.c
 create mode 100644 apps/libc/errno.c
 create mode 100644 apps/libc/fcntl.c
 create mode 100644 apps/libc/flags.c
 create mode 100644 apps/libc/getopt.c
 create mode 100644 apps/libc/getopt_long.c
 create mode 100644 apps/libc/malloc.c
 create mode 100644 apps/libc/malloc.h
 create mode 100644 apps/libc/private.h
 create mode 100644 apps/libc/stdio.c
 create mode 100644 apps/libc/stdlib.c
 create mode 100644 apps/libc/string.c
 create mode 100644 apps/libc/sys/Makefile
 create mode 100644 apps/libc/sys/stat.c
 create mode 100644 apps/libc/syscalls.c
 create mode 100644 apps/libc/time.c
 create mode 100644 apps/libc/unistd.c

diff --git a/apps/Kconfig b/apps/Kconfig
index 92899b5..4805c50 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -7,6 +7,8 @@ menuconfig APPLICATIONS
 
 if APPLICATIONS
 
+source "apps/libc/Kconfig"
+
 menu "memory layout"
 
 source "arch/$SRCARCH/apps/Kconfig"
@@ -16,6 +18,23 @@ config APP_MALLOC_SIZE
 	default 0x400000
 	prompt "malloc area size"
 
+config APP_PATH_MAX
+	hex
+	default 4096
+	prompt "path max"
+
+config APP_ENV_MAX
+	hex
+	default 4096
+	prompt "env var max size"
+
+config APP_FILE_MAX
+	int
+	default 128
+	prompt "maximun number of FILE"
+	help
+	  this does not include stdin, stderr, stdout
+
 endmenu
 
 endif
diff --git a/apps/Makefile b/apps/Makefile
index 65adfdc..c5c5c48 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -1,5 +1,9 @@
 
-CPPFLAGS += -I$(srctree)/apps/include
+APP_CPPFLAGS += -include $(srctree)/apps/include/libc_config.h
+APP_CPPFLAGS += -I$(srctree)/apps/include
+export APP_CPPFLAGS
+
+apps-$(CONFIG_APP_EXAMPLE) += example
 
 $(obj)/application: $(apps-lds) $(apps-y)
 
@@ -11,9 +15,7 @@ $(obj)/include/types.h: $(srctree)/include/types.h
 $(obj)/include/barebox/syscalls.h: $(srctree)/include/apps/syscalls.h
 	$(call cmd,shipped)
 
-$(obj)/include/errno.h: $(srctree)/include/asm-generic/errno.h
-	$(call cmd,shipped)
+obj-y += libc/
 
 barebox-app-header += $(obj)/include/types.h
-barebox-app-header += $(obj)/include/errno.h
 barebox-app-header += $(obj)/include/barebox/syscalls.h
diff --git a/apps/include/appinfo.h b/apps/include/appinfo.h
index 94409d7..ba95e65 100644
--- a/apps/include/appinfo.h
+++ b/apps/include/appinfo.h
@@ -55,4 +55,6 @@
 /* What your application does. */
 #define APP_DESCRIPTION(_description) APP_INFO(description, _description)
 
+void print_appinfo(void);
+
 #endif /* __APPINFO_H__ */
diff --git a/apps/include/assert.h b/apps/include/assert.h
new file mode 100644
index 0000000..a5d1bdd
--- /dev/null
+++ b/apps/include/assert.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ASSERT_H__
+#define __ASSERT_H__
+
+#define NDEBUG
+#if defined(NDEBUG) || defined(CONFIG_APP_NDEBUG)
+#define assert(expression)
+#else
+#define assert(expression) do {	\
+	if (expression) { \
+		fprintf(stderr, "%s:%d: ", str(expression), __FUNCTION__, __LINE__); \
+		exit(EXIT_FAILURE); \
+	} \
+} while(0)
+#endif
+
+#endif /* __ASSERT_H__ */
diff --git a/apps/include/common.h b/apps/include/common.h
new file mode 100644
index 0000000..6e991e8
--- /dev/null
+++ b/apps/include/common.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <stdio.h>
+
+#define BUG() do { \
+} while (0)
+
+#endif /* __COMMON_H__ */
diff --git a/apps/include/ctype.h b/apps/include/ctype.h
new file mode 100644
index 0000000..09eb175
--- /dev/null
+++ b/apps/include/ctype.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __CTYPE_H__
+#define __CTYPE_H__
+
+static inline int tolower(int c)
+{
+	return (c >= 'A' && c <= 'Z') ? (c + 32) : c;
+}
+
+static inline int toupper(int c)
+{
+	return (c >= 'a' && c <= 'z') ? (c - 32) : c;
+}
+
+static inline int toascii(int c)
+{
+	return ((unsigned char)c) & 0x7f;
+}
+
+static inline int isalpha(int c)
+{
+	return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+}
+
+static inline int isascii(int c)
+{
+	return (c >= 0 && c <= 127);
+}
+
+static inline int isblank(int c)
+{
+	return (c == ' ' || c == '\t');
+}
+
+static inline int iscntrl(int c)
+{
+	return (c <= 31 || c == 127);
+}
+
+static inline int isdigit(int c)
+{
+	return (c >= '0' && c <= '9');
+}
+
+static inline int isalnum(int c)
+{
+	return isalpha(c) || isdigit(c);
+}
+
+static inline int isgraph(int c)
+{
+	return (c >= 33 && c <= 126);
+}
+
+static inline int islower(int c)
+{
+	return (c >= 'a' && c <= 'z');
+}
+
+static inline int isprint(int c)
+{
+	return (c >= 32 && c <= 126);
+}
+
+static inline int isspace(int c)
+{
+	return (c == ' ' || (c >= '\t' && c <= '\r'));
+}
+
+static inline int ispunct(int c)
+{
+	return isprint(c) && !isspace(c) && !isalnum(c);
+}
+
+static inline int isupper(int c)
+{
+	return (c >= 'A' && c <= 'Z');
+}
+
+static inline int isxdigit(int c)
+{
+	return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
+}
+
+#endif /* __CTYPE_H__ */
diff --git a/apps/include/dirent.h b/apps/include/dirent.h
new file mode 100644
index 0000000..df26461
--- /dev/null
+++ b/apps/include/dirent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __DIRENT_H__
+#define __DIRENT_H__
+
+DIR *opendir(const char *name);
+struct dirent *readdir(DIR *dir);
+int closedir(DIR *dir);
+
+#endif /* __DIRENT_H__ */
diff --git a/apps/include/errno.h b/apps/include/errno.h
new file mode 100644
index 0000000..e7d5c90
--- /dev/null
+++ b/apps/include/errno.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ERRNO_H__
+#define __ERRNO_H__
+
+#include <asm-generic/errno.h>
+
+extern int errno;
+
+#endif /* __ERRNO_H__ */
diff --git a/apps/include/fcntl.h b/apps/include/fcntl.h
new file mode 100644
index 0000000..7bc8980
--- /dev/null
+++ b/apps/include/fcntl.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __FCNTL_H__
+#define __FCNTL_H__
+
+#include <barebox/fcntl.h>
+
+/* barebox does not handle the last optionnal arg */
+int open(const char *name, int flags, ...);
+
+#endif /* __FCNTL_H__ */
diff --git a/apps/include/getopt.h b/apps/include/getopt.h
new file mode 100644
index 0000000..b6c03d1
--- /dev/null
+++ b/apps/include/getopt.h
@@ -0,0 +1,76 @@
+/*	$OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $	*/
+/*	$NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $	*/
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <sys/types.h>
+
+/*
+ * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ */
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+struct option {
+	/* name of long option */
+	const char *name;
+	/*
+	 * one of no_argument, required_argument, and optional_argument:
+	 * whether option takes an argument
+	 */
+	int has_arg;
+	/* if not NULL, set *flag to val when option found */
+	int *flag;
+	/* if flag not NULL, value to set *flag to; else return value */
+	int val;
+};
+
+int	 getopt_long(int, char * const *, const char *,
+	    const struct option *, int *);
+int	 getopt_long_only(int, char * const *, const char *,
+	    const struct option *, int *);
+#ifndef _GETOPT_DEFINED_
+#define _GETOPT_DEFINED_
+int	 getopt(int, char * const *, const char *);
+int	 getsubopt(char **, char * const *, char **);
+
+extern   char *optarg;                  /* getopt(3) external variables */
+extern   int opterr;
+extern   int optind;
+extern   int optopt;
+extern   int optreset;
+extern   char *suboptarg;               /* getsubopt(3) external variable */
+#endif
+
+#endif /* !_GETOPT_H_ */
diff --git a/apps/include/libc_config.h b/apps/include/libc_config.h
new file mode 100644
index 0000000..752a417
--- /dev/null
+++ b/apps/include/libc_config.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __LIBC_CONFIG_H__
+#define __LIBC_CONFIG_H__
+
+#define LIBC_MAJOR	0
+#define LIBC_MINOR	1
+#define LIBC_SUBMINOR	0
+
+#define __str(x) #x
+#define str(x) __str(x)
+
+#define LIBC_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define LIBC_VERSION_CODE LIBC_VERSION(LIBC_MAJOR, LIBC_MINOR, LIBC_SUBMINOR)
+#define LIBC_VERSION_STRING str(LIBC_MAJOR) "." str(LIBC_MINOR) "." str(LIBC_SUBMINOR)
+
+/* dirent.h */
+#define LIBC_HAVE_DIRENT_H 1
+
+#define LIBC_HAVE_OPENDIR 1
+#define LIBC_HAVE_READDIR 1
+#define LIBC_HAVE_CLOSEDIR 1
+
+/* fcntl.h */
+#define LIBC_HAVE_FCNTL_H 1
+
+#define LIBC_HAVE_OPEN 1
+
+/* getopt.h */
+#define LIBC_HAVE_GETOPT_H 1
+
+#define LIBC_HAVE_GETOPT_LONG 1
+#define LIBC_HAVE_GETOPT_LONG_ONLY 1
+//#define LIBC_HAVE_GETOPT 1
+#define LIBC_HAVE_GETSUBOPT 1
+
+/* malloc.h */
+#define LIBC_HAVE_MALLOC_H 1
+
+#define LIBC_HAVE_MALLOC 1
+#define LIBC_HAVE_FREE 1
+#define LIBC_HAVE_REALLOC 1
+#define LIBC_HAVE_MEMALIGN 1
+#define LIBC_HAVE_CALLOC 1
+#define LIBC_HAVE_CFREE 1
+
+/* stdio.h */
+#define LIBC_HAVE_STDIO_H 1
+
+#define LIBC_HAVE_PUTCHAR 1
+#define LIBC_HAVE_GETCHAR 1
+#define LIBC_HAVE_PUTS 1
+
+#define LIBC_HAVE_FPRINTF 1
+#define LIBC_HAVE_VFPRINTF 1
+#define LIBC_HAVE_FPUTS 1
+#define LIBC_HAVE_FPUTC 1
+#define LIBC_HAVE_FOPEN 1
+#define LIBC_HAVE_FCLOSE 1
+#define LIBC_HAVE_FREAD 1
+#define LIBC_HAVE_FWRITE 1
+#define LIBC_HAVE_FSEEK 1
+
+#define LIBC_HAVE_PRINTF 1
+#define LIBC_HAVE_VPRINTF 1
+#define LIBC_HAVE_SPRINTF 1
+#define LIBC_HAVE_SNPRINTF 1
+#define LIBC_HAVE_VSPRINTF 1
+#define LIBC_HAVE_ASPRINTF 1
+#define LIBC_HAVE_VASPRINTF 1
+#define LIBC_HAVE_VSNPRINTF 1
+#define LIBC_HAVE_VSCNPRINTF 1
+
+/* barebox API */
+#define LIBC_HAVE_BAREBOX_API 1
+
+#define LIBC_HAVE_EPUTC 1
+#define LIBC_HAVE_EPUTS 1
+#define LIBC_HAVE_TSTC 1
+#define LIBC_HAVE_FLUSH 1
+#define LIBC_HAVE_ITOA 1
+
+/* stdlib.h */
+#define LIBC_HAVE_STDLIB_H 1
+
+#define LIBC_HAVE_GETENV 1
+#define LIBC_HAVE_EXIT 1
+
+/* unistd.h */
+#define LIBC_HAVE_UNISTD_H 1
+
+#define LIBC_HAVE_READ 1
+#define LIBC_HAVE_WRITE 1
+#define LIBC_HAVE_CLOSE 1
+#define LIBC_HAVE_STAT 1
+#define LIBC_HAVE_LSTAT 1
+
+#define LIBC_HAVE_LSEEK 1
+#define LIBC_HAVE_UNLINK 1
+#define LIBC_HAVE_SYMLINK 1
+#define LIBC_HAVE_READLINK 1
+#define LIBC_HAVE_RMDIR 1
+#define LIBC_HAVE_GETCWD 1
+#define LIBC_HAVE_GET_CURRENT_DIR_NAME 1
+#define LIBC_HAVE_CHDIR 1
+#define LIBC_HAVE_USLEEP 1
+
+#define LIBC_HAVE_GETOPT 1
+
+/* sys/ioctl.h */
+#define LIBC_HAVE_SYS_IOCTL_H 1
+
+#define LIBC_HAVE_IOCTL 1
+
+/* sys/stat.h */
+#define LIBC_HAVE_SYS_STAT_H 1
+
+#define LIBC_HAVE_MKDIR 1
+
+/* sys/syscall.h */
+#define LIBC_HAVE_SYS_SYSCALL_H 1
+
+#define LIBC_HAVE_SYSCALL 1
+
+#endif /* __LIBC_CONFIG_H__ */
diff --git a/apps/include/limits.h b/apps/include/limits.h
new file mode 100644
index 0000000..3625d07
--- /dev/null
+++ b/apps/include/limits.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __LIMITS_H__
+#define __LIMITS_H__
+
+#include <sys/types.h>
+
+#define USHORT_MAX	((u16)(~0U))
+#define SHORT_MAX	((s16)(USHORT_MAX>>1))
+#define SHORT_MIN	(-SHORT_MAX - 1)
+#define INT_MAX		((int)(~0U>>1))
+#define INT_MIN		(-INT_MAX - 1)
+#define UINT_MAX	(~0U)
+#define LONG_MAX	((long)(~0UL>>1))
+#define LONG_MIN	(-LONG_MAX - 1)
+#define ULONG_MAX	(~0UL)
+#define LLONG_MAX	((long long)(~0ULL>>1))
+#define LLONG_MIN	(-LLONG_MAX - 1)
+#define ULLONG_MAX	(~0ULL)
+
+#define PATH_MAX	CONFIG_APP_PATH_MAX
+#define ENV_MAX		CONFIG_APP_ENV_MAX
+
+#endif /* __LIMITS_H__ */
diff --git a/apps/include/malloc.h b/apps/include/malloc.h
new file mode 100644
index 0000000..0017419
--- /dev/null
+++ b/apps/include/malloc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __MALLOC_H
+#define __MALLOC_H
+
+#include <types.h>
+
+void* malloc(size_t);
+void free(void*);
+void* realloc(void*, size_t);
+void* memalign(size_t, size_t);
+void* calloc(size_t, size_t);
+void cfree(void*);
+
+#endif
+
diff --git a/apps/include/module.h b/apps/include/module.h
new file mode 100644
index 0000000..c62d65b
--- /dev/null
+++ b/apps/include/module.h
@@ -0,0 +1,3 @@
+#define EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL(sym)
+
diff --git a/apps/include/sections.h b/apps/include/sections.h
new file mode 100644
index 0000000..fc262a6
--- /dev/null
+++ b/apps/include/sections.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef _APPS_GENERIC_SECTIONS_H_
+#define _APPS_GENERIC_SECTIONS_H_
+
+extern char _text[], _stext[], _etext[];
+extern char __bss_start[], __bss_stop[];
+extern char _sdata[], _edata[];
+extern char _end[];
+extern void *_barebox_app_image_size;
+extern char __appinfo_start[], __appinfo_end[];
+
+#define _barebox_app_image_size	(unsigned int)&_barebox_app_image_size
+
+#endif /* _APPS_GENERIC_SECTIONS_H_ */
diff --git a/apps/include/setjmp.h b/apps/include/setjmp.h
new file mode 100644
index 0000000..ff9dd8d
--- /dev/null
+++ b/apps/include/setjmp.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __SETJMP_H__
+#define __SETJMP_H__
+
+#include <arch/setjmp.h>
+
+int setjmp(jmp_buf);
+void __attribute__((noreturn)) longjmp(jmp_buf, int);
+
+#endif /* __SETJMP_H__ */
diff --git a/apps/include/stddef.h b/apps/include/stddef.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/apps/include/stddef.h
@@ -0,0 +1 @@
+
diff --git a/apps/include/stdint.h b/apps/include/stdint.h
new file mode 100644
index 0000000..f5ad912
--- /dev/null
+++ b/apps/include/stdint.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDINT_H__
+#define __STDINT_H__
+
+#define INT64_C(c) (c ## LL)
+#define UINT64_C(c) (c ## ULL)
+
+#endif /* __STDINT_H__ */
diff --git a/apps/include/stdio.h b/apps/include/stdio.h
new file mode 100644
index 0000000..32a7d25
--- /dev/null
+++ b/apps/include/stdio.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDIO_H__
+#define __STDIO_H__
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+#define EXIT_FAILURE	1
+#define EXIT_SUCCESS	0
+#define EOF -1
+
+void putchar(char c);
+int getchar(void);
+int puts(const char *str);
+
+struct __file;
+typedef struct __file FILE;
+
+extern FILE stdin;
+extern FILE stdout;
+extern FILE stderr;
+
+#define stdin (&stdin)
+#define stdout (&stdout)
+#define stderr (&stderr)
+
+int fprintf(FILE *f, const char *fmt, ...) __attribute__ ((format(__printf__, 2, 3)));
+int vfprintf(FILE *f, const char *fmt, va_list args);
+int fputs(const char *s, FILE *f);
+int fputc(int c, FILE *f);
+FILE *fopen(const char *path, const char *mode);
+int fclose(FILE *f);
+size_t fread(void *buf, size_t size, size_t nb, FILE *f);
+size_t fwrite(const void *buf, size_t size, size_t nb, FILE *f);
+int fseek(FILE *stream, long offset, int whence);
+
+/* barebox API */
+void eputc(char c);
+int eputs(const char *str);
+int tstc(void);
+int flush(int fd);
+char* itoa(int i);
+
+static int printf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2)));
+static inline int printf(const char *fmt, ...)
+{
+	return 0;
+}
+
+static inline int vprintf(const char *fmt, va_list args)
+{
+	return 0;
+}
+
+#endif /* __STDIO_H__ */
diff --git a/apps/include/stdlib.h b/apps/include/stdlib.h
new file mode 100644
index 0000000..7ae78ad
--- /dev/null
+++ b/apps/include/stdlib.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDLIB_H__
+#define __STDLIB_H__
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+char *getenv(const char *name);
+void exit(int num);
+int atoi(const char *s);
+long atol(const char *s);
+long long atoll(const char *s);
+
+#endif /* __STDLIB_H__ */
diff --git a/apps/include/string.h b/apps/include/string.h
new file mode 100644
index 0000000..95b94a3
--- /dev/null
+++ b/apps/include/string.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STRING_H
+#define __STRING_H
+
+#include <types.h>
+
+extern char * ___strtok;
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern char * strsep(char **,const char *);
+extern size_t strspn(const char *,const char *);
+
+extern char * strcpy(char *,const char *);
+extern char * strncpy(char *,const char *, size_t);
+size_t strlcpy(char *, const char *, size_t);
+extern char * strcat(char *, const char *);
+extern char * strncat(char *, const char *, size_t);
+extern int strcmp(const char *,const char *);
+extern int strncmp(const char *,const char *,size_t);
+extern char * strchr(const char *,int);
+extern char * strrchr(const char *,int);
+extern char * strstr(const char *,const char *);
+extern size_t strlen(const char *);
+extern size_t strnlen(const char *,size_t);
+extern char * strdup(const char *);
+extern char * strswab(const char *);
+
+extern void * memset(void *,int,size_t);
+extern void * memcpy(void *,const void *,size_t);
+extern void * memmove(void *,const void *,size_t);
+extern void * memscan(void *,int,size_t);
+extern int memcmp(const void *,const void *,size_t);
+extern void * memchr(const void *,int,size_t);
+extern char * skip_spaces(const char *);
+
+extern char *strim(char *);
+
+#endif /* __STRING_H */
diff --git a/apps/include/sys/ioctl.h b/apps/include/sys/ioctl.h
new file mode 100644
index 0000000..58e9760
--- /dev/null
+++ b/apps/include/sys/ioctl.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_IOCTL_H__
+#define __SYS_IOCTL_H__
+
+int ioctl(int fd, int request, void *buf);
+
+#endif /* __SYS_IOCTL_H__ */
diff --git a/apps/include/sys/stat.h b/apps/include/sys/stat.h
new file mode 100644
index 0000000..c1cecf9
--- /dev/null
+++ b/apps/include/sys/stat.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_STAT_H__
+#define __SYS_STAT_H__
+
+#include <linux/stat.h>
+
+int mkdir(const char *path, mode_t mode);
+
+#endif /* __SYS_STAT_H__ */
diff --git a/apps/include/sys/syscall.h b/apps/include/sys/syscall.h
new file mode 100644
index 0000000..4ffb09a
--- /dev/null
+++ b/apps/include/sys/syscall.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_SYSCALL_H__
+#define __SYS_SYSCALL_H__
+
+#include <errno.h>
+
+int syscall(int num, ...);
+
+#endif /* __SYS_SYSCALL_H__ */
diff --git a/apps/include/sys/types.h b/apps/include/sys/types.h
new file mode 100644
index 0000000..ec48b2e
--- /dev/null
+++ b/apps/include/sys/types.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_TYPES_H__
+#define __SYS_TYPES_H__
+
+#include <linux/types.h>
+#include <barebox/types.h>
+
+typedef unsigned int useconds_t;
+
+#endif /* __SYS_TYPES_H__ */
diff --git a/apps/include/time.h b/apps/include/time.h
new file mode 100644
index 0000000..d067e25
--- /dev/null
+++ b/apps/include/time.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __TIME_H__
+#define __TIME_H__
+
+struct timespec {
+	time_t	tv_sec;		/* seconds */
+	long	tv_nsec;	/* nanoseconds */
+};
+
+int nanosleep(const struct timespec *req, struct timespec *rem);
+
+#endif /* __TIME_H__ */
diff --git a/apps/include/unistd.h b/apps/include/unistd.h
new file mode 100644
index 0000000..dbd8cef
--- /dev/null
+++ b/apps/include/unistd.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __UNISTD_H__
+#define __UNISTD_H__
+
+struct stat;
+
+ssize_t read(int fd, void *buf, size_t count);
+ssize_t write(int fd, const void *buf, size_t count);
+int close(int fd);
+int stat(const char *path, struct stat *buf);
+int lstat(const char *path, struct stat *buf);
+
+#define SEEK_SET        1
+#define SEEK_CUR        2
+#define SEEK_END        3
+
+loff_t lseek(int fd, loff_t offset, int whence);
+int unlink(const char *pathname);
+int symlink(const char *pathname, const char *newpath);
+ssize_t readlink(const char *path, char *buf, size_t bufsiz);
+int rmdir(const char *path);
+char *getcwd(char *buf, size_t size);
+char *get_current_dir_name(void);
+int chdir(const char *path);
+int usleep(unsigned int usec);
+
+int getopt(int argc, char * const argv[], const char *optstring);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+#endif /* __UNISTD_H__ */
diff --git a/apps/libc/Kconfig b/apps/libc/Kconfig
new file mode 100644
index 0000000..b9478b5
--- /dev/null
+++ b/apps/libc/Kconfig
@@ -0,0 +1,25 @@
+menu "libc"
+
+choice
+	prompt "malloc implementation"
+
+config APPS_MALLOC_TLSF
+	bool "tlsf"
+
+config APPS_MALLOC_DUMMY
+	bool "dummy malloc"
+	help
+	  select this option to use a dummy malloc implementation. With this
+	  memory is never freed. This is suitable for well tested noninteractive
+	  environments only.
+
+endchoice
+
+config APP_GETOPT_LONG_AS_GETOPT
+	bool "use getopt_long as getopt"
+
+config APP_PRINTF_STACK_SIZE
+	hex "printf stack size"
+	default 0x1000
+
+endmenu
diff --git a/apps/libc/Makefile b/apps/libc/Makefile
new file mode 100644
index 0000000..844ea9b
--- /dev/null
+++ b/apps/libc/Makefile
@@ -0,0 +1,36 @@
+app-y += appinfo.o
+app-y += dirent.o
+app-y += errno.o
+app-y += fcntl.o
+app-y += flags.o
+ifneq ($(CONFIG_APP_GETOPT_LONG_AS_GETOPT),y)
+app-y += getopt.o
+endif
+app-y += getopt_long.o
+app-y += malloc.o
+app-y += stdio.o
+app-y += stdlib.o
+app-y += syscalls.o
+app-y += unistd.o
+app-$(CONFIG_APPS_MALLOC_DUMMY) += dummy_malloc.o
+app-$(CONFIG_APPS_MALLOC_TLSF) += tlsf_malloc.o tlsf.o
+app-y += string.o
+obj-y += sys/
+app-y += time.o
+
+$(obj)/dummy_malloc.c: $(srctree)/common/dummy_malloc.c FORCE
+	$(call cmd,shipped)
+
+$(obj)/tlsf.c: $(srctree)/common/tlsf.c $(obj)/tlsfbits.h FORCE
+	$(call cmd,shipped)
+
+$(obj)/tlsf_malloc.c: $(srctree)/common/tlsf_malloc.c $(obj)/tlsf.h FORCE
+	$(call cmd,shipped)
+
+$(obj)/tlsfbits.h: $(srctree)/common/tlsfbits.h FORCE
+	$(call cmd,shipped)
+
+$(obj)/tlsf.h: $(srctree)/include/tlsf.h FORCE
+	$(call cmd,shipped)
+
+$(obj)/app-malloc.o: $(obj)/tlsfbits.h
diff --git a/apps/libc/appinfo.c b/apps/libc/appinfo.c
new file mode 100644
index 0000000..7eff526
--- /dev/null
+++ b/apps/libc/appinfo.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sections.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <appinfo.h>
+#include <libc_config.h>
+
+void print_appinfo(void)
+{
+	char *info = (char*)&__appinfo_start;
+
+	for (; info < (char*)&__appinfo_end; info += strlen(info) + 1)
+		printf("%s\n", info);
+}
+
+APP_INFO(libc, "barebox libc")
+APP_INFO(libc_author, "Jean-Christophe PLANGIOL-VILLARD <plagnioj at jcrosoft.com>")
+APP_INFO(libc_license, "GPLv2 + exception")
+APP_INFO(libc_version, LIBC_VERSION_STRING)
diff --git a/apps/libc/dirent.c b/apps/libc/dirent.c
new file mode 100644
index 0000000..b2a78ad
--- /dev/null
+++ b/apps/libc/dirent.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <errno.h>
+
+DIR *opendir(const char *name)
+{
+	DIR *d = malloc(sizeof(DIR));
+
+	if (!d)
+		return NULL;
+
+	if (syscall(SYS_opendir, d, name))
+		goto err;
+
+	return d;
+err:
+	free(d);
+	return NULL;
+}
+
+static struct dirent d_read;
+
+struct dirent *readdir(DIR *dir)
+{
+	if (!dir)
+		return NULL;
+
+	if (syscall(SYS_readdir, dir, &d_read))
+		return NULL;
+
+	return &d_read;
+}
+
+int closedir(DIR *dir)
+{
+	if (!dir)
+		return -EINVAL;
+
+	return syscall(SYS_closedir, dir);
+}
diff --git a/apps/libc/errno.c b/apps/libc/errno.c
new file mode 100644
index 0000000..640d09c
--- /dev/null
+++ b/apps/libc/errno.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <errno.h>
+
+int errno;
diff --git a/apps/libc/fcntl.c b/apps/libc/fcntl.c
new file mode 100644
index 0000000..da26955
--- /dev/null
+++ b/apps/libc/fcntl.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+/* barebox does not handle the last optionnal arg */
+int open(const char *name, int flags, ...)
+{
+	return syscall(SYS_open, name, flags);
+}
diff --git a/apps/libc/flags.c b/apps/libc/flags.c
new file mode 100644
index 0000000..4d4487b
--- /dev/null
+++ b/apps/libc/flags.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int __str_to_flags(const char *mode, int *flag)
+{
+	int _mode;
+	int opt;
+
+	switch (*mode++) {
+	case 'r':
+		_mode = O_RDONLY;
+		opt = 0;
+		break;
+
+	case 'w':
+		_mode = O_WRONLY;
+		opt = O_CREAT | O_TRUNC;
+		break;
+
+	case 'a':
+		_mode = O_WRONLY;
+		opt = O_CREAT | O_APPEND;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* binary ingnore it */
+	if (*mode == 'b')
+		mode++;
+
+	/* read/write */
+	if (*mode == '+') {
+		mode++;
+		_mode = O_RDWR;
+	}
+
+	/* binary ingnore it */
+	if (*mode == 'b')
+		mode++;
+
+	/*
+	 * barebox does not supprot it
+	 * just check we are not it RO mode
+	 */
+	if (*mode == 'x') {
+		mode++;
+		if (_mode == O_RDONLY)
+			return -EINVAL;
+	}
+
+	/* barebox does not support it */
+	if (*mode == 'e')
+		mode++;
+
+	*flag = _mode | opt;
+	return 0;
+}
diff --git a/apps/libc/getopt.c b/apps/libc/getopt.c
new file mode 100644
index 0000000..b445af8
--- /dev/null
+++ b/apps/libc/getopt.c
@@ -0,0 +1,127 @@
+/*	$NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $	*/
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "private.h"
+
+int	opterr = 1,		/* if error message should be printed */
+	optind = 1,		/* index into parent argv vector */
+	optopt,			/* character checked for validity */
+	optreset;		/* reset getopt */
+char	*optarg;		/* argument associated with option */
+
+#define	BADCH	(int)'?'
+#define	BADARG	(int)':'
+#define	EMSG	""
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+	int nargc;
+	char * const nargv[];
+	const char *ostr;
+{
+	static char *place = EMSG;		/* option letter processing */
+	char *oli;				/* option letter list index */
+
+	if (optreset || *place == 0) {		/* update scanning pointer */
+		optreset = 0;
+		place = nargv[optind];
+		if (optind >= nargc || *place++ != '-') {
+			/* Argument is absent or is not an option */
+			place = EMSG;
+			return (-1);
+		}
+		optopt = *place++;
+		if (optopt == '-' && *place == 0) {
+			/* "--" => end of options */
+			++optind;
+			place = EMSG;
+			return (-1);
+		}
+		if (optopt == 0) {
+			/* Solitary '-', treat as a '-' option
+			   if the program (eg su) is looking for it. */
+			place = EMSG;
+			if (strchr(ostr, '-') == NULL)
+				return (-1);
+			optopt = '-';
+		}
+	} else
+		optopt = *place++;
+
+	/* See if option letter is one the caller wanted... */
+	if (optopt == ':' || (oli = (char*)strchr(ostr, optopt)) == NULL) {
+		if (*place == 0)
+			++optind;
+		if (opterr && *ostr != ':')
+			(void)fprintf(stderr,
+			    "%s: illegal option -- %c\n", __progname,
+			    optopt);
+		return (BADCH);
+	}
+
+	/* Does this option need an argument? */
+	if (oli[1] != ':') {
+		/* don't need argument */
+		optarg = NULL;
+		if (*place == 0)
+			++optind;
+	} else {
+		/* Option-argument is either the rest of this argument or the
+		   entire next argument. */
+		if (*place)
+			optarg = place;
+		else if (nargc > ++optind)
+			optarg = nargv[optind];
+		else {
+			/* option-argument absent */
+			place = EMSG;
+			if (*ostr == ':')
+				return (BADARG);
+			if (opterr)
+				(void)fprintf(stderr,
+				    "%s: option requires an argument -- %c\n",
+				    __progname, optopt);
+			return (BADCH);
+		}
+		place = EMSG;
+		++optind;
+	}
+	return (optopt);			/* return option letter */
+}
diff --git a/apps/libc/getopt_long.c b/apps/libc/getopt_long.c
new file mode 100644
index 0000000..ed7add7
--- /dev/null
+++ b/apps/libc/getopt_long.c
@@ -0,0 +1,625 @@
+/*	$OpenBSD: getopt_long.c,v 1.22 2006/10/04 21:29:04 jmc Exp $	*/
+/*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*/
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller at courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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 <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "private.h"
+
+#define GNU_COMPATIBLE		/* Be more compatible, configure's use us! */
+
+#ifdef CONFIG_APP_GETOPT_LONG_AS_GETOPT	/* we prefer to keep our getopt(3) */
+#define	REPLACE_GETOPT		/* use this getopt as the system getopt(3) */
+#endif
+
+#ifdef REPLACE_GETOPT
+int	opterr = 1;		/* if error message should be printed */
+int	optind = 1;		/* index into parent argv vector */
+int	optopt = '?';		/* character checked for validity */
+int	optreset;		/* reset getopt */
+char    *optarg;		/* argument associated with option */
+#endif
+
+#define PRINT_ERROR	((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */
+#define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY	0x04	/* operate as getopt_long_only */
+
+/* return values */
+#define	BADCH		(int)'?'
+#define	BADARG		((*options == ':') ? (int)':' : (int)'?')
+#define	INORDER 	(int)1
+
+#define	EMSG		""
+
+#ifdef GNU_COMPATIBLE
+#define NO_PREFIX	(-1)
+#define D_PREFIX	0
+#define DD_PREFIX	1
+#define W_PREFIX	2
+#endif
+
+static int getopt_internal(int, char * const *, const char *,
+			   const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+			      const struct option *, int *, int, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
+#ifdef GNU_COMPATIBLE
+static int dash_prefix = NO_PREFIX;
+static const char gnuoptchar[] = "invalid option -- %c";
+
+static const char recargstring[] = "option `%s%s' requires an argument";
+static const char ambig[] = "option `%s%.*s' is ambiguous";
+static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
+static const char illoptstring[] = "unrecognized option `%s%s'";
+#else
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptstring[] = "unknown option -- %s";
+#endif
+
+void warnx(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+
+	(void)fprintf(stderr, "%s: ", __progname);
+	if (fmt != NULL)
+		(void)vfprintf(stderr, fmt, ap);
+	(void)fprintf(stderr, "\n");
+	va_end(ap);
+}
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+	int c;
+
+	c = a % b;
+	while (c != 0) {
+		a = b;
+		b = c;
+		c = a % b;
+	}
+
+	return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+	char * const *nargv)
+{
+	int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+	char *swap;
+
+	/*
+	 * compute lengths of blocks and number and size of cycles
+	 */
+	nnonopts = panonopt_end - panonopt_start;
+	nopts = opt_end - panonopt_end;
+	ncycle = gcd(nnonopts, nopts);
+	cyclelen = (opt_end - panonopt_start) / ncycle;
+
+	for (i = 0; i < ncycle; i++) {
+		cstart = panonopt_end+i;
+		pos = cstart;
+		for (j = 0; j < cyclelen; j++) {
+			if (pos >= panonopt_end)
+				pos -= nnonopts;
+			else
+				pos += nopts;
+			swap = nargv[pos];
+			/* LINTED const cast */
+			((char **) nargv)[pos] = nargv[cstart];
+			/* LINTED const cast */
+			((char **)nargv)[cstart] = swap;
+		}
+	}
+}
+
+/*
+ * parse_long_options --
+ *	Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int short_too, int flags)
+{
+	char *current_argv, *has_equal;
+#ifdef GNU_COMPATIBLE
+	char *current_dash;
+#endif
+	size_t current_argv_len;
+	int i, match, exact_match, second_partial_match;
+
+	current_argv = place;
+#ifdef GNU_COMPATIBLE
+	switch (dash_prefix) {
+		case D_PREFIX:
+			current_dash = "-";
+			break;
+		case DD_PREFIX:
+			current_dash = "--";
+			break;
+		case W_PREFIX:
+			current_dash = "-W ";
+			break;
+		default:
+			current_dash = "";
+			break;
+	}
+#endif
+	match = -1;
+	exact_match = 0;
+	second_partial_match = 0;
+
+	optind++;
+
+	if ((has_equal = strchr(current_argv, '=')) != NULL) {
+		/* argument found (--option=arg) */
+		current_argv_len = has_equal - current_argv;
+		has_equal++;
+	} else
+		current_argv_len = strlen(current_argv);
+
+	for (i = 0; long_options[i].name; i++) {
+		/* find matching long option */
+		if (strncmp(current_argv, long_options[i].name,
+		    current_argv_len))
+			continue;
+
+		if (strlen(long_options[i].name) == current_argv_len) {
+			/* exact match */
+			match = i;
+			exact_match = 1;
+			break;
+		}
+		/*
+		 * If this is a known short option, don't allow
+		 * a partial match of a single character.
+		 */
+		if (short_too && current_argv_len == 1)
+			continue;
+
+		if (match == -1)        /* first partial match */
+			match = i;
+		else if ((flags & FLAG_LONGONLY) ||
+			 long_options[i].has_arg !=
+			     long_options[match].has_arg ||
+			 long_options[i].flag != long_options[match].flag ||
+			 long_options[i].val != long_options[match].val)
+			second_partial_match = 1;
+	}
+	if (!exact_match && second_partial_match) {
+		/* ambiguous abbreviation */
+		if (PRINT_ERROR)
+			warnx(ambig,
+#ifdef GNU_COMPATIBLE
+			     current_dash,
+#endif
+			     (int)current_argv_len,
+			     current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (match != -1) {		/* option found */
+		if (long_options[match].has_arg == no_argument
+		    && has_equal) {
+			if (PRINT_ERROR)
+				warnx(noarg,
+#ifdef GNU_COMPATIBLE
+				     current_dash,
+#endif
+				     (int)current_argv_len,
+				     current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+#ifdef GNU_COMPATIBLE
+			return (BADCH);
+#else
+			return (BADARG);
+#endif
+		}
+		if (long_options[match].has_arg == required_argument ||
+		    long_options[match].has_arg == optional_argument) {
+			if (has_equal)
+				optarg = has_equal;
+			else if (long_options[match].has_arg ==
+			    required_argument) {
+				/*
+				 * optional argument doesn't use next nargv
+				 */
+				optarg = nargv[optind++];
+			}
+		}
+		if ((long_options[match].has_arg == required_argument)
+		    && (optarg == NULL)) {
+			/*
+			 * Missing argument; leading ':' indicates no error
+			 * should be generated.
+			 */
+			if (PRINT_ERROR)
+				warnx(recargstring,
+#ifdef GNU_COMPATIBLE
+				    current_dash,
+#endif
+				    current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			--optind;
+			return (BADARG);
+		}
+	} else {			/* unknown option */
+		if (short_too) {
+			--optind;
+			return (-1);
+		}
+		if (PRINT_ERROR)
+			warnx(illoptstring,
+#ifdef GNU_COMPATIBLE
+			      current_dash,
+#endif
+			      current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (idx)
+		*idx = match;
+	if (long_options[match].flag) {
+		*long_options[match].flag = long_options[match].val;
+		return (0);
+	} else
+		return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ *	Parse argc/argv argument vector.  Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int flags)
+{
+	char *oli;				/* option letter list index */
+	int optchar, short_too;
+	int posixly_correct;	/* no static, can be changed on the fly */
+
+	if (options == NULL)
+		return (-1);
+
+	/*
+	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
+	 * string begins with a '+'.
+	 */
+	posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+#ifdef GNU_COMPATIBLE
+	if (*options == '-')
+		flags |= FLAG_ALLARGS;
+	else if (posixly_correct || *options == '+')
+		flags &= ~FLAG_PERMUTE;
+#else
+	if (posixly_correct || *options == '+')
+		flags &= ~FLAG_PERMUTE;
+	else if (*options == '-')
+		flags |= FLAG_ALLARGS;
+#endif
+	if (*options == '+' || *options == '-')
+		options++;
+
+	/*
+	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
+	 * XXX using optreset.  Work around this braindamage.
+	 */
+	if (optind == 0)
+		optind = optreset = 1;
+
+	optarg = NULL;
+	if (optreset)
+		nonopt_start = nonopt_end = -1;
+start:
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc) {          /* end of argument vector */
+			place = EMSG;
+			if (nonopt_end != -1) {
+				/* do permutation, if we have to */
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			else if (nonopt_start != -1) {
+				/*
+				 * If we skipped non-options, set optind
+				 * to the first of them.
+				 */
+				optind = nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+		if (*(place = nargv[optind]) != '-' ||
+#ifdef GNU_COMPATIBLE
+		    place[1] == '\0') {
+#else
+		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
+#endif
+			place = EMSG;		/* found non-option */
+			if (flags & FLAG_ALLARGS) {
+				/*
+				 * GNU extension:
+				 * return non-option as argument to option 1
+				 */
+				optarg = nargv[optind++];
+				return (INORDER);
+			}
+			if (!(flags & FLAG_PERMUTE)) {
+				/*
+				 * If no permutation wanted, stop parsing
+				 * at first non-option.
+				 */
+				return (-1);
+			}
+			/* do permutation */
+			if (nonopt_start == -1)
+				nonopt_start = optind;
+			else if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				nonopt_start = optind -
+				    (nonopt_end - nonopt_start);
+				nonopt_end = -1;
+			}
+			optind++;
+			/* process next argument */
+			goto start;
+		}
+		if (nonopt_start != -1 && nonopt_end == -1)
+			nonopt_end = optind;
+
+		/*
+		 * If we have "-" do nothing, if "--" we are done.
+		 */
+		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+			optind++;
+			place = EMSG;
+			/*
+			 * We found an option (--), so if we skipped
+			 * non-options, we have to permute.
+			 */
+			if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+	}
+
+	/*
+	 * Check long options if:
+	 *  1) we were passed some
+	 *  2) the arg is not just "-"
+	 *  3) either the arg starts with -- we are getopt_long_only()
+	 */
+	if (long_options != NULL && place != nargv[optind] &&
+	    (*place == '-' || (flags & FLAG_LONGONLY))) {
+		short_too = 0;
+#ifdef GNU_COMPATIBLE
+		dash_prefix = D_PREFIX;
+#endif
+		if (*place == '-') {
+			place++;		/* --foo long option */
+#ifdef GNU_COMPATIBLE
+			dash_prefix = DD_PREFIX;
+#endif
+		} else if (*place != ':' && strchr(options, *place) != NULL)
+			short_too = 1;		/* could be short option too */
+
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, short_too, flags);
+		if (optchar != -1) {
+			place = EMSG;
+			return (optchar);
+		}
+	}
+
+	if ((optchar = (int)*place++) == (int)':' ||
+	    (optchar == (int)'-' && *place != '\0') ||
+	    (oli = (char*)strchr(options, optchar)) == NULL) {
+		/*
+		 * If the user specified "-" and  '-' isn't listed in
+		 * options, return -1 (non-option) as per POSIX.
+		 * Otherwise, it is an unknown option character (or ':').
+		 */
+		if (optchar == (int)'-' && *place == '\0')
+			return (-1);
+		if (!*place)
+			++optind;
+#ifdef GNU_COMPATIBLE
+		if (PRINT_ERROR)
+			warnx(posixly_correct ? illoptchar : gnuoptchar,
+			      optchar);
+#else
+		if (PRINT_ERROR)
+			warnx(illoptchar, optchar);
+#endif
+		optopt = optchar;
+		return (BADCH);
+	}
+	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+		/* -W long-option */
+		if (*place)			/* no space */
+			/* NOTHING */;
+		else if (++optind >= nargc) {	/* no arg */
+			place = EMSG;
+			if (PRINT_ERROR)
+				warnx(recargchar, optchar);
+			optopt = optchar;
+			return (BADARG);
+		} else				/* white space */
+			place = nargv[optind];
+#ifdef GNU_COMPATIBLE
+		dash_prefix = W_PREFIX;
+#endif
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, 0, flags);
+		place = EMSG;
+		return (optchar);
+	}
+	if (*++oli != ':') {			/* doesn't take argument */
+		if (!*place)
+			++optind;
+	} else {				/* takes (optional) argument */
+		optarg = NULL;
+		if (*place)			/* no white space */
+			optarg = place;
+		else if (oli[1] != ':') {	/* arg not optional */
+			if (++optind >= nargc) {	/* no arg */
+				place = EMSG;
+				if (PRINT_ERROR)
+					warnx(recargchar, optchar);
+				optopt = optchar;
+				return (BADARG);
+			} else
+				optarg = nargv[optind];
+		}
+		place = EMSG;
+		++optind;
+	}
+	/* dump back option letter */
+	return (optchar);
+}
+
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+	/*
+	 * We don't pass FLAG_PERMUTE to getopt_internal() since
+	 * the BSD getopt(3) (unlike GNU) has never done this.
+	 *
+	 * Furthermore, since many privileged programs call getopt()
+	 * before dropping privileges it makes sense to keep things
+	 * as simple (and bug-free) as possible.
+	 */
+	return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+ * getopt_long --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE|FLAG_LONGONLY));
+}
diff --git a/apps/libc/malloc.c b/apps/libc/malloc.c
new file mode 100644
index 0000000..ab4b8b5
--- /dev/null
+++ b/apps/libc/malloc.c
@@ -0,0 +1,50 @@
+#include <malloc.h>
+#include <types.h>
+#include <string.h>
+
+#include "malloc.h"
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static unsigned long malloc_start;
+static unsigned long malloc_end;
+static unsigned long malloc_brk;
+
+static void *sbrk_no_zero(ptrdiff_t increment)
+{
+	unsigned long old = malloc_brk;
+	unsigned long new = old + increment;
+
+	if ((new < malloc_start) || (new > malloc_end))
+		return NULL;
+
+	malloc_brk = new;
+
+	return (void *)old;
+}
+
+void *sbrk(ptrdiff_t increment)
+{
+	void *old = sbrk_no_zero(increment);
+
+	/* Only clear increment, if valid address was returned */
+	if (old != NULL)
+		memset(old, 0, increment);
+
+	return old;
+}
+
+#ifdef CONFIG_APPS_MALLOC_TLSF
+#include <tlsf.h>
+tlsf_pool tlsf_mem_pool;
+#endif
+
+void mem_malloc_init(void *start, void *end)
+{
+	malloc_start = (unsigned long)start;
+	malloc_end = (unsigned long)end;
+	malloc_brk = malloc_start;
+#ifdef CONFIG_APPS_MALLOC_TLSF
+	tlsf_mem_pool = tlsf_create(start, end - start + 1);
+#endif
+}
diff --git a/apps/libc/malloc.h b/apps/libc/malloc.h
new file mode 100644
index 0000000..7995fb1
--- /dev/null
+++ b/apps/libc/malloc.h
@@ -0,0 +1,2 @@
+
+void mem_malloc_init(void *start, void *end);
diff --git a/apps/libc/private.h b/apps/libc/private.h
new file mode 100644
index 0000000..9a56544
--- /dev/null
+++ b/apps/libc/private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __LIBC_PRIVATE_H__
+#define __LIBC_PRIVATE_H__
+
+extern char *__progname;
+int __str_to_flags(const char *mode, int *flag);
+
+struct __file {
+	int fd;
+	struct __file *cookie; /* to check the file is open */
+};
+
+#endif /* __LIBC_PRIVATE_H__ */
diff --git a/apps/libc/stdio.c b/apps/libc/stdio.c
new file mode 100644
index 0000000..82233f7
--- /dev/null
+++ b/apps/libc/stdio.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <fcntl.h>
+
+#include "private.h"
+
+#undef stderr
+#undef stdin
+#undef stdout
+
+FILE stdin = { .fd = 0, .cookie = &stdin, };
+FILE stdout = { .fd = 1, .cookie = &stdout, };
+FILE stderr = { .fd = 2, .cookie = &stderr, };
+
+void putchar(char c)
+{
+	syscall(SYS_putchar, c);
+}
+
+void eputc(char c)
+{
+	syscall(SYS_eputc, c);
+}
+
+int getchar(void)
+{
+	return syscall(SYS_getchar);
+}
+
+int tstc(void)
+{
+	return syscall(SYS_tstc);
+}
+
+int ioctl(int fd, int request, void *buf)
+{
+	return syscall(SYS_ioctl, fd, request, buf);
+}
+
+int eputs(const char *str)
+{
+	const char *s = str;
+	int i = 0;
+
+	while (*s) {
+		eputc(*s);
+		if (*s == '\n')
+			eputc('\r');
+		s++;
+		i++;
+	}
+
+	return i;
+}
+
+int puts(const char *str)
+{
+	const char *s = str;
+	int i = 0;
+
+	while (*s) {
+		putchar(*s);
+		if (*s == '\n')
+			putchar('\r');
+		s++;
+		i++;
+	}
+
+	return i;
+}
+
+int printf(const char *fmt, ...)
+{
+	va_list args;
+	uint i;
+	char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+	va_start(args, fmt);
+	i = vsprintf (printbuffer, fmt, args);
+	va_end(args);
+
+	puts(printbuffer);
+
+	return i;
+}
+
+int vprintf(const char *fmt, va_list args)
+{
+	uint i;
+	char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+	i = vsprintf(printbuffer, fmt, args);
+
+	puts(printbuffer);
+
+	return i;
+}
+
+/* FILE implementation */
+
+static int __files_used = 0;
+
+static void __file_free(FILE *f)
+{
+	free(f);
+	f = NULL;
+	__files_used--;
+}
+
+static bool __file_sanity_check(FILE *f)
+{
+	return f->cookie != NULL;
+}
+
+static FILE *__file_malloc(void)
+{
+	FILE *f;
+
+	if (__files_used >= CONFIG_APP_FILE_MAX)
+		return NULL;
+
+	f = calloc(1, sizeof(*f));	
+	if (!f)
+		return NULL;
+
+	f->cookie = f;
+	__files_used++;
+	return f;
+}
+
+int fputs(const char *s, FILE *f)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	if (f == &stdout)
+		return puts(s);
+	else if (f == &stderr)
+		return eputs(s);
+	else
+		return write(f->fd, s, strlen(s));
+}
+
+int fputc(int c, FILE *f)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	if (f == &stdout)
+		putchar(c);
+	else if (f == &stderr)
+		eputc(c);
+	else
+		return write(f->fd, &c, 1);
+
+	return 1;
+}
+
+int vfprintf(FILE *file, const char *fmt, va_list args)
+{
+	char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+	vsprintf(printbuffer, fmt, args);
+
+	return fputs(printbuffer, file);
+}
+
+int fprintf(FILE *file, const char *fmt, ...)
+{
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	ret = vfprintf(file, fmt, args);
+	va_end(args);
+
+	return ret;
+}
+
+FILE *fopen(const char *path, const char *mode)
+{
+	int flags;
+	int fd;
+	FILE *f;
+
+	fd = __str_to_flags(mode, &flags);
+	if (fd)
+		return NULL;
+
+	f = __file_malloc();
+	if (!f)
+		return NULL;
+
+	fd = open(mode, flags); 
+	if (fd < 0) {
+		__file_free(f);
+		return NULL;
+	}
+
+	f->fd = fd;
+
+	return f;
+}
+
+int fclose(FILE *f)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	if (f == &stderr || f == &stdout || f == &stdin)
+		return -EINVAL;
+
+	close(f->fd);
+
+	__file_free(f);
+
+	return 0;
+}
+
+size_t fread(void *buf, size_t size, size_t nb, FILE *f)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	return read(f->fd, buf, size * nb);
+}
+
+size_t fwrite(const void *buf, size_t size, size_t nb, FILE *f)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	return write(f->fd, buf, size * nb);
+}
+
+int fseek(FILE *f, long offset, int whence)
+{
+	if (!__file_sanity_check(f))
+		return -EINVAL;
+
+	return lseek(f->fd, offset, whence);
+}
+
+char* itoa(int i)
+{
+	char printbuffer[26];
+	char *p = &printbuffer[25];
+	*p-- = '\0';
+	do {
+		*p-- = '0' + i % 10;
+		i /= 10;
+	} while (i > 0);
+	return p + 1;
+}
diff --git a/apps/libc/stdlib.c b/apps/libc/stdlib.c
new file mode 100644
index 0000000..0ec07ac
--- /dev/null
+++ b/apps/libc/stdlib.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <limits.h>
+#include <malloc.h>
+#include <errno.h>
+#include <ctype.h>
+
+static char env[ENV_MAX];
+
+char *getenv(const char *name)
+{
+	if (syscall(SYS_getenv, name, env))
+		return NULL;
+
+	return env;
+}
+
+int atoi(const char *s)
+{
+	int i = 0;
+	bool minus;
+
+	if (*s == '-') {
+		minus = true;
+		s++;
+	}
+
+	while (isdigit(*s))
+		i = i * 10 + *(s++) - '0';
+	return (minus) ? -i : i;
+}
+
+long atol(const char *s)
+{
+	long i = 0;
+	bool minus;
+
+	if (*s == '-') {
+		minus = true;
+		s++;
+	}
+
+	while (isdigit(*s))
+		i = i * 10 + *(s++) - '0';
+	return (minus) ? -i : i;
+}
+
+long long atoll(const char *s)
+{
+	long long i = 0;
+	bool minus;
+
+	if (*s == '-') {
+		minus = true;
+		s++;
+	}
+
+	while (isdigit(*s))
+		i = i * 10 + *(s++) - '0';
+	return (minus) ? -i : i;
+}
diff --git a/apps/libc/string.c b/apps/libc/string.c
new file mode 100644
index 0000000..67a34f9
--- /dev/null
+++ b/apps/libc/string.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <malloc.h>
+
+void *memcpy(void *dst, const void *src, size_t count)
+{
+	char *d = (char *)dst;
+	const char *s = (const char *)src;
+
+	while (count--)
+		*d++ = *s++;
+
+	return d;
+}
+
+void *memset(void *dst, int val, size_t count)
+{
+	char *d = (char *)dst;
+
+	while (count--)
+		*d++ = (char)val;
+
+	return d;
+}
+
+int memcmp(const void *dst, const void *src, size_t count)
+{
+	const char *d = (const char *)dst;
+	const char *s = (const char *)src;
+	int r = 0;
+
+	while (count-- && (r = *d++ - *s++) == 0) ;
+
+	return r;
+}
+
+unsigned int strlen(const char *s)
+{
+	const char *p;
+
+	for (p = s; *p != '\0'; p++)
+		;
+	return p - s;
+}
+
+char *strcpy(char *dst, const char *src)
+{
+	char *tmp = dst;
+
+	while ((*dst++ = *src++) != '\0')
+		;
+
+	return tmp;
+}
+
+int strcmp(const char *s1, const char *s2)
+{
+	signed char res;
+
+	while (1) {
+		res = *s1 - *s2++;
+		
+		if (res)
+			break;
+
+		if (!*s1++)
+			break;
+	}
+
+	return res;
+}
+
+int strncmp(const char *s1, const char *s2, size_t count)
+{
+	signed char res;
+
+	while (count--) {
+		res = *s1 - *s2++;
+		
+		if (res)
+			break;
+
+		if (!*s1++)
+			break;
+	}
+
+	return res;
+}
+
+char *strchr(const char *s, int c)
+{
+	for (; *s != (char) c; ++s)
+		if (*s == '\0')
+			return NULL;
+
+	return (char *)s;
+}
+
+void *memchr(const void *src, int val, size_t count)
+{
+	const char *s = src;
+
+	while (count--) {
+		if (*s++ == val)
+			return (void*)(s - 1);
+	}
+
+	return NULL;
+}
+
+void *memmove(void *dst, const void *src, size_t count)
+{
+	char *p, *s;
+
+	if (dst <= src) {
+		p = (char *)dst;
+		s = (char *)src;
+		while (count--)
+			*p++ = *s++;
+	} else {
+		p = (char *)dst + count;
+		s = (char *)src + count;
+		while (count--)
+			*--p = *--s;
+	}
+
+	return dst;
+}
+
+char *strdup(const char *s)
+{
+	char *p;
+
+	if (!s)
+		return NULL;
+		
+	p = malloc (strlen(s) + 1);
+	if (!p)
+		return NULL;
+
+	strcpy (p, s);
+	return p;
+}
diff --git a/apps/libc/sys/Makefile b/apps/libc/sys/Makefile
new file mode 100644
index 0000000..119f373
--- /dev/null
+++ b/apps/libc/sys/Makefile
@@ -0,0 +1,2 @@
+
+app-y += stat.o
diff --git a/apps/libc/sys/stat.c b/apps/libc/sys/stat.c
new file mode 100644
index 0000000..decc227
--- /dev/null
+++ b/apps/libc/sys/stat.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int mkdir(const char *path, mode_t mode)
+{
+	return syscall(SYS_mkdir, path, mode);
+}
diff --git a/apps/libc/syscalls.c b/apps/libc/syscalls.c
new file mode 100644
index 0000000..796a681
--- /dev/null
+++ b/apps/libc/syscalls.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sections.h>
+
+#include "malloc.h"
+#include "private.h"
+
+int main(int argc, char **argv);
+
+static bool is_valid_syscall(void *addr)
+{
+	return strncmp(addr, SYSCALLS_MAGIC, 8) == 0;
+}
+
+void panic(char *s)
+{
+	puts(s);
+	exit(10);
+}
+
+static void **syscalls;
+static uint32_t nb_syscalls;
+
+int syscall(int num, ...)
+{
+	long (*__syscall)(unsigned long arg0, unsigned long arg1, unsigned long arg2);
+	va_list args;
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	int ret;
+
+	if (num >= nb_syscalls)
+		return -1;
+
+	va_start(args, num);
+	arg0 = va_arg(args, unsigned long);
+	arg1 = va_arg(args, unsigned long);
+	arg2 = va_arg(args, unsigned long);
+	__syscall = syscalls[num];
+	ret = __syscall(arg0, arg1, arg2);
+
+	va_end(args);
+
+	return ret;
+}
+
+int syscalls_parse(struct syscalls_header *sys)
+{
+#ifndef	CONFIG_PHYS_ADDR_T_64BIT
+	uint32_t malloc_base = sys->malloc_base & 0xffffffff;
+	uint32_t malloc_end = malloc_base + sys->malloc_size - 1;
+#else
+	uint64_t malloc_base = sys->malloc_base;
+	uint64_t malloc_end = malloc_base + sys->malloc_size - 1;
+#endif
+
+	if (!sys->syscalls)
+		return 1;
+
+	syscalls = sys->syscalls;
+	nb_syscalls = sys->nb_syscalls;
+
+	mem_malloc_init((void *)malloc_base, (void *)malloc_end);
+
+	return 0;
+}
+
+char *__progname;
+
+int app_start(int argc, char **argv)
+{
+	void *sys = _text - 0x2000;
+
+	if (!is_valid_syscall(sys))
+		return EXIT_FAILURE;
+
+	if (syscalls_parse(sys))
+		return EXIT_FAILURE;
+
+	__progname = argv[0];
+
+	return main(argc, argv);
+}
diff --git a/apps/libc/time.c b/apps/libc/time.c
new file mode 100644
index 0000000..6bb57da
--- /dev/null
+++ b/apps/libc/time.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <types.h>
+
+#define SECOND	1000 * 1000 * 1000
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+	int ret;
+
+	if (req->tv_sec) {
+		ret = syscall(SYS_ndelay, req->tv_sec * SECOND);
+		if (ret)
+			return ret;
+	}
+
+	if (!req->tv_nsec)
+		return 0;
+
+	if (req->tv_nsec > 999999999)
+		return -1;
+
+	return syscall(SYS_ndelay, req->tv_nsec);
+}
diff --git a/apps/libc/unistd.c b/apps/libc/unistd.c
new file mode 100644
index 0000000..ea92604
--- /dev/null
+++ b/apps/libc/unistd.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <string.h>
+#include <malloc.h>
+#include <limits.h>
+
+int read(int fd, void *buf, size_t count)
+{
+	return syscall(SYS_read, fd, buf, count);
+}
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	return syscall(SYS_write, fd, buf, count);
+}
+
+int close(int fd)
+{
+	return syscall(SYS_close, fd);
+}
+
+int unlink(const char *pathname)
+{
+	return syscall(SYS_unlink, pathname);
+}
+
+int stat(const char *path, struct stat *buf)
+{
+	return syscall(SYS_stat, path, buf);
+}
+
+int lstat(const char *path, struct stat *buf)
+{
+	return syscall(SYS_lstat, path, buf);
+}
+
+loff_t lseek(int fd, loff_t offset, int whence)
+{
+	return syscall(SYS_lseek, fd, offset, whence);
+}
+
+int symlink(const char *pathname, const char *newpath)
+{
+	return syscall(SYS_symlink, pathname, newpath);
+}
+
+ssize_t readlink(const char *path, char *buf, size_t bufsiz)
+{
+	return syscall(SYS_readlink, path, buf, bufsiz);
+}
+
+int rmdir(const char *path)
+{
+	return syscall(SYS_rmdir, path);
+}
+
+char *get_current_dir_name(void)
+{
+	size_t size = sizeof(char) * PATH_MAX;
+	char *cwd = malloc(size);
+
+	if (!cwd)
+		return NULL;
+
+	if (syscall(SYS_getcwd, cwd, size))
+		goto err;
+
+	return cwd;
+
+err:
+	free(cwd);
+	return NULL;
+}
+
+char *getcwd(char *buf, size_t size)
+{
+	if (syscall(SYS_getcwd, buf, size))
+		return NULL;
+
+	return buf;
+}
+
+int chdir(const char *path)
+{
+	return syscall(SYS_chdir, path);
+}
+
+int usleep(unsigned int usec)
+{
+	return syscall(SYS_ndelay, usec * 1000);
+}
-- 
1.7.10.4




More information about the barebox mailing list