]> code.delx.au - gnu-emacs/blobdiff - nt/cmdproxy.c
* lisp/progmodes/sql.el: Remove comment link to defunct viewcvs url.
[gnu-emacs] / nt / cmdproxy.c
index 0ca57abb5cad907412ad24ee285d0cff1ed7e682..4f2d113a900d9f07d4a0bccbea8170a7f2217465 100644 (file)
@@ -1,7 +1,8 @@
 /* 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, 2009, 2010  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
@@ -25,9 +26,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 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>
 
@@ -36,6 +35,9 @@ Boston, MA 02111-1307, USA.  */
 #include <stdlib.h>  /* getenv */
 #include <string.h>  /* strlen */
 
+/* We don't want to include stdio.h because we are already duplicating
+   lots of it here */
+extern int _snprintf (char *buffer, size_t count, const char *format, ...);
 
 /*******  Mock C library routines  *********************************/
 
@@ -158,6 +160,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 +232,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 +242,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 +274,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 +306,7 @@ make_absolute (char *prog)
 
       /* Move to the next directory.  */
       path = p + 1;
-    } 
+    }
 
   return NULL;
 }
@@ -321,7 +324,7 @@ setup_argv (void)
   char * cmdline = GetCommandLine ();
   int arg_bytes = 0;
 
-  
+
 }
 #endif
 
@@ -341,7 +344,7 @@ console_event_handler (DWORD event)
     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
@@ -383,7 +386,7 @@ spawn (char * progname, char * cmdline, char * dir, 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);
 
@@ -464,10 +467,20 @@ main (int argc, char ** argv)
   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
@@ -503,10 +516,10 @@ main (int argc, char ** argv)
     {
       ++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'))
@@ -521,7 +534,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.  */
@@ -594,6 +607,7 @@ main (int argc, char ** argv)
     {
       char * p;
       int    extra_arg_space = 0;
+      int    maxlen, remlen;
       int    run_command_dot_com;
 
       progname = getenv ("COMSPEC");
@@ -625,21 +639,27 @@ main (int argc, char ** argv)
             case path contains spaces (fortunately it can't contain
             quotes, since they are illegal in path names).  */
 
-         buf = p = alloca (strlen (progname) + extra_arg_space +
-                           strlen (cmdline) + 16);
+         remlen = maxlen =
+           strlen (progname) + extra_arg_space + strlen (cmdline) + 16;
+         buf = p = alloca (maxlen + 1);
 
          /* Quote progname in case it contains spaces.  */
-         p += wsprintf (p, "\"%s\"", progname);
+         p += _snprintf (p, remlen, "\"%s\"", progname);
+         remlen = maxlen - (p - buf);
 
          /* Include pass_through_args verbatim; these are just switches
              so should not need quoting.  */
          for (argv = pass_through_args; *argv != NULL; ++argv)
-           p += wsprintf (p, " %s", *argv);
+           {
+             p += _snprintf (p, remlen, " %s", *argv);
+             remlen = maxlen - (p - buf);
+           }
 
          if (run_command_dot_com)
-           wsprintf(p, " /e:%d /c %s", envsize, cmdline);
+           _snprintf (p, remlen, " /e:%d /c %s", envsize, cmdline);
          else
-           wsprintf(p, " /c %s", cmdline);
+           _snprintf (p, remlen, " /c %s", cmdline);
+         remlen = maxlen - (p - buf);
          cmdline = buf;
        }
       else
@@ -659,19 +679,27 @@ main (int argc, char ** argv)
          else
            path[0] = '\0';
 
-         cmdline = p = alloca (strlen (progname) + extra_arg_space +
-                               strlen (path) + 13);
+         remlen = maxlen =
+           strlen (progname) + extra_arg_space + strlen (path) + 13;
+         cmdline = p = alloca (maxlen + 1);
 
          /* Quote progname in case it contains spaces.  */
-         p += wsprintf (p, "\"%s\" %s", progname, path);
+         p += _snprintf (p, remlen, "\"%s\" %s", progname, path);
+         remlen = maxlen - (p - cmdline);
 
          /* Include pass_through_args verbatim; these are just switches
              so should not need quoting.  */
          for (argv = pass_through_args; *argv != NULL; ++argv)
-           p += wsprintf (p, " %s", *argv);
+           {
+             p += _snprintf (p, remlen, " %s", *argv);
+             remlen = maxlen - (p - cmdline);
+           }
 
          if (run_command_dot_com)
-           wsprintf (p, " /e:%d", envsize);
+           {
+             _snprintf (p, remlen, " /e:%d", envsize);
+             remlen = maxlen - (p - cmdline);
+           }
        }
     }
 
@@ -694,3 +722,6 @@ main (int argc, char ** argv)
 
   return 0;
 }
+
+/* arch-tag: 88678d93-07ac-4e2f-ad63-d4a740ca69ac
+   (do not change this comment) */