/* 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
+ Accepts subset of Unix sh(1) command-line options, for compatibility
with elisp code written for Unix. When possible, executes external
programs directly (a common use of /bin/sh by Emacs), otherwise
invokes the user-specified command processor to handle built-in shell
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+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)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <windows.h>
if (p[0] == escape_char && escape_char != '"')
{
escape_char_run++;
+ p++;
continue;
}
else if (p[0] == '"')
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)
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 *
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);
/* Move to the next directory. */
path = p + 1;
- }
+ }
return NULL;
}
char * cmdline = GetCommandLine ();
int arg_bytes = 0;
-
+
}
#endif
case CTRL_BREAK_EVENT:
if (!interactive)
{
- /* Both command.com and cmd.exe have the annoying behaviour of
+ /* Both command.com and cmd.exe have the annoying behavior of
prompting "Terminate batch job (y/n)?" when interrupted
while running a batch file, even if running in
non-interactive (-c) mode. Try to make up for this
/* 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;
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 */
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.
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 ());
}
{
++argv;
/* Act on switches we recognize (mostly single letter switches,
- except for -e); all unrecognised switches and extra args are
+ except for -e); all unrecognized switches and extra args are
passed on to real shell if used (only really of benefit for
interactive use, but allow for batch use as well). Accept / as
- switch char for compatability with cmd.exe. */
+ switch char for compatibility with cmd.exe. */
if (((*argv)[0] == '-' || (*argv)[0] == '/') && (*argv)[1] != '\0')
{
if (((*argv)[1] == 'c' || (*argv)[1] == 'C') && ((*argv)[2] == '\0'))
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. */
if (!cmdline)
cmdline = progname;
- if (spawn (progname, cmdline, &rc))
+ if (spawn (progname, cmdline, dir, &rc))
return rc;
if (!need_shell)
return 0;
}
+
+/* arch-tag: 88678d93-07ac-4e2f-ad63-d4a740ca69ac
+ (do not change this comment) */