comparison nt/runemacs.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents
children
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
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
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
23 #define WIN32
24
25 #include <windows.h>
26 #include <string.h>
27 #include <malloc.h>
28
29 #if defined(__CYGWIN32__)
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #endif
33
34 int WINAPI
35 WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
36 {
37 STARTUPINFO start;
38 SECURITY_ATTRIBUTES sec_attrs;
39 SECURITY_DESCRIPTOR sec_desc;
40 PROCESS_INFORMATION child;
41 int wait_for_child = FALSE;
42 DWORD ret_code = 0;
43 char *new_cmdline;
44 char *basename;
45 char *p;
46 char modname[MAX_PATH];
47
48 if (!GetModuleFileName (NULL, modname, MAX_PATH))
49 goto error;
50 if ((p = strrchr (modname, '\\')) == NULL)
51 goto error;
52
53 basename = alloca(strlen(p) + 1);
54 strcpy (basename, p + 1);
55
56 *p = 0;
57
58 new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 1);
59 strcpy (new_cmdline, modname);
60
61 #ifdef CHOOSE_NEWEST_EXE
62 {
63 /* Silly hack to allow new versions to be installed on
64 server even when current version is in use. */
65
66 char * best_name = alloca (MAX_PATH + 1);
67 FILETIME best_time = {0,0};
68 WIN32_FIND_DATA wfd;
69 HANDLE fh;
70 p = new_cmdline + strlen (new_cmdline);
71 strcpy (p, "\\xemacs*.exe ");
72 fh = FindFirstFile (new_cmdline, &wfd);
73 if (fh == INVALID_HANDLE_VALUE)
74 goto error;
75 do
76 {
77 if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime
78 || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime
79 && wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime))
80 {
81 best_time = wfd.ftLastWriteTime;
82 strcpy (best_name, wfd.cFileName);
83 }
84 }
85 while (FindNextFile (fh, &wfd));
86 FindClose (fh);
87 *p++ = '\\';
88 strcpy (p, best_name);
89 strcat (p, " ");
90 }
91 #else
92 #if defined(__CYGWIN32__)
93 {
94 struct stat stbuf;
95 char sym_link_name[MAX_PATH+1], real_name[MAX_PATH+1];
96
97 strcpy(sym_link_name, new_cmdline);
98 if (strcmp(basename, "rungnuclient.exe") == 0)
99 strcat(new_cmdline, "\\gnuclient.exe ");
100 else if (strcmp(basename, "runemacs.exe") == 0)
101 {
102 strcat(sym_link_name, "\\xemacs");
103
104 if (lstat(sym_link_name, &stbuf) == 0)
105 {
106 if ((stbuf.st_mode & S_IFLNK) == S_IFLNK)
107 {
108 if (readlink(sym_link_name, real_name, sizeof(real_name)) == -1)
109 {
110 MessageBox (NULL, "Error reading symbolic link for xemacs",
111 "Error", MB_ICONSTOP);
112 return 1;
113 }
114 else
115 {
116 strcat(new_cmdline, "\\");
117 strcat(new_cmdline, real_name);
118 strcat(new_cmdline, " ");
119 }
120 }
121 else
122 strcat(new_cmdline, "\\xemacs ");
123 }
124 else
125 {
126 MessageBox (NULL, "can't locate XEmacs executable",
127 "Error", MB_ICONSTOP);
128 return 1;
129 }
130 }
131 }
132 #else
133 if (strcmp(basename, "rungnuclient.exe") == 0)
134 strcat (new_cmdline, "\\gnuclient.exe ");
135 else
136 strcat (new_cmdline, "\\xemacs.exe ");
137 #endif
138 #endif
139
140 /* Append original arguments if any; first look for -wait as first
141 argument, and apply that ourselves. */
142 if (strncmp (cmdline, "-wait", 5) == 0)
143 {
144 wait_for_child = TRUE;
145 cmdline += 5;
146 }
147 strcat (new_cmdline, cmdline);
148
149 /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin". */
150 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
151 {
152 *p = 0;
153 for (p = modname; *p; p++)
154 if (*p == '\\') *p = '/';
155 SetEnvironmentVariable ("emacs_dir", modname);
156 }
157
158 memset (&start, 0, sizeof (start));
159 start.cb = sizeof (start);
160 start.dwFlags = STARTF_USESHOWWINDOW;
161 start.wShowWindow = SW_HIDE;
162
163 sec_attrs.nLength = sizeof (sec_attrs);
164 sec_attrs.lpSecurityDescriptor = NULL;
165 sec_attrs.bInheritHandle = FALSE;
166
167 if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, 0,
168 NULL, NULL, &start, &child))
169 {
170 if (wait_for_child)
171 {
172 WaitForSingleObject (child.hProcess, INFINITE);
173 GetExitCodeProcess (child.hProcess, &ret_code);
174 }
175 CloseHandle (child.hThread);
176 CloseHandle (child.hProcess);
177 }
178 else
179 goto error;
180 return (int) ret_code;
181
182 error:
183 MessageBox (NULL, "Could not start XEmacs or gnuclient.", "Error", MB_ICONSTOP);
184 return 1;
185 }