(fix_start_end_in_overlays): make overlays empty if they are backwards.
[bpt/emacs.git] / nt / runemacs.c
CommitLineData
c911543b
GV
1/*
2 Simple program to start Emacs with its console window hidden.
3
4 This program is provided purely for convenience, since most users will
5 use Emacs in windowing (GUI) mode, and will not want to have an extra
6 console window lying around. */
7
662463d9
RS
8/*
9 You may want to define this if you want to be able to install updated
10 emacs binaries even when other users are using the current version.
11 The problem with some file servers (notably Novell) is that an open
12 file cannot be overwritten, deleted, or even renamed. So if someone
13 is running emacs.exe already, you cannot install a newer version.
14 By defining CHOOSE_NEWEST_EXE, you can name your new emacs.exe
15 something else which matches "emacs*.exe", and runemacs will
16 automatically select the newest emacs executeable in the bin directory.
17 (So you'll probably be able to delete the old version some hours/days
18 later).
19*/
20
21/* #define CHOOSE_NEWEST_EXE */
22
c911543b
GV
23#include <windows.h>
24#include <string.h>
25#include <malloc.h>
26
27int WINAPI
28WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
29{
30 STARTUPINFO start;
31 SECURITY_ATTRIBUTES sec_attrs;
32 SECURITY_DESCRIPTOR sec_desc;
33 PROCESS_INFORMATION child;
34 int wait_for_child = FALSE;
05c4be3c 35 DWORD priority_class = NORMAL_PRIORITY_CLASS;
c911543b 36 DWORD ret_code = 0;
662463d9
RS
37 char *new_cmdline;
38 char *p;
c911543b
GV
39 char modname[MAX_PATH];
40
41 if (!GetModuleFileName (NULL, modname, MAX_PATH))
42 goto error;
43 if ((p = strrchr (modname, '\\')) == NULL)
44 goto error;
45 *p = 0;
46
0ac7bf6c
JR
47 new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 3);
48 /* Quote executable name in case of spaces in the path. */
49 *new_cmdline = '"';
50 strcpy (new_cmdline + 1, modname);
c911543b 51
662463d9 52#ifdef CHOOSE_NEWEST_EXE
c911543b 53 {
662463d9
RS
54 /* Silly hack to allow new versions to be installed on
55 server even when current version is in use. */
56
57 char * best_name = alloca (MAX_PATH + 1);
58 FILETIME best_time = {0,0};
59 WIN32_FIND_DATA wfd;
60 HANDLE fh;
61 p = new_cmdline + strlen (new_cmdline);
0ac7bf6c 62 strcpy (p, "\\emacs*.exe\" ");
662463d9
RS
63 fh = FindFirstFile (new_cmdline, &wfd);
64 if (fh == INVALID_HANDLE_VALUE)
65 goto error;
66 do
67 {
68 if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime
69 || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime
70 && wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime))
71 {
72 best_time = wfd.ftLastWriteTime;
73 strcpy (best_name, wfd.cFileName);
74 }
75 }
76 while (FindNextFile (fh, &wfd));
77 FindClose (fh);
78 *p++ = '\\';
79 strcpy (p, best_name);
80 strcat (p, " ");
c911543b 81 }
662463d9 82#else
0ac7bf6c 83 strcat (new_cmdline, "\\emacs.exe\" ");
662463d9
RS
84#endif
85
05c4be3c
GV
86 /* Append original arguments if any; first look for arguments we
87 recognise (-wait, -high, and -low), and apply them ourselves. */
88 while (cmdline[0] == '-' || cmdline[0] == '/')
662463d9 89 {
05c4be3c
GV
90 if (strncmp (cmdline+1, "wait", 4) == 0)
91 {
662463d9
RS
92 wait_for_child = TRUE;
93 cmdline += 5;
94 }
05c4be3c
GV
95 else if (strncmp (cmdline+1, "high", 4) == 0)
96 {
97 priority_class = HIGH_PRIORITY_CLASS;
98 cmdline += 5;
99 }
100 else if (strncmp (cmdline+1, "low", 3) == 0)
101 {
102 priority_class = IDLE_PRIORITY_CLASS;
103 cmdline += 4;
104 }
105 else
106 break;
107 }
c911543b
GV
108 strcat (new_cmdline, cmdline);
109
662463d9 110 /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin". */
c911543b 111 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
662463d9
RS
112 {
113 *p = 0;
114 for (p = modname; *p; p++)
115 if (*p == '\\') *p = '/';
116 SetEnvironmentVariable ("emacs_dir", modname);
117 }
c911543b
GV
118
119 memset (&start, 0, sizeof (start));
120 start.cb = sizeof (start);
121 start.dwFlags = STARTF_USESHOWWINDOW;
122 start.wShowWindow = SW_HIDE;
123
124 sec_attrs.nLength = sizeof (sec_attrs);
125 sec_attrs.lpSecurityDescriptor = NULL;
126 sec_attrs.bInheritHandle = FALSE;
127
05c4be3c 128 if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, priority_class,
17132120 129 GetEnvironmentStrings (), NULL, &start, &child))
c911543b
GV
130 {
131 if (wait_for_child)
132 {
133 WaitForSingleObject (child.hProcess, INFINITE);
134 GetExitCodeProcess (child.hProcess, &ret_code);
135 }
136 CloseHandle (child.hThread);
137 CloseHandle (child.hProcess);
138 }
139 else
140 goto error;
141 return (int) ret_code;
142
143error:
144 MessageBox (NULL, "Could not start Emacs.", "Error", MB_ICONSTOP);
145 return 1;
146}
ab5796a9
MB
147
148/* arch-tag: 7e02df73-4df7-4aa0-baea-99c6d047a384
149 (do not change this comment) */