#include #include #include #include #include void search_path(char *file, char *path); struct _new_proc { unsigned long arg_off; unsigned long env_off; unsigned long fname_off; unsigned short arg_sel; unsigned short env_sel; unsigned short fname_sel; unsigned short arg_count; unsigned short arg_size; unsigned short env_count; unsigned short env_size; unsigned short mode; }; int __spawnve(struct _new_proc * np) { int ret_v; __asm__("movl %1, %%edx \n\t" "movw $0x7F06, %%ax \n\t" "int $0x21 \n\t" "jc 1f \n\t" "jmp 2f \n\t" "1: \n\t" "movl %0, _errno \n\t" "movl $-1, %0 \n\t" "2:\n\t" : "=a"(ret_v):"m"(np)); return ret_v; } int spawnve(int mode, const char *name, const char *const * argv, const char *const * envp) { struct _new_proc np; int i, size, n; const char *const * p; char *d; char exe[512]; np.mode = mode; strcpy(exe, name); np.fname_off = (unsigned long) exe; if (envp == NULL) envp = (const char *const *) environ; for (size = 1, n = 0, p = envp; *p != NULL; ++p) { ++n; size += 1 + strlen(*p); } d = alloca(size); np.env_count = n; np.env_size = size; np.env_off = (unsigned long) d; for (p = envp; *p != NULL; ++p) { i = strlen(*p); (void) memcpy(d, *p, i + 1); d += i + 1; } *d = 0; size = 0; n = 0; for (p = argv; *p != NULL; ++p) { ++n; size += 2 + strlen(*p); } d = alloca(size); np.arg_count = n; np.arg_size = size; np.arg_off = (unsigned long) d; for (p = argv; *p != NULL; ++p) { i = strlen(*p); *d++ = 0xff; (void) memcpy(d, *p, i + 1); d += i + 1; } i = __spawnve(&np); return (i); } int spawnvpe(int mode, const char *name, const char *const * argv, const char *const * envp) { char exe[512]; char path[512]; strcpy(exe, name); search_path(exe, path); return (spawnve(mode, path, argv, envp)); } int spawnl(int mode, const char *name, const char *arg0,...) { va_list vl; int r; va_start(vl, name); r = spawnv(mode, name, (const char *const *) vl); va_end(vl); return (r); } int spawnle(int mode, const char *name, const char *arg0,...) { va_list vl; const char *const * env_ptr; int r; va_start(vl, name); while (va_arg(vl, char *) !=NULL) ; env_ptr = va_arg(vl, const char *const *); va_end(vl); va_start(vl, name); r = spawnve(mode, name, (const char *const *) vl, env_ptr); va_end(vl); return (r); } int spawnlp(int mode, const char *name, const char *arg0,...) { va_list vl; int r; va_start(vl, name); r = spawnvp(mode, name, (const char *const *) vl); va_end(vl); return (r); } int spawnlpe(int mode, const char *name, const char *arg0,...) { va_list vl; const char *const * env_ptr; int r; va_start(vl, name); while (va_arg(vl, char *) !=NULL) /* do nothing */ ; env_ptr = va_arg(vl, const char *const *); va_end(vl); va_start(vl, name); r = spawnvpe(mode, name, (const char *const *) vl, env_ptr); va_end(vl); return (r); } int spawnv(int mode, const char *name, const char *const * argv) { return (spawnve(mode, name, argv, NULL)); } int spawnvp(int mode, const char *name, const char *const * argv) { return (spawnvpe(mode, name, argv, NULL)); } void search_path(char *file, char *path) { char *envp, *end; int i, len; strcpy (path, file); len = strlen (file); if (access (path, 4) == 0) return; envp = getenv("PATH"); if (envp != NULL) for (;;) { while (*envp == ' ' || *envp == '\t') ++envp; if (*envp == 0) break; end = envp; while (*end != 0 && *end != ';') ++end; i = end - envp; while (i>0 && (envp[i-1] == ' ' || envp[i-1] == '\t')) --i; if (i != 0) { memcpy (path, envp, i); if (envp[i-1] != '/' && envp[i-1] != '\\' && envp[i-1] != ':') path[i++] = '\\'; strcpy (path+i, file); if (access (path, 4) == 0) return; strcat (path+i+len, ".exe"); if (access (path, 4) == 0) return; } if (*end == 0) break; envp = end + 1; } path[0] = 0; }