X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/1d7d10d1fc36b8bba908c0cb09160d7a7d3c3780..2e8195083823ba5ba044343389bd39adc9f48072:/nt/cmdproxy.c diff --git a/nt/cmdproxy.c b/nt/cmdproxy.c index 312d6f6b3c..631570b9d5 100644 --- a/nt/cmdproxy.c +++ b/nt/cmdproxy.c @@ -1,5 +1,6 @@ /* Proxy shell designed for use with Emacs on Windows 95 and NT. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008 Free Software Foundation, Inc. Accepts subset of Unix sh(1) command-line options, for compatability with elisp code written for Unix. When possible, executes external @@ -16,7 +17,7 @@ This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -26,8 +27,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #include @@ -158,6 +159,7 @@ get_next_token (char * buf, char ** pSrc) if (p[0] == escape_char && escape_char != '"') { escape_char_run++; + p++; continue; } else if (p[0] == '"') @@ -229,7 +231,7 @@ search_dir (char *dir, char *exec, int bufsize, char *buffer) int i, rc; /* Search the directory for the program. */ - for (i = 0; i < n_exts; i++) + for (i = 0; i < n_exts; i++) { rc = SearchPath (dir, exec, exts[i], bufsize, buffer, &dummy); if (rc > 0) @@ -239,7 +241,7 @@ search_dir (char *dir, char *exec, int bufsize, char *buffer) return 0; } -/* Return the absolute name of executable file PROG, including +/* Return the absolute name of executable file PROG, including any file extensions. If an absolute name for PROG cannot be found, return NULL. */ char * @@ -271,18 +273,18 @@ make_absolute (char *prog) return NULL; } - if (GetCurrentDirectory (MAX_PATH, curdir) <= 0) + if (GetCurrentDirectory (MAX_PATH, curdir) <= 0) return NULL; /* Relative path; search in current dir. */ - if (strpbrk (prog, "\\")) + if (strpbrk (prog, "\\")) { if (search_dir (curdir, prog, MAX_PATH, absname) > 0) return strdup (absname); - else + else return NULL; } - + /* Just filename; search current directory then PATH. */ path = alloca (strlen (getenv ("PATH")) + strlen (curdir) + 2); strcpy (path, curdir); @@ -303,7 +305,7 @@ make_absolute (char *prog) /* Move to the next directory. */ path = p + 1; - } + } return NULL; } @@ -321,7 +323,7 @@ setup_argv (void) char * cmdline = GetCommandLine (); int arg_bytes = 0; - + } #endif @@ -369,7 +371,7 @@ console_event_handler (DWORD event) /* Change from normal usage; return value indicates whether spawn succeeded or failed - program return code is returned separately. */ int -spawn (char * progname, char * cmdline, int * retcode) +spawn (char * progname, char * cmdline, char * dir, int * retcode) { BOOL success = FALSE; SECURITY_ATTRIBUTES sec_attrs; @@ -383,12 +385,12 @@ spawn (char * progname, char * cmdline, int * retcode) sec_attrs.nLength = sizeof (sec_attrs); sec_attrs.lpSecurityDescriptor = NULL; sec_attrs.bInheritHandle = FALSE; - + memset (&start, 0, sizeof (start)); start.cb = sizeof (start); if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE, - 0, envblock, NULL, &start, &child)) + 0, envblock, dir, &start, &child)) { success = TRUE; /* wait for completion and pass on return code */ @@ -432,12 +434,16 @@ main (int argc, char ** argv) int num_pass_through_args; char modname[MAX_PATH]; char path[MAX_PATH]; + char dir[MAX_PATH]; interactive = TRUE; SetConsoleCtrlHandler ((PHANDLER_ROUTINE) console_event_handler, TRUE); + if (!GetCurrentDirectory (sizeof (dir), dir)) + fail ("error: GetCurrentDirectory failed\n"); + /* We serve double duty: we can be called either as a proxy for the real shell (that is, because we are defined to be the user shell), or in our role as a helper application for running DOS programs. @@ -453,16 +459,33 @@ main (int argc, char ** argv) if (!GetModuleFileName (NULL, modname, sizeof (modname))) fail ("error: GetModuleFileName failed\n"); + /* Change directory to location of .exe so startup directory can be + deleted. */ + progname = strrchr (modname, '\\'); + *progname = '\0'; + SetCurrentDirectory (modname); + *progname = '\\'; + + /* Due to problems with interaction between API functions that use "OEM" + codepage vs API functions that use the "ANSI" codepage, we need to + make things consistent by choosing one and sticking with it. */ + SetConsoleCP (GetACP()); + SetConsoleOutputCP (GetACP()); + /* Although Emacs always sets argv[0] to an absolute pathname, we might get run in other ways as well, so convert argv[0] to an - absolute name before comparing to the module name. */ + absolute name before comparing to the module name. Don't get + caught out by mixed short and long names. */ + GetShortPathName (modname, modname, sizeof (modname)); + path[0] = '\0'; if (!SearchPath (NULL, argv[0], ".exe", sizeof (path), path, &progname) + || !GetShortPathName (path, path, sizeof (path)) || stricmp (modname, path) != 0) { /* We are being used as a helper to run a DOS app; just pass command line to DOS app without change. */ /* TODO: fill in progname. */ - if (spawn (NULL, GetCommandLine (), &rc)) + if (spawn (NULL, GetCommandLine (), dir, &rc)) return rc; fail ("Could not run %s\n", GetCommandLine ()); } @@ -510,7 +533,7 @@ main (int argc, char ** argv) if (cmdline) warn ("warning: %s ignored because of -c\n", *argv); } - else if (((*argv)[1] == 'e' || (*argv[1] == 'E')) && ((*argv)[2] == ':')) + else if (((*argv)[1] == 'e' || (*argv)[1] == 'E') && ((*argv)[2] == ':')) { int requested_envsize = atoi (*argv + 3); /* Enforce a reasonable minimum size, as above. */ @@ -583,6 +606,7 @@ main (int argc, char ** argv) { char * p; int extra_arg_space = 0; + int run_command_dot_com; progname = getenv ("COMSPEC"); if (!progname) @@ -594,6 +618,10 @@ main (int argc, char ** argv) if (progname == NULL || strchr (progname, '\\') == NULL) fail ("error: the program %s could not be found.\n", getenv ("COMSPEC")); + /* Need to set environment size when running command.com. */ + run_command_dot_com = + (stricmp (strrchr (progname, '\\'), "command.com") == 0); + /* Work out how much extra space is required for pass_through_args. */ for (argv = pass_through_args; *argv != NULL; ++argv) @@ -620,8 +648,7 @@ main (int argc, char ** argv) for (argv = pass_through_args; *argv != NULL; ++argv) p += wsprintf (p, " %s", *argv); - if (GetVersion () & 0x80000000) - /* Set environment size to something reasonable on Windows 95. */ + if (run_command_dot_com) wsprintf(p, " /e:%d /c %s", envsize, cmdline); else wsprintf(p, " /c %s", cmdline); @@ -629,12 +656,10 @@ main (int argc, char ** argv) } else { - if (GetVersion () & 0x80000000) + if (run_command_dot_com) { /* Provide dir arg expected by command.com when first - started interactively (the "command search path"). - cmd.exe does not require it, but accepts it silently - - presumably other DOS compatible shells do the same. To + started interactively (the "command search path"). To avoid potential problems with spaces in command dir (which cannot be quoted - command.com doesn't like it), we always use the 8.3 form. */ @@ -644,7 +669,6 @@ main (int argc, char ** argv) *(++p) = '\0'; } else - /* Dir arg not needed on NT. */ path[0] = '\0'; cmdline = p = alloca (strlen (progname) + extra_arg_space + @@ -658,8 +682,7 @@ main (int argc, char ** argv) for (argv = pass_through_args; *argv != NULL; ++argv) p += wsprintf (p, " %s", *argv); - if (GetVersion () & 0x80000000) - /* Set environment size to something reasonable on Windows 95. */ + if (run_command_dot_com) wsprintf (p, " /e:%d", envsize); } } @@ -670,7 +693,7 @@ main (int argc, char ** argv) if (!cmdline) cmdline = progname; - if (spawn (progname, cmdline, &rc)) + if (spawn (progname, cmdline, dir, &rc)) return rc; if (!need_shell) @@ -683,3 +706,6 @@ main (int argc, char ** argv) return 0; } + +/* arch-tag: 88678d93-07ac-4e2f-ad63-d4a740ca69ac + (do not change this comment) */