add simple_exec{ve,le}
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@6773 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -213,8 +213,10 @@ SigAction signal(int iSig, SigAction pAction); /* BSD compatible */
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int ROKEN_LIB_FUNCTION simple_execve(const char*, char*const[], char*const[]);
|
||||||
int ROKEN_LIB_FUNCTION simple_execvp(const char*, char *const[]);
|
int ROKEN_LIB_FUNCTION simple_execvp(const char*, char *const[]);
|
||||||
int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...);
|
int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...);
|
||||||
|
int ROKEN_LIB_FUNCTION simple_execle(const char*, ...);
|
||||||
|
|
||||||
void ROKEN_LIB_FUNCTION print_version(const char *);
|
void ROKEN_LIB_FUNCTION print_version(const char *);
|
||||||
|
|
||||||
|
@@ -69,6 +69,24 @@ RCSID("$Id$");
|
|||||||
128- is 128 + signal that killed subprocess
|
128- is 128 + signal that killed subprocess
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_status(pid_t pid)
|
||||||
|
{
|
||||||
|
while(1) {
|
||||||
|
int status;
|
||||||
|
|
||||||
|
while(waitpid(pid, &status, 0) < 0)
|
||||||
|
if (errno != EINTR)
|
||||||
|
return -3;
|
||||||
|
if(WIFSTOPPED(status))
|
||||||
|
continue;
|
||||||
|
if(WIFEXITED(status))
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
if(WIFSIGNALED(status))
|
||||||
|
return WTERMSIG(status) + 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
simple_execvp(const char *file, char *const args[])
|
simple_execvp(const char *file, char *const args[])
|
||||||
{
|
{
|
||||||
@@ -80,45 +98,79 @@ simple_execvp(const char *file, char *const args[])
|
|||||||
execvp(file, args);
|
execvp(file, args);
|
||||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||||
default:
|
default:
|
||||||
while(1) {
|
return check_status(pid);
|
||||||
int status;
|
|
||||||
|
|
||||||
while(waitpid(pid, &status, 0) < 0)
|
|
||||||
if (errno != EINTR)
|
|
||||||
return -3;
|
|
||||||
if(WIFSTOPPED(status))
|
|
||||||
continue;
|
|
||||||
if(WIFEXITED(status))
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
if(WIFSIGNALED(status))
|
|
||||||
return WTERMSIG(status) + 128;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* gee, I'd like a execvpe */
|
||||||
|
int
|
||||||
|
simple_execve(const char *file, char *const args[], char *const envp[])
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
switch(pid){
|
||||||
|
case -1:
|
||||||
|
return -2;
|
||||||
|
case 0:
|
||||||
|
execve(file, args, envp);
|
||||||
|
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||||
|
default:
|
||||||
|
return check_status(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
collect_args(va_list *ap)
|
||||||
|
{
|
||||||
|
char **argv = NULL;
|
||||||
|
int argc = 0, i = 0;
|
||||||
|
do {
|
||||||
|
if(i == argc) {
|
||||||
|
/* realloc argv */
|
||||||
|
char **tmp = realloc(argv, (argc + 5) * sizeof(*argv));
|
||||||
|
if(tmp == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
argv = tmp;
|
||||||
|
argc += 5;
|
||||||
|
}
|
||||||
|
argv[i++] = va_arg(*ap, char*);
|
||||||
|
} while(argv[i - 1] != NULL);
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
simple_execlp(const char *file, ...)
|
simple_execlp(const char *file, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char **argv = NULL;
|
char **argv;
|
||||||
int argc, i;
|
int ret;
|
||||||
|
|
||||||
argc = i = 0;
|
|
||||||
va_start(ap, file);
|
va_start(ap, file);
|
||||||
do {
|
argv = collect_args(&ap);
|
||||||
if(i == argc) {
|
|
||||||
char **tmp = realloc(argv, (argc + 5) * sizeof(*argv));
|
|
||||||
if(tmp == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
argv = tmp;
|
|
||||||
argc += 5;
|
|
||||||
}
|
|
||||||
argv[i++] = va_arg(ap, char*);
|
|
||||||
} while(argv[i - 1] != NULL);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
i = simple_execvp(file, argv);
|
if(argv == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = simple_execvp(file, argv);
|
||||||
free(argv);
|
free(argv);
|
||||||
return i;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
simple_execle(const char *file, ... /* ,char *const envp[] */)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char **argv;
|
||||||
|
char *const* envp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(ap, file);
|
||||||
|
argv = collect_args(&ap);
|
||||||
|
envp = va_arg(ap, char **);
|
||||||
|
va_end(ap);
|
||||||
|
if(argv == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = simple_execve(file, argv, envp);
|
||||||
|
free(argv);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user