add timed simple_exec
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13342 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		@@ -261,11 +261,15 @@ SigAction signal(int iSig, SigAction pAction); /* BSD compatible */
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int ROKEN_LIB_FUNCTION simple_execve(const char*, char*const[], char*const[]);
 | 
					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_execvp_timed(const char *, char *const[], 
 | 
				
			||||||
 | 
										   time_t (*)(void *), void *, time_t);
 | 
				
			||||||
int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...);
 | 
					int ROKEN_LIB_FUNCTION simple_execlp(const char*, ...);
 | 
				
			||||||
int ROKEN_LIB_FUNCTION simple_execle(const char*, ...);
 | 
					int ROKEN_LIB_FUNCTION simple_execle(const char*, ...);
 | 
				
			||||||
int ROKEN_LIB_FUNCTION simple_execl(const char *file, ...);
 | 
					int ROKEN_LIB_FUNCTION simple_execl(const char *file, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ROKEN_LIB_FUNCTION wait_for_process(pid_t);
 | 
					int ROKEN_LIB_FUNCTION wait_for_process(pid_t);
 | 
				
			||||||
 | 
					int ROKEN_LIB_FUNCTION wait_for_process_timed(pid_t, time_t (*)(void *), 
 | 
				
			||||||
 | 
										      void *, time_t);
 | 
				
			||||||
int ROKEN_LIB_FUNCTION pipe_execv(FILE**, FILE**, FILE**, const char*, ...);
 | 
					int ROKEN_LIB_FUNCTION pipe_execv(FILE**, FILE**, FILE**, const char*, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ROKEN_LIB_FUNCTION print_version(const char *);
 | 
					void ROKEN_LIB_FUNCTION print_version(const char *);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 1998 - 2001 Kungliga Tekniska H<>gskolan
 | 
					 * Copyright (c) 1998 - 2001, 2004 Kungliga Tekniska H<>gskolan
 | 
				
			||||||
 * (Royal Institute of Technology, Stockholm, Sweden). 
 | 
					 * (Royal Institute of Technology, Stockholm, Sweden). 
 | 
				
			||||||
 * All rights reserved. 
 | 
					 * All rights reserved. 
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -58,28 +58,89 @@ RCSID("$Id$");
 | 
				
			|||||||
   -1   on `unspecified' system errors
 | 
					   -1   on `unspecified' system errors
 | 
				
			||||||
   -2   on fork failures
 | 
					   -2   on fork failures
 | 
				
			||||||
   -3   on waitpid errors
 | 
					   -3   on waitpid errors
 | 
				
			||||||
 | 
					   -4   exec timeout
 | 
				
			||||||
   0-   is return value from subprocess
 | 
					   0-   is return value from subprocess
 | 
				
			||||||
   126  if the program couldn't be executed
 | 
					   126  if the program couldn't be executed
 | 
				
			||||||
   127  if the program couldn't be found
 | 
					   127  if the program couldn't be found
 | 
				
			||||||
   128- is 128 + signal that killed subprocess
 | 
					   128- is 128 + signal that killed subprocess
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   possible values `func' can return:
 | 
				
			||||||
 | 
					   ((time_t)-2)		exit loop w/o killing child and return
 | 
				
			||||||
 | 
					   			`exec timeout'/-4 from simple_exec
 | 
				
			||||||
 | 
					   ((time_t)-1)		kill child with SIGTERM and wait for child to exit
 | 
				
			||||||
 | 
					   0			don't timeout again
 | 
				
			||||||
 | 
					   n			seconds to next timeout
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sig_alarm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static RETSIGTYPE
 | 
				
			||||||
 | 
					sigtimeout(int sig)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sig_alarm = 1;
 | 
				
			||||||
 | 
					    SIGRETURN(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					wait_for_process_timed(pid_t pid, time_t (*func)(void *), 
 | 
				
			||||||
 | 
							       void *ptr, time_t timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    RETSIGTYPE (*old_func)(int sig) = NULL;
 | 
				
			||||||
 | 
					    unsigned int oldtime = 0;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sig_alarm = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (func) {
 | 
				
			||||||
 | 
						old_func = signal(SIGALRM, sigtimeout);
 | 
				
			||||||
 | 
						oldtime = alarm(timeout);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(1) {
 | 
				
			||||||
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while(waitpid(pid, &status, 0) < 0) {
 | 
				
			||||||
 | 
						    if (errno != EINTR) {
 | 
				
			||||||
 | 
							ret = -3;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    if (func == NULL)
 | 
				
			||||||
 | 
							continue;
 | 
				
			||||||
 | 
						    if (sig_alarm == 0)
 | 
				
			||||||
 | 
							continue;
 | 
				
			||||||
 | 
						    timeout = (*func)(ptr);
 | 
				
			||||||
 | 
						    if (timeout == (time_t)-1) {
 | 
				
			||||||
 | 
							kill(pid, SIGTERM);
 | 
				
			||||||
 | 
							continue;
 | 
				
			||||||
 | 
						    } else if (timeout == (time_t)-2) {
 | 
				
			||||||
 | 
							ret = -4;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    alarm(timeout);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(WIFSTOPPED(status))
 | 
				
			||||||
 | 
						    continue;
 | 
				
			||||||
 | 
						if(WIFEXITED(status)) {
 | 
				
			||||||
 | 
						    ret = WEXITSTATUS(status);
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(WIFSIGNALED(status)) {
 | 
				
			||||||
 | 
						    ret = WTERMSIG(status) + 128;
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					 out:
 | 
				
			||||||
 | 
					    if (func) {
 | 
				
			||||||
 | 
						signal(SIGALRM, old_func);
 | 
				
			||||||
 | 
						alarm(oldtime);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
wait_for_process(pid_t pid)
 | 
					wait_for_process(pid_t pid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    while(1) {
 | 
					    return wait_for_process_timed(pid, NULL, NULL, 0);
 | 
				
			||||||
	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
 | 
				
			||||||
@@ -170,7 +231,8 @@ pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
simple_execvp(const char *file, char *const args[])
 | 
					simple_execvp_timed(const char *file, char *const args[], 
 | 
				
			||||||
 | 
							    time_t (*func)(void *), void *ptr, time_t timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    pid_t pid = fork();
 | 
					    pid_t pid = fork();
 | 
				
			||||||
    switch(pid){
 | 
					    switch(pid){
 | 
				
			||||||
@@ -180,13 +242,20 @@ 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: 
 | 
				
			||||||
	return wait_for_process(pid);
 | 
						return wait_for_process_timed(pid, func, ptr, timeout);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					simple_execvp(const char *file, char *const args[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return simple_execvp_timed(file, args, NULL, NULL, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* gee, I'd like a execvpe */
 | 
					/* gee, I'd like a execvpe */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
simple_execve(const char *file, char *const args[], char *const envp[])
 | 
					simple_execve_timed(const char *file, char *const args[], char *const envp[],
 | 
				
			||||||
 | 
							    time_t (*func)(void *), void *ptr, time_t timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    pid_t pid = fork();
 | 
					    pid_t pid = fork();
 | 
				
			||||||
    switch(pid){
 | 
					    switch(pid){
 | 
				
			||||||
@@ -196,10 +265,16 @@ simple_execve(const char *file, char *const args[], char *const envp[])
 | 
				
			|||||||
	execve(file, args, envp);
 | 
						execve(file, args, envp);
 | 
				
			||||||
	exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
 | 
						exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
 | 
				
			||||||
    default: 
 | 
					    default: 
 | 
				
			||||||
	return wait_for_process(pid);
 | 
						return wait_for_process_timed(pid, func, ptr, timeout);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					simple_execve(const char *file, char *const args[], char *const envp[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return simple_execve_timed(file, args, envp, NULL, NULL, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
simple_execlp(const char *file, ...)
 | 
					simple_execlp(const char *file, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user