summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorPiotr Strzelczyk <piotr@eps.gda.pl>2009-08-14 08:03:03 +0000
committerPiotr Strzelczyk <piotr@eps.gda.pl>2009-08-14 08:03:03 +0000
commita117dd391ce40a6f9bce4e14ea97b79bb7ed6d37 (patch)
tree52ec211b3fca8169ab80495f4c8b940f7fbd1833 /Build
parent608d80efb6ecb33200f881b804aa19a144da0f14 (diff)
exe stubs consistency check, redundant copies of universal wrapper removed
git-svn-id: svn://tug.org/texlive/trunk@14660 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/texlive/runscript.c176
-rwxr-xr-xBuild/source/texk/texlive/runscript.exebin0 -> 4096 bytes
2 files changed, 176 insertions, 0 deletions
diff --git a/Build/source/texk/texlive/runscript.c b/Build/source/texk/texlive/runscript.c
new file mode 100644
index 00000000000..bb06bc2d5d5
--- /dev/null
+++ b/Build/source/texk/texlive/runscript.c
@@ -0,0 +1,176 @@
+/*
+
+runscript.c
+
+Public Domain
+Originally written 2009 by T.M.Trzeciak
+
+Batch script launcher:
+
+Runs a batch file of the same name in the same location or sets
+TL_PROGNAME environment variable to its own name and calls
+the default batch script.
+
+Rationale:
+
+Batch scripts are not as universal as binary executables, there
+are some odd cases where they are not interchangeable with them.
+
+Usage:
+
+simply copy and rename the compiled binary
+
+Compilation:
+
+with gcc (size optimized):
+gcc -Os -s -o runscript.exe runscript.c
+
+with tcc (ver. 0.9.24), extra small size
+tcc -o runscript.exe runscript.c
+
+*/
+
+#include <windows.h>
+#include <stdio.h>
+#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
+#define DEFAULT_SCRIPT "tl-w32-wrapper.cmd"
+#define MAX_CMD 32768
+//#define DRYRUN
+
+static char dirname[MAX_PATH];
+static char basename[MAX_PATH];
+static char progname[MAX_PATH];
+static char cmdline[MAX_CMD];
+
+int main( int argc, char *argv[] ) {
+ int i;
+ static char path[MAX_PATH];
+
+ // get file name of this executable and split it into parts
+ DWORD nchars = GetModuleFileNameA(NULL, path, MAX_PATH);
+ if ( !nchars || (nchars == MAX_PATH) ) {
+ fprintf(stderr, "runscript: cannot get own name or path too long\n");
+ return -1;
+ }
+ // file extension part
+ i = strlen(path);
+ while ( i && (path[i] != '.') && (path[i] != '\\') ) i--;
+ strcpy(basename, path);
+ if ( basename[i] == '.' ) basename[i] = '\0'; //remove file extension
+ // file name part
+ while ( i && (path[i] != '\\') ) i--;
+ if ( path[i] != '\\' ) {
+ fprintf(stderr, "runcmd: no directory part in own name: %s\n", path);
+ return -1;
+ }
+ strcpy(dirname, path);
+ dirname[i+1] = '\0'; //remove file name, leave trailing backslash
+ strcpy(progname, &basename[i+1]);
+
+ // find program to execute
+ if ( (strlen(basename)+4 >= MAX_PATH) || (strlen(dirname)+strlen(DEFAULT_SCRIPT) >= MAX_PATH) ) {
+ fprintf(stderr, "runscript: path too long: %s\n", path);
+ return -1;
+ }
+ // try .bat first
+ strcpy(path, basename);
+ strcat(path, ".bat");
+ if ( GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES ) goto PROGRAM_FOUND;
+ // try .cmd next
+ strcpy(path, basename);
+ strcat(path, ".cmd");
+ if ( GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES ) goto PROGRAM_FOUND;
+ // pass the program name through environment (generic launcher case)
+ if ( !SetEnvironmentVariableA("TL_PROGNAME", progname) ) {
+ fprintf(stderr, "runscript: cannot set evironment variable\n", path);
+ return -1;
+ }
+ // check environment for default command
+ /*if ( GetEnvironmentVariableA("TL_W32_WRAPPER", cmd, MAX_CMD) ) goto PROGRAM_FOUND;*/
+ // use default script
+ strcpy(path, dirname);
+ strcat(path, DEFAULT_SCRIPT);
+ if ( GetFileAttributesA(path) == INVALID_FILE_ATTRIBUTES ) {
+ fprintf(stderr, "runscript: missing default script: %s\n", path);
+ return -1;
+ }
+
+PROGRAM_FOUND:
+
+ if ( !cmdline[0] ) {
+ strcpy(cmdline, "\"");
+ strcat(cmdline, path);
+ strcat(cmdline, "\"");
+ }
+
+ // get the command line for this process
+ char *argstr;
+ argstr = GetCommandLineA();
+ if ( argstr == NULL ) {
+ fprintf(stderr, "runscript: cannot get command line string\n");
+ return -1;
+ }
+ // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!)
+ int argstrlen = strlen(argstr);
+ int quoted = 0;
+ for ( i = 0; ( i < argstrlen) && ( !IS_WHITESPACE(argstr[i]) || quoted ); i++ )
+ if (argstr[i] == '"') quoted = !quoted;
+ // while ( IS_WHITESPACE(argstr[i]) ) i++; // arguments leading whitespace
+ argstr = &argstr[i];
+ if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD ) {
+ fprintf(stderr, "runscript: command line string too long:\n%s%s\n", cmdline, argstr);
+ return -1;
+ }
+ // pass through all the arguments
+ strcat(cmdline, argstr);
+
+#ifdef DRYRUN
+ printf("progname: %s\n", progname);
+ printf("dirname: %s\n", dirname);
+ printf("args: %s\n", &argstr[-i]);
+ for (i = 0; i < argc; i++) printf("argv[%d]: %s\n", i, argv[i]);
+ printf("cmdl: %s\n", cmdline);
+ return;
+#endif
+
+ // create child process
+ STARTUPINFOA si; // ANSI variant
+ PROCESS_INFORMATION pi;
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW;
+ //si.dwFlags = STARTF_USESHOWWINDOW;
+ //si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag)
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ ZeroMemory( &pi, sizeof(pi) );
+ if( !CreateProcessA(
+ NULL, // module name (uses command line if NULL)
+ cmdline, // command line
+ NULL, // process security atrributes
+ NULL, // thread security atrributes
+ TRUE, // handle inheritance
+ 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
+ NULL, // pointer to environment block (uses parent if NULL)
+ NULL, // starting directory (uses parent if NULL)
+ &si, // STARTUPINFO structure
+ &pi ) // PROCESS_INFORMATION structure
+ ) {
+ fprintf(stderr, "runscript: cannot create process: %s\n", cmdline);
+ return -1;
+ }
+ CloseHandle( pi.hThread ); // thread handle is not needed
+ DWORD ret = 0;
+ if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
+ if ( !GetExitCodeProcess( pi.hProcess, &ret) ) {
+ fprintf(stderr, "runscript: cannot get process exit code: %s\n", cmdline);
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "runscript: failed to wait for process termination: %s\n", cmdline);
+ return -1;
+ }
+ CloseHandle( pi.hProcess );
+ return ret;
+}
diff --git a/Build/source/texk/texlive/runscript.exe b/Build/source/texk/texlive/runscript.exe
new file mode 100755
index 00000000000..a93ef24732b
--- /dev/null
+++ b/Build/source/texk/texlive/runscript.exe
Binary files differ