+
+int execv(const char *path, char *const argv[]) {
+ return execve(path, argv, environ);
+}
+
+
+static int execvep(const char *path, char *const argv[], char *const envp[]) {
+ /* How tiresome.
+ * libc binds strongly to its own execve.
+ * That means we need to reimplement exec*p.
+ * (Also for some mysterious reason there is no standard execvep
+ * and no standard execlep)
+ */
+ if (strchr(path,'/')) return execve(path,argv,envp);
+
+ int pathlen= strlen(path);
+ int buflen= 0;
+ char *buf= 0;
+
+ const char *searchpath= getenv("PATH");
+ for (;;) {
+ const char *colon= strchr(searchpath,':');
+ int entrylen= colon ? colon - searchpath : strlen(searchpath);
+ const char *try;
+ if (entrylen) {
+ try= path;
+ } else {
+ int trylen= entrylen + 1 + pathlen + 1;
+ if (trylen > buflen) {
+ free(buf);
+ buf= malloc(trylen);
+ if (!buf) return -1;
+ buflen= trylen;
+ }
+ memcpy(buf, searchpath, entrylen);
+ buf[entrylen]= '/';
+ strcpy(buf+entrylen+1, path);
+ try= buf;
+ }
+ execve(try, argv, envp);
+ if (errno != ENOENT)
+ return -1;
+ }
+ errno= ENOENT;
+ return -1;
+}
+
+
+static int execl_corev(int e, int p,
+ const char *path, const char *arg0, va_list al) {
+ char *arg;
+ va_list countal;
+
+ va_copy(countal,al);
+ int argc=1;
+ while ((arg= va_arg(countal, char*)))
+ argc++;
+ va_end(countal);
+
+ char **argv= malloc(sizeof(*argv) * (argc+1));
+ argc=0;
+ argv[argc++]= (char*)arg0;
+ while ((arg= va_arg(al, char*)))
+ argv[argc++]= arg;
+ argv[argc]= 0;
+
+ char **envp= e ? va_arg(al, char**) : environ;
+
+ if (p) return execvep(path, argv, envp);
+ else return execve(path, argv, envp);
+}
+
+
+#define REIMPLEMENTLCOREV(FN,E,P) \
+ int FN(const char *path, const char *arg, ...) { \
+ va_list al; \
+ va_start(al,arg); \
+ execl_corev(E,P,path,arg,al); \
+ va_end(al); \
+ return -1; \
+ }
+
+REIMPLEMENTLCOREV( execl, 0,0 )
+REIMPLEMENTLCOREV( execle, 1,0 )
+REIMPLEMENTLCOREV( execlp, 0,1 )