[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/unistd/exec.c b/ap/build/uClibc/libc/unistd/exec.c
new file mode 100644
index 0000000..7d24072
--- /dev/null
+++ b/ap/build/uClibc/libc/unistd/exec.c
@@ -0,0 +1,331 @@
+/*  Copyright (C) 2004     Manuel Novoa III
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Jan 1, 2004
+ *   Initial version of a SUSv3 compliant exec*() functions.
+ * Feb 17, 2004
+ *   Sigh... Fall back to alloca() if munmap() is broken on uClinux.
+ */
+
+/* NOTE: Strictly speaking, there could be problems from accessing
+ * __environ in multithreaded programs.  The only way around this
+ * that I see is to essentially lock __environ access (modifying
+ * the setenv code), make a copy of the environment table (just the
+ * pointers since the strings themselves are never freed), and then
+ * unlock prior to the execve call.  If that fails, then we'd need
+ * to free the storage allocated for the copy.  Better ideas anyone?
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+
+
+/**********************************************************************/
+#define EXEC_FUNC_COMMON 0
+#define EXEC_FUNC_EXECVP 1
+#if defined(__ARCH_USE_MMU__)
+
+/* We have an MMU, so use alloca() to grab space for buffers and arg lists. */
+
+# define EXEC_ALLOC_SIZE(VAR)      /* nothing to do */
+# define EXEC_ALLOC(SIZE,VAR,FUNC) alloca((SIZE))
+# define EXEC_FREE(PTR,VAR)        ((void)0)
+
+#else
+
+/* We do not have an MMU, so using alloca() is not an option (as this will
+ * easily overflow the stack in most setups).  Less obviously, using malloc()
+ * is not an option either since malloc()ed memory can leak in from a vfork()ed
+ * child into the parent as no one is around after the child calls exec*() to
+ * free() the memory.  Therefore, we must use mmap() and unmap() directly,
+ * caching the result as we go.  This way we minimize the leak by reusing the
+ * memory with every call to an exec*().
+ *
+ * To prevent recursive use of the same cached memory, we have to give execvp()
+ * its own cache.  Here are the nested exec calls (a/-: alloc/no-alloc):
+ *  execve(-) -> calls straight to kernel
+ *  execl(a)  -> execve(-)
+ *  execlp(a) -> execvp(a)	!! recursive usage !!
+ *  execle(a) -> execve(-)
+ *  execv(-)  -> execve(-)
+ *  execvp(a) -> execve(-)
+ */
+
+# define EXEC_ALLOC_SIZE(VAR)      /* nothing to do */
+# define EXEC_ALLOC(SIZE,VAR,FUNC) __exec_alloc((SIZE), FUNC)
+# define EXEC_FREE(PTR,VAR)        ((void)0)
+
+extern void *__exec_alloc(size_t size, int func) attribute_hidden;
+
+# ifdef L___exec_alloc
+
+void attribute_hidden *__exec_alloc(size_t size, int func)
+{
+	static void *common_cache, *execvp_cache;
+	static size_t common_size, execvp_size;
+
+	void **cache = (func ? &execvp_cache : &common_cache);
+	size_t *cache_size = (func ? &execvp_size : &common_size);
+
+	if (*cache_size >= size)
+		return *cache;
+	else if (*cache)
+		munmap(*cache, *cache_size);
+
+	*cache_size = size;
+	return *cache = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+
+	/* We don't actually handle OOM in the exec funcs ...
+	if (*cache != MAP_FAILED)
+		return *cache;
+	else
+		return (*cache = NULL);
+	*/
+}
+
+# endif
+
+#endif
+/**********************************************************************/
+#ifdef L_execl
+
+int execl(const char *path, const char *arg, ...)
+{
+	EXEC_ALLOC_SIZE(size)		/* Do NOT add a semicolon! */
+	int n;
+	char **argv;
+	char **p;
+	va_list args;
+
+	n = 0;
+	va_start(args, arg);
+	do {
+		++n;
+	} while (va_arg(args, char *));
+	va_end(args);
+
+	p = argv = (char **) EXEC_ALLOC((n+1) * sizeof(char *), size, EXEC_FUNC_COMMON);
+
+	p[0] = (char *)arg;
+
+	va_start(args, arg);
+	do {
+		*++p = va_arg(args, char *);
+	} while (--n);
+	va_end(args);
+
+	n = execve(path, (char *const *) argv, __environ);
+
+	EXEC_FREE(argv, size);
+
+	return n;
+}
+libc_hidden_def(execl)
+
+#endif
+/**********************************************************************/
+#ifdef L_execv
+
+int execv(__const char *path, char *__const argv[])
+{
+	return execve(path, argv, __environ);
+}
+libc_hidden_def(execv)
+
+#endif
+/**********************************************************************/
+#ifdef L_execle
+
+int execle(const char *path, const char *arg, ...)
+{
+	EXEC_ALLOC_SIZE(size)		/* Do NOT add a semicolon! */
+	int n;
+	char **argv;
+	char **p;
+	char *const *envp;
+	va_list args;
+
+	n = 0;
+	va_start(args, arg);
+	do {
+		++n;
+	} while (va_arg(args, char *));
+	envp = va_arg(args, char *const *);	/* Varies from execl and execlp. */
+	va_end(args);
+
+	p = argv = (char **) EXEC_ALLOC((n+1) * sizeof(char *), size, EXEC_FUNC_COMMON);
+
+	p[0] = (char *)arg;
+
+	va_start(args, arg);
+	do {
+		*++p = va_arg(args, char *);
+	} while (--n);
+	va_end(args);
+
+	n = execve(path, (char *const *) argv, envp);
+
+	EXEC_FREE(argv, size);
+
+	return n;
+}
+libc_hidden_def(execle)
+
+#endif
+/**********************************************************************/
+#ifdef L_execlp
+
+int execlp(const char *file, const char *arg, ...)
+{
+	EXEC_ALLOC_SIZE(size)		/* Do NOT add a semicolon! */
+	int n;
+	char **argv;
+	char **p;
+	va_list args;
+
+	n = 0;
+	va_start(args, arg);
+	do {
+		++n;
+	} while (va_arg(args, char *));
+	va_end(args);
+
+	p = argv = (char **) EXEC_ALLOC((n+1) * sizeof(char *), size, EXEC_FUNC_COMMON);
+
+	p[0] = (char *)arg;
+
+	va_start(args, arg);
+	do {
+		*++p = va_arg(args, char *);
+	} while (--n);
+	va_end(args);
+
+	n = execvp(file, (char *const *) argv);
+
+	EXEC_FREE(argv, size);
+
+	return n;
+}
+libc_hidden_def(execlp)
+
+#endif
+/**********************************************************************/
+#ifdef L_execvp
+
+
+/* Use a default path that matches glibc behavior, since SUSv3 says
+ * this is implementation-defined.  The default is current working dir,
+ * /bin, and then /usr/bin. */
+static const char default_path[] = ":/bin:/usr/bin";
+
+int execvp(const char *path, char *const argv[])
+{
+	char *buf = NULL;
+	char *p;
+	char *e;
+	char *s0;
+	char *s;
+	EXEC_ALLOC_SIZE(size = 0)	/* Do NOT add a semicolon! */
+	size_t len;
+	size_t plen;
+
+	if (!path || !*path) {		/* Comply with SUSv3. */
+	BAD:
+		__set_errno(ENOENT);
+		return -1;
+	}
+
+	if (strchr(path, '/')) {
+		execve(path, argv, __environ);
+		if (errno == ENOEXEC) {
+			char **nargv;
+			EXEC_ALLOC_SIZE(size2) /* Do NOT add a semicolon! */
+			size_t n;
+	RUN_BIN_SH:
+			/* Need the dimension - 1.  We omit counting the trailing
+			 * NULL but we actually omit the first entry. */
+			for (n=0 ; argv[n] ; n++) {}
+			nargv = (char **) EXEC_ALLOC((n+2) * sizeof(char *), size2, EXEC_FUNC_EXECVP);
+			nargv[0] = argv[0];
+			nargv[1] = (char *)path;
+			memcpy(nargv+2, argv+1, n*sizeof(char *));
+			execve("/bin/sh", nargv, __environ);
+			EXEC_FREE(nargv, size2);
+		}
+	} else {
+		if ((p = getenv("PATH")) != NULL) {
+			if (!*p) {
+				goto BAD;
+			}
+		} else {
+			p = (char *) default_path;
+		}
+
+		plen = strlen(path);
+		if (plen > (FILENAME_MAX - 1)) {
+		ALL_TOO_LONG:
+			__set_errno(ENAMETOOLONG);
+			return -1;
+		}
+		len = (FILENAME_MAX - 1) - plen;
+
+		buf = EXEC_ALLOC(FILENAME_MAX, size, EXEC_FUNC_EXECVP);
+		{
+			int seen_small = 0;
+			s0 = buf + len;
+			memcpy(s0, path, plen+1);
+
+			do {
+				s = s0;
+				e = strchrnul(p, ':');
+				if (e > p) {
+					plen = e - p;
+					if (e[-1] != '/') {
+						++plen;
+					}
+					if (plen > len) {
+						goto NEXT;
+					}
+					s -= plen;
+					memcpy(s, p, plen);
+					s[plen-1] = '/';
+				}
+
+				execve(s, argv, __environ);
+
+				seen_small = 1;
+
+				if (errno == ENOEXEC) {
+					path = s;
+					goto RUN_BIN_SH;
+				}
+
+			NEXT:
+				if (!*e) {
+					if (!seen_small) {
+						goto ALL_TOO_LONG;
+					}
+					break;
+				}
+				p = e + 1;
+			} while (1);
+		}
+	}
+
+	EXEC_FREE(buf, size);
+
+	return -1;
+}
+libc_hidden_def(execvp)
+
+#endif
+/**********************************************************************/