-rw-r--r-- | quickexec/quickexec.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/quickexec/quickexec.cpp b/quickexec/quickexec.cpp new file mode 100644 index 0000000..772ab4c --- a/dev/null +++ b/quickexec/quickexec.cpp @@ -0,0 +1,98 @@ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <dlfcn.h> + +#define QUICKEXEC "/tmp/.quickexec" + +#include <signal.h> +#include <sys/wait.h> + +void sigchildhandler(int) { + wait(0); +} + +int exec( const char *lib, int argc, char** argv ) +{ + setpgid(0,0); +// printf("loadlib %s, argc=%d\n", lib, argc ); + void *handle = dlopen ( lib, RTLD_LAZY); + if (!handle) { + fprintf( stderr, "%s\n", dlerror()); + exit(1); + } + typedef int (*Mainfunc)(int, char**); + Mainfunc mainfunc; + mainfunc = (Mainfunc) dlsym(handle, "main"); + char *error; + if ((error = dlerror()) != NULL) { + fprintf (stderr, "%s\n", error); + exit(1); + } + (*mainfunc)(argc,argv); + return 0; +} + +#define BUFFER_SIZE 1024 +int main( int argc, char** argv ) +{ + signal( SIGCHLD, sigchildhandler ); + (void) unlink( QUICKEXEC ); + if ( mkfifo( QUICKEXEC, S_IFIFO | S_IWUSR | S_IRUSR ) == -1 ) { + perror( QUICKEXEC ); + exit(1); + } + + if ( argc > 1 && fork() == 0 ) + return exec( argv[1], argc-2, argc > 2 ? argv+2 : 0 ); + + char buf[BUFFER_SIZE]; + int p = 0; + int r; + int fd = open( QUICKEXEC, O_RDONLY ); + if ( fd == -1 ) { + perror( QUICKEXEC ); + exit(1); + } + for ( ;; ) { + r = read( fd, buf+p, BUFFER_SIZE-p ); + p += r; + if ( r == 0 || p >= BUFFER_SIZE - 1 ) { + buf[p] = '\0'; + close ( fd ); + if ( fork() == 0 ) { + int argc = -1; + int i = 0; + int k = 0; + for ( i = 0; i <= p; i++ ) + if ( buf[i] == '\0' ) + argc++; + char** argv = new char*[argc]; + for ( i = 0; i < p; i++ ) { + if ( buf[i] == '\0' ) + argv[k++]=buf+i+1; + } + return exec( buf, argc, argv ); + } + p = 0; + fd = open( QUICKEXEC, O_RDONLY ); + } + } + return 0; +} + + + + + + + + + + + + + + |