summaryrefslogtreecommitdiff
path: root/src/w32proc.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-06-27 13:48:26 +0300
committerEli Zaretskii <eliz@gnu.org>2015-06-27 13:48:26 +0300
commit31807189b55d9519a46e4b35fadbe20218e4ebea (patch)
treec2d926b9871ebb9788923c2fe2241670e903f423 /src/w32proc.c
parent5a7fb4f0cc5a21808ab6fa062050059ceac027e4 (diff)
downloademacs-31807189b55d9519a46e4b35fadbe20218e4ebea.tar.gz
Add a new function w32-application-type
* src/w32proc.c (Fw32_application_type): New function. ; * etc/NEWS: Mention w32-application-type.
Diffstat (limited to 'src/w32proc.c')
-rw-r--r--src/w32proc.c104
1 files changed, 89 insertions, 15 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index 1f633d834c2..b301fcf18ab 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1527,22 +1527,25 @@ waitpid (pid_t pid, int *status, int options)
/* Implementation note: This function works with file names encoded in
the current ANSI codepage. */
-static void
+static int
w32_executable_type (char * filename,
int * is_dos_app,
int * is_cygnus_app,
+ int * is_msys_app,
int * is_gui_app)
{
file_data executable;
char * p;
+ int retval = 0;
/* Default values in case we can't tell for sure. */
*is_dos_app = FALSE;
*is_cygnus_app = FALSE;
+ *is_msys_app = FALSE;
*is_gui_app = FALSE;
if (!open_input_file (&executable, filename))
- return;
+ return -1;
p = strrchr (filename, '.');
@@ -1560,7 +1563,8 @@ w32_executable_type (char * filename,
extension, which is defined in the registry. */
p = egetenv ("COMSPEC");
if (p)
- w32_executable_type (p, is_dos_app, is_cygnus_app, is_gui_app);
+ retval = w32_executable_type (p, is_dos_app, is_cygnus_app, is_msys_app,
+ is_gui_app);
}
else
{
@@ -1637,6 +1641,16 @@ w32_executable_type (char * filename,
*is_cygnus_app = TRUE;
break;
}
+ else if (strncmp (dllname, "msys-", 5) == 0)
+ {
+ /* This catches both MSYS 1.x and MSYS2
+ executables (the DLL name is msys-1.0.dll and
+ msys-2.0.dll, respectively). There's doesn't
+ seem to be a reason to distinguish between
+ the two, for now. */
+ *is_msys_app = TRUE;
+ break;
+ }
}
}
}
@@ -1644,6 +1658,7 @@ w32_executable_type (char * filename,
unwind:
close_file_data (&executable);
+ return retval;
}
static int
@@ -1702,7 +1717,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
int arglen, numenv;
pid_t pid;
child_process *cp;
- int is_dos_app, is_cygnus_app, is_gui_app;
+ int is_dos_app, is_cygnus_app, is_msys_app, is_gui_app;
int do_quoting = 0;
/* We pass our process ID to our children by setting up an environment
variable in their environment. */
@@ -1713,10 +1728,10 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
argument being split into two or more. Arguments with wildcards
are also quoted, for consistency with posix platforms, where wildcards
are not expanded if we run the program directly without a shell.
- Some extra whitespace characters need quoting in Cygwin programs,
+ Some extra whitespace characters need quoting in Cygwin/MSYS programs,
so this list is conditionally modified below. */
char *sepchars = " \t*?";
- /* This is for native w32 apps; modified below for Cygwin apps. */
+ /* This is for native w32 apps; modified below for Cygwin/MSUS apps. */
char escape_char = '\\';
char cmdname_a[MAX_PATH];
@@ -1777,15 +1792,17 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
cmdname = cmdname_a;
argv[0] = cmdname;
- /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows
- executable that is implicitly linked to the Cygnus dll (implying it
- was compiled with the Cygnus GNU toolchain and hence relies on
- cygwin.dll to parse the command line - we use this to decide how to
- escape quote chars in command line args that must be quoted).
+ /* Determine whether program is a 16-bit DOS executable, or a 32-bit
+ Windows executable that is implicitly linked to the Cygnus or
+ MSYS dll (implying it was compiled with the Cygnus/MSYS GNU
+ toolchain and hence relies on cygwin.dll or MSYS DLL to parse the
+ command line - we use this to decide how to escape quote chars in
+ command line args that must be quoted).
Also determine whether it is a GUI app, so that we don't hide its
initial window unless specifically requested. */
- w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_gui_app);
+ w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_msys_app,
+ &is_gui_app);
/* On Windows 95, if cmdname is a DOS app, we invoke a helper
application to start it by specifying the helper app as cmdname,
@@ -1845,10 +1862,10 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
if (INTEGERP (Vw32_quote_process_args))
escape_char = XINT (Vw32_quote_process_args);
else
- escape_char = is_cygnus_app ? '"' : '\\';
+ escape_char = (is_cygnus_app || is_msys_app) ? '"' : '\\';
}
- /* Cygwin apps needs quoting a bit more often. */
+ /* Cygwin/MSYS apps need quoting a bit more often. */
if (escape_char == '"')
sepchars = "\r\n\t\f '";
@@ -1866,7 +1883,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
for ( ; *p; p++)
{
if (escape_char == '"' && *p == '\\')
- /* If it's a Cygwin app, \ needs to be escaped. */
+ /* If it's a Cygwin/MSYS app, \ needs to be escaped. */
arglen++;
else if (*p == '"')
{
@@ -2947,6 +2964,59 @@ If successful, the return value is t, otherwise nil. */)
return result;
}
+DEFUN ("w32-application-type", Fw32_application_type,
+ Sw32_application_type, 1, 1, 0,
+ doc: /* Return the type of an MS-Windows PROGRAM.
+
+Knowing the type of an executable could be useful for formatting
+file names passed to it or for quoting its command-line arguments.
+
+PROGRAM should specify an executable file, including the extension.
+
+The value is one of the following:
+
+`dos' -- a DOS .com program or some other non-PE executable
+`cygwin' -- a Cygwin program that depends on Cygwin DLL
+`msys' -- an MSYS 1.x or MSYS2 program
+`w32-native' -- a native Windows application
+`unknown' -- a file that doesn't exist, or cannot be open, or whose
+ name is not encodable in the current ANSI codepage.
+
+Note that for .bat and .cmd batch files the function returns the type
+of their command interpreter, as specified by the \"COMSPEC\"
+environment variable.
+
+This function returns `unknown' for programs whose file names
+include characters not supported by the current ANSI codepage, as
+such programs cannot be invoked by Emacs anyway. */)
+ (Lisp_Object program)
+{
+ int is_dos_app, is_cygwin_app, is_msys_app, dummy;
+ Lisp_Object encoded_progname;
+ char *progname, progname_a[MAX_PATH];
+
+ program = Fexpand_file_name (program, Qnil);
+ encoded_progname = ENCODE_FILE (program);
+ progname = SDATA (encoded_progname);
+ unixtodos_filename (progname);
+ filename_to_ansi (progname, progname_a);
+ /* Reject file names that cannot be encoded in the current ANSI
+ codepage. */
+ if (_mbspbrk (progname_a, "?"))
+ return Qunknown;
+
+ if (w32_executable_type (progname_a, &is_dos_app, &is_cygwin_app,
+ &is_msys_app, &dummy) != 0)
+ return Qunknown;
+ if (is_dos_app)
+ return Qdos;
+ if (is_cygwin_app)
+ return Qcygwin;
+ if (is_msys_app)
+ return Qmsys;
+ return Qw32_native;
+}
+
#ifdef HAVE_LANGINFO_CODESET
/* Emulation of nl_langinfo. Used in fns.c:Flocale_info. */
char *
@@ -3541,6 +3611,9 @@ syms_of_ntproc (void)
{
DEFSYM (Qhigh, "high");
DEFSYM (Qlow, "low");
+ DEFSYM (Qcygwin, "cygwin");
+ DEFSYM (Qmsys, "msys");
+ DEFSYM (Qw32_native, "w32-native");
defsubr (&Sw32_has_winsock);
defsubr (&Sw32_unload_winsock);
@@ -3548,6 +3621,7 @@ syms_of_ntproc (void)
defsubr (&Sw32_short_file_name);
defsubr (&Sw32_long_file_name);
defsubr (&Sw32_set_process_priority);
+ defsubr (&Sw32_application_type);
defsubr (&Sw32_get_locale_info);
defsubr (&Sw32_get_current_locale_id);
defsubr (&Sw32_get_default_locale_id);