summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2010-12-01 10:13:00 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2010-12-01 10:13:00 +0000
commit6a6e883e80a6273c5376e7039c04b641405b6ad2 (patch)
tree76a746890ffcdc619a33c00c468496b0161f8d30
parent5f3e957d96ea7892cf414c7a8857af53f30bd50f (diff)
WIN32 code from Akira
git-svn-id: svn://tug.org/texlive/trunk@20627 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/kpathsea/ChangeLog4
-rw-r--r--Build/source/texk/kpathsea/tex-make.c213
2 files changed, 92 insertions, 125 deletions
diff --git a/Build/source/texk/kpathsea/ChangeLog b/Build/source/texk/kpathsea/ChangeLog
index 74b789daf95..8dd247b1435 100644
--- a/Build/source/texk/kpathsea/ChangeLog
+++ b/Build/source/texk/kpathsea/ChangeLog
@@ -1,3 +1,7 @@
+2010-12-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * tex-make.c (maketex): [WIN32] spawnvp(_P_NOWAIT, ...) and pipe.
+
2010-11-29 Karl Berry <karl@tug.org>
* doc/kpathsea.texi (Brace expansion): no longer derived from Bash.
diff --git a/Build/source/texk/kpathsea/tex-make.c b/Build/source/texk/kpathsea/tex-make.c
index c17eeec3ab9..f3c7d2a5c0e 100644
--- a/Build/source/texk/kpathsea/tex-make.c
+++ b/Build/source/texk/kpathsea/tex-make.c
@@ -26,6 +26,9 @@
#include <kpathsea/readable.h>
#include <kpathsea/tex-make.h>
#include <kpathsea/variable.h>
+#if defined(WIN32) && !defined(__MINGW32__)
+#include <kpathsea/win32lib.h>
+#endif
#if !defined (AMIGA) && !(defined (MSDOS) && !defined(__DJGPP__)) && !defined (WIN32)
#include <sys/wait.h>
@@ -152,7 +155,23 @@ maketex (kpathsea kpse, kpse_file_format_type format, string* args)
string *s;
string ret = NULL;
string fn;
+#if defined(WIN32)
+ char fullbin[256], *wrp;
+
+ wrp = kpathsea_var_value(kpse, "SELFAUTOLOC");
+ if(wrp == NULL) {
+ fprintf(stderr, "I cannot get SELFAUTOLOC\n");
+ exit(100);
+ }
+ strcpy(fullbin, wrp);
+ free(wrp);
+ for(wrp=fullbin; *wrp; wrp++) {
+ if(*wrp == '/') *wrp = '\\';
+ }
+ strcat(fullbin, "\\");
+ strcat(fullbin, args[0]);
+#endif
if (!kpse->make_tex_discard_errors) {
fprintf (stderr, "\nkpathsea: Running");
for (s = &args[0]; *s != NULL; s++)
@@ -177,141 +196,83 @@ maketex (kpathsea kpse, kpse_file_format_type format, string* args)
#elif defined (MSDOS) && !defined(__DJGPP__)
#error Implement new MSDOS mktex call interface here
#elif defined (WIN32)
+ { /* spawnvp(_P_NOWAIT, ...) and pipe --ak 2002/12/15 */
- /* We would vastly prefer to link directly with mktex.c here.
- Unfortunately, it is not quite possible because kpathsea
- is not reentrant. The progname is expected to be set in mktex.c
- and various initialisations occur. So to be safe, we implement
- a call sequence equivalent to the Unix one. */
- {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- HANDLE child_in, child_out, child_err;
- HANDLE father_in, father_out_dup;
- HANDLE current_pid;
- SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
- string new_cmd = NULL, app_name = NULL;
-
- char buf[1024+1];
-#ifdef __MINGW32__
- DWORD num;
-#else
- int num;
-#endif
+ int nexitcode = STILL_ACTIVE;
+ HANDLE hchild;
+ int hstdout, childpipe[2];
+ int hstderr;
+ FILE *Hnul = NULL;
- if (look_for_cmd(args[0], &app_name) == FALSE) {
- goto error_exit;
+ if(_pipe(childpipe, 1024, O_TEXT | _O_NOINHERIT) == -1) {
+ perror("kpathsea: pipe()");
+ fn = NULL;
+ goto labeldone;
}
- /* Compute the command line */
- new_cmd = quote_args(args);
-
- /* We need this handle to duplicate other handles */
- current_pid = GetCurrentProcess();
-
- ZeroMemory( &si, sizeof(STARTUPINFO) );
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW ;
- si.wShowWindow = /* 0 */ SW_HIDE ;
-
- /* Child stdin */
- child_in = CreateFile("nul",
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sa, /* non inheritable */
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- si.hStdInput = child_in;
-
- if (CreatePipe(&father_in, &child_out, NULL, 0) == FALSE) {
- fprintf(stderr, "popen: error CreatePipe\n");
- goto error_exit;
- }
- if (DuplicateHandle(current_pid, child_out,
- current_pid, &father_out_dup,
- 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) {
- fprintf(stderr, "popen: error DuplicateHandle father_in\n");
- CloseHandle(father_in);
- CloseHandle(child_out);
- goto error_exit;
- }
- CloseHandle(child_out);
- si.hStdOutput = father_out_dup;
-
- /* Child stderr */
- if (kpse->make_tex_discard_errors) {
- child_err = CreateFile("nul",
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sa, /* non inheritable */
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
+ hstdout = _dup(fileno(stdout));
+ if(_dup2(childpipe[1], fileno(stdout)) != 0) {
+ fn = NULL;
+ close(hstdout);
+ close(childpipe[0]);
+ close(childpipe[1]);
+ goto labeldone;
}
- else {
- DuplicateHandle(current_pid, GetStdHandle(STD_ERROR_HANDLE),
- current_pid, &child_err,
- 0, TRUE,
- DUPLICATE_SAME_ACCESS);
+
+ close(childpipe[1]);
+
+ if(kpse->make_tex_discard_errors) {
+ Hnul = fopen("nul", "w");
+ if(!Hnul) {
+ perror("kpathsea: fopen(\"nul\")");
+ }
+ else {
+ hstderr = _dup(fileno(stderr));
+ _dup2(fileno(Hnul), fileno(stderr));
+ }
}
- si.hStdError = child_err;
-
- /* creating child process */
- if (CreateProcess(app_name, /* pointer to name of executable module */
- new_cmd, /* pointer to command line string */
- NULL, /* pointer to process security attributes */
- NULL, /* pointer to thread security attributes */
- TRUE, /* handle inheritance flag */
- 0, /* creation flags */
- NULL, /* pointer to environment */
- NULL, /* pointer to current directory */
- &si, /* pointer to STARTUPINFO */
- &pi /* pointer to PROCESS_INFORMATION */
- ) == 0) {
- LIB_FATAL2 ("kpathsea: CreateProcess() failed for `%s' (Error %d)\n",
- new_cmd, (int)(GetLastError()));
+ fprintf(stderr, "\nThe command name is %s\n", fullbin);
+ hchild = (HANDLE)spawnvp(_P_NOWAIT, fullbin, args);
+
+ _dup2(hstdout, fileno(stdout));
+ close(hstdout);
+
+ if((int)hchild == -1) {
+ fn = NULL;
+ close(childpipe[0]);
+ goto labeldone;
}
- CloseHandle(child_in);
- CloseHandle(father_out_dup);
- CloseHandle(child_err);
-
- /* Only the process handle is needed */
- CloseHandle(pi.hThread);
-
- /* Get stdout of child from the pipe. */
- fn = xstrdup("");
- while (ReadFile(father_in,buf,sizeof(buf)-1, &num, NULL) != 0
- && num > 0) {
- if (num <= 0) {
- if (GetLastError() != ERROR_BROKEN_PIPE) {
- LIB_FATAL2 ("kpathsea: read() error code for `%s' (Error %d)",
- new_cmd, (int)(GetLastError()));
- break;
+ if(hchild) {
+ char buf[1024+1];
+ int num;
+
+ fn = xstrdup("");
+ while(nexitcode == STILL_ACTIVE) {
+ num = read(childpipe[0], buf, sizeof(buf)-1);
+ if(num) {
+ string newfn;
+ buf[num] = '\0';
+ newfn = concat(fn, buf);
+ free(fn);
+ fn = newfn;
+ }
+ if(!GetExitCodeProcess((HANDLE)hchild, (unsigned long*)&nexitcode)) {
+ fn = NULL;
+ close(childpipe[0]);
+ goto labeldone;
}
- } else {
- string newfn;
- buf[num] = '\0';
- newfn = concat(fn, buf);
- free(fn);
- fn = newfn;
}
+ close(childpipe[0]);
}
- /* End of file on pipe, child should have exited at this point. */
- CloseHandle(father_in);
- if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) {
- WARNING2 ("kpathsea: process termination wait failed: %s (Error %d)\n",
- new_cmd, (int)(GetLastError()));
+ labeldone:
+ if(kpse->make_tex_discard_errors && Hnul) {
+ _dup2(hstderr, fileno(stderr));
+ close(hstderr);
+ fclose(Hnul);
}
- CloseHandle(pi.hProcess);
-
- if (new_cmd) free(new_cmd);
- if (app_name) free(app_name);
-
if (fn) {
len = strlen(fn);
@@ -323,16 +284,16 @@ maketex (kpathsea kpse, kpse_file_format_type format, string* args)
ret = len == 0 ? NULL : kpathsea_readable_file (kpse, fn);
if (!ret && len > 1) {
- WARNING2 ("kpathsea: %s output `%s' instead of a filename",
- new_cmd, fn);
+ WARNING2("kpathsea: %s output `%s' instead of a filename",
+ args[0], fn);
}
/* Free the name if we're not returning it. */
if (fn != ret)
free (fn);
+ } else {
+ ret = NULL;
}
- error_exit:
- ;
}
#else
{
@@ -454,6 +415,8 @@ maketex (kpathsea kpse, kpse_file_format_type format, string* args)
/* Free the name if we're not returning it. */
if (fn != ret)
free (fn);
+ } else {
+ ret = NULL;
}
}
#endif