#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;
}