summaryrefslogtreecommitdiff
path: root/Build/source/texk/kpathsea/win32lib.c
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2013-01-28 15:08:54 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2013-01-28 15:08:54 +0000
commit6eb4e4fd92e16d8e86fe34efa288c39269e91269 (patch)
treeed7755e0b4956d2dc4e0c4ec9a827f5744fb26cd /Build/source/texk/kpathsea/win32lib.c
parent514749b8e48e8f9dbf83252adb1cbd0b9335c016 (diff)
Simplify win32_popen.
git-svn-id: svn://tug.org/texlive/trunk@28966 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/kpathsea/win32lib.c')
-rw-r--r--Build/source/texk/kpathsea/win32lib.c675
1 files changed, 5 insertions, 670 deletions
diff --git a/Build/source/texk/kpathsea/win32lib.c b/Build/source/texk/kpathsea/win32lib.c
index 5741c953e81..dc7980cf963 100644
--- a/Build/source/texk/kpathsea/win32lib.c
+++ b/Build/source/texk/kpathsea/win32lib.c
@@ -21,267 +21,20 @@
#include <kpathsea/variable.h>
#include <kpathsea/c-stat.h>
-FILE * __cdecl kpathsea_win32_popen (kpathsea kpse, const char *cmd, const char *fmode)
+FILE * win32_popen (const char *cmd, const char *fmode)
{
char mode[3];
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
- FILE *f = NULL;
- int fno, i;
- HANDLE child_in, child_out;
- HANDLE father_in, father_out;
- HANDLE father_in_dup, father_out_dup;
- HANDLE current_in, current_out;
- HANDLE current_pid;
- char *env_path;
- int binary_mode;
- char *new_cmd, *app_name = NULL;
- char *p, *q;
- struct _popen_elt *new_process;
- char pname[MAXPATHLEN], *fp;
- char *suffixes[] = { ".bat", ".cmd", ".com", ".exe", NULL };
- char **s;
- BOOL go_on;
-
- /* We always use binary mode */
mode[0] = fmode[0];
mode[1] = 'b';
mode[2] = '\0';
- /* We should look for the application name along the PATH,
- and decide to prepend "%COMSPEC% /c " or not to the command line.
- Do nothing for the moment. */
-
- /* Another way to do that would be to try CreateProcess first without
- invoking cmd, and look at the error code. If it fails because of
- command not found, try to prepend "cmd /c" to the cmd line.
- */
- /* Look for the application name */
- for (p = (char *)cmd; *p && isspace(*p); p++);
- if (*p == '"') {
- q = ++p;
- while(*p && *p != '"') p++;
- if (*p == '\0') {
- fprintf(stderr, "popen: malformed command (\" not terminated)\n");
- return NULL;
- }
- }
- else
- for (q = p; *p && !isspace(*p); p++);
- /* q points to the beginning of appname, p to the last + 1 char */
- if ((app_name = malloc(p - q + 1)) == NULL) {
- fprintf(stderr, "xpopen: malloc(app_name) failed.\n");
- return NULL;
- }
- strncpy(app_name, q, p - q );
- app_name[p - q] = '\0';
- pname[0] = '\0';
-#ifdef TRACE
- fprintf(stderr, "popen: app_name = %s\n", app_name);
-#endif
-
- {
- char *tmp = getenv("PATH");
- env_path = xmalloc(strlen(tmp) + 3);
- strcpy(env_path, tmp);
- strcat(env_path, ";.");
- }
-
- /* Looking for appname on the path */
- for (s = suffixes, go_on = TRUE; go_on; s++) {
- if (SearchPath(env_path, /* Address of search path */
- app_name, /* Address of filename */
- *s, /* Address of extension */
- MAXPATHLEN, /* Size of destination buffer */
- pname, /* Address of destination buffer */
- &fp) /* File part of app_name */
- != 0 && *s) { /* added *s in order not to allow no suffix.
- --ak 2009/10/24 */
-#ifdef TRACE
- fprintf(stderr, "%s found with suffix %s\nin %s\n", app_name, *s, pname);
-#endif
- new_cmd = xstrdup(cmd);
- free(app_name);
- app_name = xstrdup(pname);
- break;
- }
- go_on = (*s != NULL);
- }
- if (go_on == FALSE) {
- /* the app_name was not found */
-#ifdef TRACE
- fprintf(stderr, "%s not found, concatenating comspec\n", app_name);
-#endif
- new_cmd = concatn("cmd.exe", " /c ", cmd, NULL);
- free(app_name);
- app_name = NULL;
- }
- if (env_path) free(env_path);
-
-#ifdef TRACE
- fprintf(stderr, "popen: app_name = %s\n", app_name);
- fprintf(stderr, "popen: cmd_line = %s\n", new_cmd);
-#endif
- current_in = GetStdHandle(STD_INPUT_HANDLE);
- current_out = GetStdHandle(STD_OUTPUT_HANDLE);
- current_pid = GetCurrentProcess();
- ZeroMemory( &si, sizeof(STARTUPINFO) );
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
-
- if (strchr(mode, 'b'))
- binary_mode = _O_BINARY;
- else
- binary_mode = _O_TEXT;
-
- /* Opening the pipe for writing */
- if (strchr(mode, 'w')) {
- binary_mode |= _O_WRONLY;
- if (CreatePipe(&child_in, &father_out, &sa, 0) == FALSE) {
- fprintf(stderr, "popen: error CreatePipe\n");
- return NULL;
- }
-
- si.hStdInput = child_in;
- si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
- if (DuplicateHandle(current_pid, father_out,
- current_pid, &father_out_dup,
- 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) {
- fprintf(stderr, "popen: error DuplicateHandle father_out\n");
- return NULL;
- }
- CloseHandle(father_out);
- fno = _open_osfhandle((long)father_out_dup, binary_mode);
- f = _fdopen(fno, mode);
- i = setvbuf( f, NULL, _IONBF, 0 );
- }
- /* Opening the pipe for reading */
- else if (strchr(mode, 'r')) {
- binary_mode |= _O_RDONLY;
- if (CreatePipe(&father_in, &child_out, &sa, 0) == FALSE) {
- fprintf(stderr, "popen: error CreatePipe\n");
- return NULL;
- }
-
- si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- si.hStdOutput = child_out;
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
- if (DuplicateHandle(current_pid, father_in,
- current_pid, &father_in_dup,
- 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) {
- fprintf(stderr, "popen: error DuplicateHandle father_in\n");
- return NULL;
- }
- CloseHandle(father_in);
- fno = _open_osfhandle((long)father_in_dup, binary_mode);
- f = _fdopen(fno, mode);
- i = setvbuf( f, NULL, _IONBF, 0 );
- }
- else {
- fprintf(stderr, "popen: invalid mode %s\n", mode);
- return NULL;
- }
-
- /* 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, do not touch this again ! (16/06/98) */
- NULL, /* pointer to environment */
- NULL, /* pointer to current directory */
- &si, /* pointer to STARTUPINFO */
- &pi /* pointer to PROCESS_INFORMATION */
- ) == FALSE) {
- fprintf(stderr, "popen: CreateProcess %x\n", GetLastError());
- return NULL;
- }
-
- /* Only the process handle is needed */
- if (CloseHandle(pi.hThread) == FALSE) {
- fprintf(stderr, "popen: error closing thread handle\n");
- return NULL;
- }
-
- if (new_cmd) free(new_cmd);
- if (app_name) free(app_name);
-
- /* Add the pair (f, pi.hProcess) to the list */
- if ((new_process = malloc(sizeof(struct _popen_elt))) == NULL) {
- fprintf (stderr, "popen: malloc(new_process) error\n");
- return NULL;
- }
- /* Saving the FILE * pointer, access key for retrieving the process
- handle later on */
- new_process->f = f;
- /* Closing the unnecessary part of the pipe */
- if (strchr(mode, 'r')) {
- CloseHandle(child_out);
- }
- else if (strchr(mode, 'w')) {
- CloseHandle(child_in);
- }
- /* Saving the process handle */
- new_process->hp = pi.hProcess;
- /* Linking it to the list of popen() processes */
- new_process->next = kpse->_popen_list;
- kpse->_popen_list = new_process;
-
- return f;
-
+ return _popen (cmd, mode);
}
-int __cdecl kpathsea_win32_pclose (kpathsea kpse, FILE *f)
+int win32_pclose (FILE *f)
{
- struct _popen_elt *p, *q;
- int exit_code;
-
- /* Look for f is the access key in the linked list */
- for (q = NULL, p = kpse->_popen_list;
- p != &kpse->_z_p_open && p->f != f;
- q = p, p = p->next);
-
- if (p == &kpse->_z_p_open) {
- fprintf(stderr, "pclose: error, file not found.");
- return -1;
- }
-
- /* Closing the FILE pointer */
- fclose(f);
-
- /* Waiting for the process to terminate */
- if (WaitForSingleObject(p->hp, INFINITE) != WAIT_OBJECT_0) {
- fprintf(stderr, "pclose: error, process still active\n");
- return -1;
- }
-
- /* retrieving the exit code */
- if (GetExitCodeProcess(p->hp, &exit_code) == 0) {
- fprintf(stderr, "pclose: can't get process exit code\n");
- return -1;
- }
-
- /* Closing the process handle, this will cause the system to
- remove the process from memory */
- if (CloseHandle(p->hp) == FALSE) {
- fprintf(stderr, "pclose: error closing process handle\n");
- return -1;
- }
-
- /* remove the elt from the list */
- if (q != NULL)
- q->next = p->next;
- else
- kpse->_popen_list = p->next;
- free(p);
-
- return exit_code;
+ return _pclose (f);
}
/* large file support */
@@ -571,414 +324,6 @@ kpathsea_init_user_info (kpathsea kpse)
strcpy (kpse->the_passwd.pw_shell, getenv ("SHELL"));
}
-/*
- Command parser. Borrowed from DJGPP.
- */
-
-typedef enum {
- EMPTY,
- WORDARG,
- REDIR_INPUT,
- REDIR_APPEND,
- REDIR_OUTPUT,
- PIPE,
- SEMICOLON,
- UNMATCHED_QUOTE,
- EOL
-} cmd_sym_t;
-
-/* Return a copy of a word between BEG and (excluding) END with all
- quoting characters removed from it. */
-
-static char *
-kpathsea__unquote (kpathsea kpse, char *to, const char *beg, const char *end)
-{
- const char *s = beg;
- char *d = to;
- int quote = 0;
-
- while (s < end)
- {
- switch (*s)
- {
- case '"':
- case '\'':
- if (!quote)
- quote = *s;
- else if (quote == *s)
- quote = 0;
- s++;
- break;
- case '\\':
- if (s[1] == '"' || s[1] == '\''
- || (s[1] == ';'
- && (kpse->__system_allow_multiple_cmds)))
- s++;
- /* Fall-through. */
- default:
- *d++ = *s++;
- break;
- }
- }
-
- *d = 0;
- return to;
-}
-
-/* A poor-man's lexical analyzer for simplified command processing.
-
- It only knows about these:
-
- redirection and pipe symbols
- semi-colon `;' (that possibly ends a command)
- argument quoting rules with quotes and `\'
- whitespace delimiters of words (except in quoted args)
-
- Returns the type of next symbol and pointers to its first and (one
- after) the last characters.
-
- Only `get_sym' and `unquote' should know about quoting rules. */
-
-static cmd_sym_t
-kpathsea_get_sym (kpathsea kpse, char *s, char **beg, char **end)
-{
- int in_a_word = 0;
-
- while (isspace (*s))
- s++;
-
- *beg = s;
-
- do {
- *end = s + 1;
-
- if (in_a_word
- && (!*s || strchr ("<>| \t\n", *s)
- || ((kpse->__system_allow_multiple_cmds) && *s == ';')))
- {
- --*end;
- return WORDARG;
- }
-
- switch (*s)
- {
- case '<':
- return REDIR_INPUT;
- case '>':
- if (**end == '>')
- {
- ++*end;
- return REDIR_APPEND;
- }
- return REDIR_OUTPUT;
- case '|':
- return PIPE;
- case ';':
- if (kpse->__system_allow_multiple_cmds)
- return SEMICOLON;
- else
- in_a_word = 1;
- break;
- case '\0':
- --*end;
- return EOL;
- case '\\':
- if (s[1] == '"' || s[1] == '\''
- || (s[1] == ';' && (kpse->__system_allow_multiple_cmds)))
- s++;
- in_a_word = 1;
- break;
- case '\'':
- case '"':
- {
- char quote = *s++;
-
- while (*s && *s != quote)
- {
- if (*s++ == '\\' && (*s == '"' || *s == '\''))
- s++;
- }
- *end = s;
- if (!*s)
- return UNMATCHED_QUOTE;
- in_a_word = 1;
- break;
- }
- default:
- in_a_word = 1;
- break;
- }
-
- s++;
-
- } while (1);
-}
-
-/*
- What we allow :
- [cmd] [arg1] ... [argn] < [redinput] | [cmd2] | ... | [cmdn] > [redoutput]
-*/
-void *kpathsea_parse_cmdline(kpathsea kpse, char *line, char **input,
- char **output, int *is_cmd_pipe)
-{
- BOOL again, needcmd = TRUE, bSuccess = TRUE, append_out = FALSE;
- char *beg = line, *end, *new_end;
- cmd_sym_t token = EMPTY, prev_token = EMPTY;
- int ncmd = 0, narg = 1;
- char **fp;
- char ***cmd;
- char *dummy_input; /* So that we could pass NULL */
- char *dummy_output; /* instead of a real ??put */
-
- if (input == NULL) input = &dummy_input;
- if (output == NULL) output = &dummy_output;
-
- *input = NULL;
- *output = NULL;
- cmd = xmalloc(MAX_PIPES*sizeof(char **));
- cmd[ncmd] = NULL;
-#ifdef TRACE
- fprintf(stderr, "line = %s\n", line);
-#endif
- do {
- again = FALSE;
- prev_token = token;
- token = kpathsea_get_sym (kpse, beg, &beg, &end); /* get next symbol */
-#ifdef TRACE
- fprintf(stderr, "token = %s\n", beg);
-#endif
- switch (token) {
- case WORDARG:
- if (prev_token == REDIR_INPUT
- || prev_token == REDIR_OUTPUT) {
- fprintf(stderr, "Ambigous input/output redirect.");
- bSuccess = FALSE;
- goto leave;
- }
- /* First word we see is the program to run. */
- if (needcmd) {
- narg = 1;
- cmd[ncmd] = xmalloc(narg * sizeof(char *));
- cmd[ncmd][narg - 1] = xmalloc(end - beg + 1);
- kpathsea__unquote (kpse, cmd[ncmd][narg - 1], beg, end);
- /* unquote and copy to prog */
- if (cmd[ncmd][narg - 1][0] == '(') {
- fprintf(stderr, "parse_cmdline(%s): Parenthesized groups not allowed.\n", line);
- bSuccess = FALSE;
- goto leave;
- }
- needcmd = FALSE;
- }
- else {
- narg++;
- cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
- cmd[ncmd][narg - 1] = xmalloc(end - beg + 1);
- kpathsea__unquote (kpse, cmd[ncmd][narg - 1], beg, end);
- /* unquote and copy to prog */
- }
- beg = end; /* go forward */
- again = TRUE;
- break;
-
- case REDIR_INPUT:
- case REDIR_OUTPUT:
- case REDIR_APPEND:
- if (token == REDIR_INPUT) {
- if (*input) {
- fprintf(stderr, "Ambiguous input redirect.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- }
- fp = input;
- }
- else if (token == REDIR_OUTPUT || token == REDIR_APPEND) {
- if (*output) {
- fprintf(stderr, "Ambiguous output redirect.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- }
- fp = output;
- if (token == REDIR_APPEND)
- append_out = TRUE;
- }
- if (kpathsea_get_sym (kpse, end, &end, &new_end) != WORDARG) {
- fprintf(stderr, "Target of redirect is not a filename.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- }
- *fp = (char *)xmalloc (new_end - end + 1);
- memcpy (*fp, end, new_end - end);
- (*fp)[new_end - end] = '\0';
- beg = new_end;
- again = TRUE;
- break;
- case PIPE:
- *is_cmd_pipe = 1; /* --ak 2009/07/08 */
- if (*output) {
- fprintf(stderr, "Ambiguous output redirect.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- }
- narg++;
- cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
- cmd[ncmd][narg - 1] = NULL;
- ncmd++;
- needcmd = TRUE;
- beg = end;
- again = TRUE;
- break;
- case SEMICOLON:
- case EOL:
- if (needcmd) {
- fprintf(stderr, "No command name seen.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- }
- narg++;
- cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
- cmd[ncmd][narg - 1] = NULL;
- ncmd++;
- cmd[ncmd] = NULL;
- again = FALSE;
- break;
-
- case UNMATCHED_QUOTE:
- fprintf(stderr, "Unmatched quote character.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
- default:
- fprintf(stderr, "I cannot grok this.");
- errno = EINVAL;
- bSuccess = FALSE;
- goto leave;
-
- }
-
- } while (again);
-
- leave:
- if (!bSuccess) {
- int i;
- char **p;
- /* Need to free everything that was allocated */
- for (i = 0; i < ncmd; i++) {
- for (p = cmd[i]; *p; p++)
- free(*p);
- free(cmd[i]);
- }
- if (cmd[ncmd]) {
- for (i = 0; i < narg; i++)
- free(cmd[ncmd][i]);
- free(cmd[ncmd]);
- }
- free(cmd);
- *cmd = NULL;
- }
- return cmd;
-}
-
-static int need_qq(char c)
-{
- int ret;
- ret = ((c=='&') ||
- (c=='(') ||
- (c==')') ||
- (c=='[') ||
- (c==']') ||
- (c=='{') ||
- (c=='}') ||
- (c=='^') ||
- (c==';') ||
- (c=='!') ||
- (c=='\'') ||
- (c=='+') ||
- (c=='`') ||
- (c=='~') ||
- (c=='%') ||
- (c=='@'));
- return ret;
-}
-
-static char *
-quote_elt(char *elt)
-{
- char *p;
- int qok;
-
- if(!strcmp(elt,"|") ||
- !strcmp(elt,"||") ||
- !strcmp(elt,"&") ||
- !strcmp(elt,"&&") ||
- !strcmp(elt,";")) {
- qok = 0;
- } else {
- qok = 1;
- }
- for (p = elt; *p; p++)
- if (isspace(*p) || (need_qq(*p) && qok))
- return concat3("\"", elt, "\"");
-
- return xstrdup(elt);
-}
-
-static char *
-quote_args(char **argv)
-{
- int i;
- char *line = NULL, *new_line;
- char *new_argv;
-
- if (!argv)
- return line;
-
- line = quote_elt(argv[0]);
- for (i = 1; argv[i]; i++) {
- new_argv = quote_elt(argv[i]);
- new_line = concat3(line, " ", new_argv);
- free(line);
- free(new_argv);
- line = new_line;
- }
-
- return line;
-}
-
-char *
-build_cmdline(char ***cmd, char *input, char *output)
-{
- int ncmd;
- char *line = NULL, *new_line;
-
- if (!cmd)
- return line;
-
- line = quote_args(cmd[0]);
- if (input) {
- new_line = concat3(line, "<", quote_elt(input));
- free(line);
- line = new_line;
- }
- for(ncmd = 1; cmd[ncmd]; ncmd++) {
- new_line = concat3(line, " | ", quote_args(cmd[ncmd]));
- free(line);
- line = new_line;
- }
-
- if (output) {
- new_line = concat3(line, ">", quote_elt(output));
- free(line);
- line = new_line;
- }
-
- return line;
-}
-
/* win32_system */
static int is_include_space(const char *s)
{
@@ -990,7 +335,7 @@ static int is_include_space(const char *s)
return 0;
}
-int __cdecl win32_system(const char *cmd)
+int win32_system(const char *cmd)
{
const char *p;
char *q;
@@ -1028,16 +373,6 @@ int __cdecl win32_system(const char *cmd)
}
#if defined (KPSE_COMPAT_API)
-FILE * __cdecl win32_popen (const char *cmd, const char *mode)
-{
- return kpathsea_win32_popen(kpse_def, cmd, mode);
-}
-
-int __cdecl win32_pclose (FILE *f)
-{
- return kpathsea_win32_pclose(kpse_def, f);
-}
-
int
getuid (void)
{