diff options
| author | Eli Zaretskii | 2015-04-23 10:15:07 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-04-23 10:15:07 +0300 |
| commit | f2e2cd5969ddfb8d0302e2ee82986fa4a79b5b69 (patch) | |
| tree | 31d151700baa5b044e3be7c744312e0c5a82af24 /src | |
| parent | 62fe329762301b4edf546e74893d9169906ffa96 (diff) | |
| download | emacs-f2e2cd5969ddfb8d0302e2ee82986fa4a79b5b69.tar.gz emacs-f2e2cd5969ddfb8d0302e2ee82986fa4a79b5b69.zip | |
Avoid starting threads by w32-shell-execute
* src/w32fns.c (Fw32_shell_execute): Convert "file:///" URLs into
local file names, before invoking ShellExecute. (Bug#20220)
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 6abb433fd2f..b9d7bd4d75b 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 29 | #include <fcntl.h> | 29 | #include <fcntl.h> |
| 30 | #include <unistd.h> | 30 | #include <unistd.h> |
| 31 | 31 | ||
| 32 | #include <c-ctype.h> | ||
| 33 | |||
| 32 | #include "lisp.h" | 34 | #include "lisp.h" |
| 33 | #include "w32term.h" | 35 | #include "w32term.h" |
| 34 | #include "frame.h" | 36 | #include "frame.h" |
| @@ -7038,7 +7040,28 @@ a ShowWindow flag: | |||
| 7038 | 7040 | ||
| 7039 | #else /* !CYGWIN */ | 7041 | #else /* !CYGWIN */ |
| 7040 | 7042 | ||
| 7041 | current_dir = ENCODE_FILE (current_dir); | 7043 | const char file_url_str[] = "file:///"; |
| 7044 | const int file_url_len = sizeof (file_url_str) - 1; | ||
| 7045 | if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) | ||
| 7046 | { | ||
| 7047 | /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to | ||
| 7048 | start a thread in some rare system configurations, for | ||
| 7049 | unknown reasons. That thread is started in the context of | ||
| 7050 | the Emacs process, but out of control of our code, and seems | ||
| 7051 | to never exit afterwards. Each such thread reserves 8MB of | ||
| 7052 | stack space (because that's the value recorded in the Emacs | ||
| 7053 | executable at link time: Emacs needs a large stack). So a | ||
| 7054 | large enough number of invocations of w32-shell-execute can | ||
| 7055 | potentially cause the Emacs process to run out of available | ||
| 7056 | address space, which is nasty. To work around this, we | ||
| 7057 | convert such URLs to local file names, which seems to prevent | ||
| 7058 | those threads from starting. See bug #20220. */ | ||
| 7059 | char *p = SSDATA (document) + file_url_len; | ||
| 7060 | |||
| 7061 | if (c_isalpha (*p) && p[1] == ':' && IS_DIRECTORY_SEP (p[2])) | ||
| 7062 | document = Fsubstring_no_properties (document, | ||
| 7063 | make_number (file_url_len), Qnil); | ||
| 7064 | } | ||
| 7042 | /* We have a situation here. If DOCUMENT is a relative file name, | 7065 | /* We have a situation here. If DOCUMENT is a relative file name, |
| 7043 | but its name includes leading directories, i.e. it lives not in | 7066 | but its name includes leading directories, i.e. it lives not in |
| 7044 | CURRENT_DIR, but in its subdirectory, then ShellExecute below | 7067 | CURRENT_DIR, but in its subdirectory, then ShellExecute below |
| @@ -7071,6 +7094,8 @@ a ShowWindow flag: | |||
| 7071 | else | 7094 | else |
| 7072 | document = ENCODE_FILE (document); | 7095 | document = ENCODE_FILE (document); |
| 7073 | UNGCPRO; | 7096 | UNGCPRO; |
| 7097 | |||
| 7098 | current_dir = ENCODE_FILE (current_dir); | ||
| 7074 | if (use_unicode) | 7099 | if (use_unicode) |
| 7075 | { | 7100 | { |
| 7076 | wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; | 7101 | wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; |