comparison src/nt.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 de805c49cfc1
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
23 23
24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */ 24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
25 /* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */ 25 /* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
26 26
27 #include <config.h> 27 #include <config.h>
28
29 #undef signal
28 #define getwd _getwd 30 #define getwd _getwd
29 #include "lisp.h" 31 #include "lisp.h"
30 #undef getwd 32 #undef getwd
31 33
32 #include "systime.h" 34 #include "systime.h"
33 #include "syssignal.h" 35 #include "syssignal.h"
34 #include "sysproc.h" 36 #include "sysproc.h"
35 #include "sysfile.h" 37 #include "sysfile.h"
36 #include "syspwd.h" 38
37 #include "sysdir.h" 39 #include <ctype.h>
38 40 #include <direct.h>
39 #include "syswindows.h" 41 #include <errno.h>
42 #include <fcntl.h>
43 #include <io.h>
44 #include <pwd.h>
45 #include <signal.h>
46 #include <stddef.h> /* for offsetof */
47 #include <string.h>
48 #include <stdlib.h>
49 #include <stdio.h>
50
51 #include <windows.h>
52 #ifndef __MINGW32__
53 #include <mmsystem.h>
54 #else
55 typedef void (CALLBACK TIMECALLBACK)(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
56
57 typedef TIMECALLBACK FAR *LPTIMECALLBACK;
58 DWORD WINAPI timeGetTime(void);
59 MMRESULT WINAPI timeSetEvent(UINT uDelay, UINT uResolution,
60 LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);
61 MMRESULT WINAPI timeKillEvent(UINT uTimerID);
62 MMRESULT WINAPI timeGetDevCaps(TIMECAPS* ptc, UINT cbtc);
63 MMRESULT WINAPI timeBeginPeriod(UINT uPeriod);
64 MMRESULT WINAPI timeEndPeriod(UINT uPeriod);
65 #endif
40 66
41 #include "nt.h" 67 #include "nt.h"
68 #include <sys/dir.h>
42 #include "ntheap.h" 69 #include "ntheap.h"
43 70
44 71
45 extern Lisp_Object Vmswindows_downcase_file_names; 72 extern Lisp_Object Vmswindows_downcase_file_names;
46 #if 0 73 #if 0
47 extern Lisp_Object Vwin32_generate_fake_inodes; 74 extern Lisp_Object Vwin32_generate_fake_inodes;
48 #endif 75 #endif
49 extern Lisp_Object Vmswindows_get_true_file_attributes; 76 extern Lisp_Object Vmswindows_get_true_file_attributes;
50 77
51 int nt_fake_unix_uid; 78 extern char *get_home_directory(void);
52 79
53 static char startup_dir[ MAXPATHLEN ]; 80 static char startup_dir[ MAXPATHLEN ];
54 81
55 /* Get the current working directory. */ 82 /* Get the current working directory. */
56 char * 83 char *
103 the_passwd_gecos, 130 the_passwd_gecos,
104 the_passwd_dir, 131 the_passwd_dir,
105 the_passwd_shell, 132 the_passwd_shell,
106 }; 133 };
107 134
108 uid_t 135 int
109 getuid (void) 136 getuid ()
110 {
111 return nt_fake_unix_uid;
112 }
113
114 uid_t
115 geteuid (void)
116 { 137 {
117 return nt_fake_unix_uid; 138 return the_passwd.pw_uid;
118 } 139 }
119 140
120 gid_t 141 int
121 getgid (void) 142 geteuid ()
143 {
144 /* I could imagine arguing for checking to see whether the user is
145 in the Administrators group and returning a UID of 0 for that
146 case, but I don't know how wise that would be in the long run. */
147 return getuid ();
148 }
149
150 int
151 getgid ()
122 { 152 {
123 return the_passwd.pw_gid; 153 return the_passwd.pw_gid;
124 } 154 }
125 155
126 gid_t 156 int
127 getegid (void) 157 getegid ()
128 { 158 {
129 return getgid (); 159 return getgid ();
130 } 160 }
131 161
132 struct passwd * 162 struct passwd *
133 getpwuid (uid_t uid) 163 getpwuid (int uid)
134 { 164 {
135 if (uid == nt_fake_unix_uid) 165 if (uid == the_passwd.pw_uid)
136 { 166 return &the_passwd;
137 the_passwd.pw_gid = the_passwd.pw_uid = uid; 167 return NULL;
138 return &the_passwd;
139 }
140 else
141 return NULL;
142 } 168 }
143 169
144 struct passwd * 170 struct passwd *
145 getpwnam (const char *name) 171 getpwnam (const char *name)
146 { 172 {
155 181
156 return pw; 182 return pw;
157 } 183 }
158 184
159 void 185 void
160 init_user_info (void) 186 init_user_info ()
161 { 187 {
162 /* This code is pretty much of ad hoc nature. There is no unix-like
163 UIDs under Windows NT. There is no concept of root user, because
164 all security is ACL-based. Instead, let's use a simple variable,
165 nt-fake-unix-uid, which would allow the user to have a uid of
166 choice. --kkm, 02/03/2000 */
167 #if 0
168 /* Find the user's real name by opening the process token and 188 /* Find the user's real name by opening the process token and
169 looking up the name associated with the user-sid in that token. 189 looking up the name associated with the user-sid in that token.
170 190
171 Use the relative portion of the identifier authority value from 191 Use the relative portion of the identifier authority value from
172 the user-sid as the user id value (same for group id using the 192 the user-sid as the user id value (same for group id using the
238 strcpy (the_passwd.pw_name, "unknown"); 258 strcpy (the_passwd.pw_name, "unknown");
239 the_passwd.pw_uid = 123; 259 the_passwd.pw_uid = 123;
240 the_passwd.pw_gid = 123; 260 the_passwd.pw_gid = 123;
241 } 261 }
242 262
243 if (token)
244 CloseHandle (token);
245 #else
246 /* Obtain only logon id here, uid part is moved to getuid */
247 char name[256];
248 DWORD length = sizeof (name);
249 if (GetUserName (name, &length))
250 strcpy (the_passwd.pw_name, name);
251 else
252 strcpy (the_passwd.pw_name, "unknown");
253 #endif
254
255 /* Ensure HOME and SHELL are defined. */ 263 /* Ensure HOME and SHELL are defined. */
256 #if 0 264 #if 0
257 /* 265 /*
258 * With XEmacs, setting $HOME is deprecated. 266 * With XEmacs, setting $HOME is deprecated.
259 */ 267 */
262 #endif 270 #endif
263 if (getenv ("SHELL") == NULL) 271 if (getenv ("SHELL") == NULL)
264 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); 272 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
265 273
266 /* Set dir and shell from environment variables. */ 274 /* Set dir and shell from environment variables. */
267 strcpy (the_passwd.pw_dir, (char *)get_home_directory()); 275 strcpy (the_passwd.pw_dir, get_home_directory());
268 strcpy (the_passwd.pw_shell, getenv ("SHELL")); 276 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
277
278 if (token)
279 CloseHandle (token);
269 } 280 }
270 281
271 /* Normalize filename by converting all path separators to 282 /* Normalize filename by converting all path separators to
272 the specified separator. Also conditionally convert upper 283 the specified separator. Also conditionally convert upper
273 case path name components to lower case. */ 284 case path name components to lower case. */
274 285
275 static void 286 static void
276 normalize_filename (char *fp, char path_sep) 287 normalize_filename (fp, path_sep)
288 REGISTER char *fp;
289 char path_sep;
277 { 290 {
278 char sep; 291 char sep;
279 char *elem; 292 char *elem;
280 293
281 /* Always lower-case drive letters a-z, even if the filesystem 294 /* Always lower-case drive letters a-z, even if the filesystem
327 } while (*fp++); 340 } while (*fp++);
328 } 341 }
329 342
330 /* Destructively turn backslashes into slashes. */ 343 /* Destructively turn backslashes into slashes. */
331 void 344 void
332 dostounix_filename (char *p) 345 dostounix_filename (p)
346 REGISTER char *p;
333 { 347 {
334 normalize_filename (p, '/'); 348 normalize_filename (p, '/');
335 } 349 }
336 350
337 /* Destructively turn slashes into backslashes. */ 351 /* Destructively turn slashes into backslashes. */
338 void 352 void
339 unixtodos_filename (char *p) 353 unixtodos_filename (p)
354 REGISTER char *p;
340 { 355 {
341 normalize_filename (p, '\\'); 356 normalize_filename (p, '\\');
342 } 357 }
343 358
344 /* Remove all CR's that are followed by a LF. 359 /* Remove all CR's that are followed by a LF.
345 (From msdos.c...probably should figure out a way to share it, 360 (From msdos.c...probably should figure out a way to share it,
346 although this code isn't going to ever change.) */ 361 although this code isn't going to ever change.) */
347 int 362 int
348 crlf_to_lf (int n, unsigned char *buf, unsigned *lf_count) 363 crlf_to_lf (n, buf, lf_count)
364 REGISTER int n;
365 REGISTER unsigned char *buf;
366 REGISTER unsigned *lf_count;
349 { 367 {
350 unsigned char *np = buf; 368 unsigned char *np = buf;
351 unsigned char *startp = buf; 369 unsigned char *startp = buf;
352 unsigned char *endp = buf + n; 370 unsigned char *endp = buf + n;
353 371
520 #endif /* 0 */ 538 #endif /* 0 */
521 539
522 #define REG_ROOT "SOFTWARE\\GNU\\XEmacs" 540 #define REG_ROOT "SOFTWARE\\GNU\\XEmacs"
523 541
524 LPBYTE 542 LPBYTE
525 nt_get_resource (char *key, LPDWORD lpdwtype) 543 nt_get_resource (key, lpdwtype)
544 char *key;
545 LPDWORD lpdwtype;
526 { 546 {
527 LPBYTE lpvalue; 547 LPBYTE lpvalue;
528 HKEY hrootkey = NULL; 548 HKEY hrootkey = NULL;
529 DWORD cbData; 549 DWORD cbData;
530 550
565 585
566 return (NULL); 586 return (NULL);
567 } 587 }
568 588
569 void 589 void
570 init_environment (void) 590 init_environment ()
571 { 591 {
572 /* Check for environment variables and use registry if they don't exist */ 592 /* Check for environment variables and use registry if they don't exist */
573 { 593 {
574 int i; 594 int i;
575 LPBYTE lpval; 595 LPBYTE lpval;
587 "EMACSPATH", 607 "EMACSPATH",
588 "EMACSPACKAGEPATH", 608 "EMACSPACKAGEPATH",
589 "EMACSLOCKDIR", 609 "EMACSLOCKDIR",
590 "INFOPATH" 610 "INFOPATH"
591 }; 611 };
592 #if defined (HEAP_IN_DATA) && !defined(PDUMP) 612
593 cache_system_info ();
594 #endif
595 for (i = 0; i < countof (env_vars); i++) 613 for (i = 0; i < countof (env_vars); i++)
596 { 614 {
597 if (!getenv (env_vars[i]) && 615 if (!getenv (env_vars[i]) &&
598 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL) 616 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL)
599 { 617 {
1061 dir_is_fat = is_fat_volume (filename, NULL); 1079 dir_is_fat = is_fat_volume (filename, NULL);
1062 1080
1063 return dirp; 1081 return dirp;
1064 } 1082 }
1065 1083
1066 int 1084 void
1067 closedir (DIR *dirp) 1085 closedir (DIR *dirp)
1068 { 1086 {
1069 BOOL retval;
1070
1071 /* If we have a find-handle open, close it. */ 1087 /* If we have a find-handle open, close it. */
1072 if (dir_find_handle != INVALID_HANDLE_VALUE) 1088 if (dir_find_handle != INVALID_HANDLE_VALUE)
1073 { 1089 {
1074 retval = FindClose (dir_find_handle); 1090 FindClose (dir_find_handle);
1075 dir_find_handle = INVALID_HANDLE_VALUE; 1091 dir_find_handle = INVALID_HANDLE_VALUE;
1076 } 1092 }
1077 xfree (dirp); 1093 xfree (dirp);
1078 if (retval)
1079 return 0;
1080 else
1081 return -1;
1082 } 1094 }
1083 1095
1084 struct direct * 1096 struct direct *
1085 readdir (DIR *dirp) 1097 readdir (DIR *dirp)
1086 { 1098 {
1189 return rename (temp, newname); 1201 return rename (temp, newname);
1190 } 1202 }
1191 #endif /* 0 */ 1203 #endif /* 0 */
1192 1204
1193 static FILETIME utc_base_ft; 1205 static FILETIME utc_base_ft;
1206 static long double utc_base;
1194 static int init = 0; 1207 static int init = 0;
1195
1196 #if 0
1197
1198 static long double utc_base;
1199 1208
1200 time_t 1209 time_t
1201 convert_time (FILETIME ft) 1210 convert_time (FILETIME ft)
1202 { 1211 {
1203 long double ret; 1212 long double ret;
1226 1235
1227 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime; 1236 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1228 ret -= utc_base; 1237 ret -= utc_base;
1229 return (time_t) (ret * 1e-7); 1238 return (time_t) (ret * 1e-7);
1230 } 1239 }
1231 #else 1240
1232 1241 #if 0
1233 #if defined(MINGW) && CYGWIN_VERSION_DLL_MAJOR <= 21 1242 /* in case we ever have need of this */
1234 #define LowPart u.LowPart 1243 void
1235 #define HighPart u.HighPart 1244 convert_from_time_t (time_t time, FILETIME * pft)
1236 #endif 1245 {
1237 1246 long double tmp;
1238 static LARGE_INTEGER utc_base_li;
1239
1240 time_t
1241 convert_time (FILETIME uft)
1242 {
1243 time_t ret;
1244 #ifndef MAXLONGLONG
1245 SYSTEMTIME st;
1246 struct tm t;
1247 FILETIME ft;
1248 TIME_ZONE_INFORMATION tzi;
1249 DWORD tzid;
1250 #else
1251 LARGE_INTEGER lft;
1252 #endif
1253 1247
1254 if (!init) 1248 if (!init)
1255 { 1249 {
1256 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ 1250 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1257 SYSTEMTIME st; 1251 SYSTEMTIME st;
1263 st.wMinute = 0; 1257 st.wMinute = 0;
1264 st.wSecond = 0; 1258 st.wSecond = 0;
1265 st.wMilliseconds = 0; 1259 st.wMilliseconds = 0;
1266 1260
1267 SystemTimeToFileTime (&st, &utc_base_ft); 1261 SystemTimeToFileTime (&st, &utc_base_ft);
1268
1269 utc_base_li.LowPart = utc_base_ft.dwLowDateTime;
1270 utc_base_li.HighPart = utc_base_ft.dwHighDateTime;
1271
1272 init = 1;
1273 }
1274
1275 #ifdef MAXLONGLONG
1276
1277 /* On a compiler that supports long integers, do it the easy way */
1278 lft.LowPart = uft.dwLowDateTime;
1279 lft.HighPart = uft.dwHighDateTime;
1280 ret = (time_t) ((lft.QuadPart - utc_base_li.QuadPart) / 10000000);
1281
1282 #else
1283
1284 /* Do it the hard way using mktime. */
1285 FileTimeToLocalFileTime(&uft, &ft);
1286 FileTimeToSystemTime (&ft, &st);
1287 tzid = GetTimeZoneInformation (&tzi);
1288 t.tm_year = st.wYear - 1900;
1289 t.tm_mon = st.wMonth - 1;
1290 t.tm_mday = st.wDay;
1291 t.tm_hour = st.wHour;
1292 t.tm_min = st.wMinute;
1293 t.tm_sec = st.wSecond;
1294 t.tm_isdst = (tzid == TIME_ZONE_ID_DAYLIGHT);
1295 /* st.wMilliseconds not applicable */
1296 ret = mktime(&t);
1297 if (ret == -1)
1298 {
1299 ret = 0;
1300 }
1301
1302 #endif
1303
1304 return ret;
1305 }
1306 #endif
1307 #if defined(MINGW) && CYGWIN_VERSION_DLL_MAJOR <= 21
1308 #undef LowPart
1309 #undef HighPart
1310 #endif
1311
1312 #if 0
1313 /* in case we ever have need of this */
1314 void
1315 convert_from_time_t (time_t time, FILETIME * pft)
1316 {
1317 long double tmp;
1318
1319 if (!init)
1320 {
1321 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1322 SYSTEMTIME st;
1323
1324 st.wYear = 1970;
1325 st.wMonth = 1;
1326 st.wDay = 1;
1327 st.wHour = 0;
1328 st.wMinute = 0;
1329 st.wSecond = 0;
1330 st.wMilliseconds = 0;
1331
1332 SystemTimeToFileTime (&st, &utc_base_ft);
1333 utc_base = (long double) utc_base_ft.dwHighDateTime 1262 utc_base = (long double) utc_base_ft.dwHighDateTime
1334 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime; 1263 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1335 init = 1; 1264 init = 1;
1336 } 1265 }
1337 1266
1383 return hashval (p); 1312 return hashval (p);
1384 } 1313 }
1385 1314
1386 #endif 1315 #endif
1387 1316
1388 /* #### aichner@ecf.teradyne.com reported that with the library
1389 provided stat/fstat, (file-exist "d:\\tmp\\") =>> nil,
1390 (file-exist "d:\\tmp") =>> t, when d:\tmp exists. Whenever
1391 we opt to use non-encapsulated stat(), this should serve as
1392 a compatibility test. --kkm */
1393
1394 /* Since stat is encapsulated on Windows NT, we need to encapsulate
1395 the equally broken fstat as well. */
1396 int
1397 mswindows_fstat (int handle, struct stat *buffer)
1398 {
1399 int ret;
1400 BY_HANDLE_FILE_INFORMATION lpFileInfo;
1401 /* Initialize values */
1402 buffer->st_mode = 0;
1403 buffer->st_size = 0;
1404 buffer->st_dev = 0;
1405 buffer->st_rdev = 0;
1406 buffer->st_atime = 0;
1407 buffer->st_ctime = 0;
1408 buffer->st_mtime = 0;
1409 buffer->st_nlink = 0;
1410 ret = GetFileInformationByHandle((HANDLE) _get_osfhandle(handle), &lpFileInfo);
1411 if (!ret)
1412 {
1413 return -1;
1414 }
1415 else
1416 {
1417 buffer->st_mtime = convert_time (lpFileInfo.ftLastWriteTime);
1418 buffer->st_atime = convert_time (lpFileInfo.ftLastAccessTime);
1419 if (buffer->st_atime == 0) buffer->st_atime = buffer->st_mtime;
1420 buffer->st_ctime = convert_time (lpFileInfo.ftCreationTime);
1421 if (buffer->st_ctime == 0) buffer->st_ctime = buffer->st_mtime;
1422 buffer->st_size = lpFileInfo.nFileSizeLow;
1423 buffer->st_nlink = (short) lpFileInfo.nNumberOfLinks;
1424 return 0;
1425 }
1426 }
1427
1428 /* MSVC stat function can't cope with UNC names and has other bugs, so 1317 /* MSVC stat function can't cope with UNC names and has other bugs, so
1429 replace it with our own. This also allows us to calculate consistent 1318 replace it with our own. This also allows us to calculate consistent
1430 inode values without hacks in the main Emacs code. */ 1319 inode values without hacks in the main Emacs code. */
1431 int 1320 int
1432 mswindows_stat (const char * path, struct stat * buf) 1321 stat (const char * path, struct stat * buf)
1433 { 1322 {
1434 char * name; 1323 char * name;
1435 WIN32_FIND_DATA wfd; 1324 WIN32_FIND_DATA wfd;
1436 HANDLE fh; 1325 HANDLE fh;
1437 DWORD fake_inode; 1326 DWORD fake_inode;
1457 directory of a drive or UNC volume in which case ensure there 1346 directory of a drive or UNC volume in which case ensure there
1458 is a trailing separator. */ 1347 is a trailing separator. */
1459 len = strlen (name); 1348 len = strlen (name);
1460 rootdir = (path >= name + len - 1 1349 rootdir = (path >= name + len - 1
1461 && (IS_DIRECTORY_SEP (*path) || *path == 0)); 1350 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1462 name = strcpy ((char *)alloca (len + 2), name); 1351 name = strcpy (alloca (len + 2), name);
1463 1352
1464 if (rootdir) 1353 if (rootdir)
1465 { 1354 {
1466 if (!IS_DIRECTORY_SEP (name[len-1])) 1355 if (!IS_DIRECTORY_SEP (name[len-1]))
1467 strcat (name, "\\"); 1356 strcat (name, "\\");
1575 1464
1576 /* #### MSVC defines _ino_t to be short; other libc's might not. */ 1465 /* #### MSVC defines _ino_t to be short; other libc's might not. */
1577 buf->st_ino = (unsigned short) (fake_inode ^ (fake_inode >> 16)); 1466 buf->st_ino = (unsigned short) (fake_inode ^ (fake_inode >> 16));
1578 1467
1579 /* consider files to belong to current user */ 1468 /* consider files to belong to current user */
1580 buf->st_uid = buf->st_gid = nt_fake_unix_uid; 1469 buf->st_uid = the_passwd.pw_uid;
1470 buf->st_gid = the_passwd.pw_gid;
1581 1471
1582 /* volume_info is set indirectly by map_win32_filename */ 1472 /* volume_info is set indirectly by map_win32_filename */
1583 buf->st_dev = volume_info.serialnum; 1473 buf->st_dev = volume_info.serialnum;
1584 buf->st_rdev = volume_info.serialnum; 1474 buf->st_rdev = volume_info.serialnum;
1475
1585 1476
1586 buf->st_size = wfd.nFileSizeLow; 1477 buf->st_size = wfd.nFileSizeLow;
1587 1478
1588 /* Convert timestamps to Unix format. */ 1479 /* Convert timestamps to Unix format. */
1589 buf->st_mtime = convert_time (wfd.ftLastWriteTime); 1480 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1653 term_ntproc (int unused) 1544 term_ntproc (int unused)
1654 { 1545 {
1655 } 1546 }
1656 1547
1657 void 1548 void
1658 init_ntproc (void) 1549 init_ntproc ()
1659 { 1550 {
1660 /* Initial preparation for subprocess support: replace our standard 1551 /* Initial preparation for subprocess support: replace our standard
1661 handles with non-inheritable versions. */ 1552 handles with non-inheritable versions. */
1662 { 1553 {
1663 HANDLE parent; 1554 HANDLE parent;
1786 unsigned signal_block_mask = 0; 1677 unsigned signal_block_mask = 0;
1787 1678
1788 /* Signal pending mask: bit set to 1 means sig is pending */ 1679 /* Signal pending mask: bit set to 1 means sig is pending */
1789 unsigned signal_pending_mask = 0; 1680 unsigned signal_pending_mask = 0;
1790 1681
1791 mswindows_sighandler mswindows_sigset (int nsig, mswindows_sighandler handler) 1682 msw_sighandler msw_sigset (int nsig, msw_sighandler handler)
1792 { 1683 {
1793 /* We delegate some signals to the system function */ 1684 /* We delegate some signals to the system function */
1794 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) 1685 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT)
1795 return signal (nsig, handler); 1686 return signal (nsig, handler);
1796 1687
1800 return NULL; 1691 return NULL;
1801 } 1692 }
1802 1693
1803 /* Store handler ptr */ 1694 /* Store handler ptr */
1804 { 1695 {
1805 mswindows_sighandler old_handler = signal_handlers[nsig]; 1696 msw_sighandler old_handler = signal_handlers[nsig];
1806 signal_handlers[nsig] = handler; 1697 signal_handlers[nsig] = handler;
1807 return old_handler; 1698 return old_handler;
1808 } 1699 }
1809 } 1700 }
1810 1701
1811 int mswindows_sighold (int nsig) 1702 int msw_sighold (int nsig)
1812 { 1703 {
1813 if (nsig < 0 || nsig > SIG_MAX) 1704 if (nsig < 0 || nsig > SIG_MAX)
1814 return errno = EINVAL; 1705 return errno = EINVAL;
1815 1706
1816 signal_block_mask |= sigmask(nsig); 1707 signal_block_mask |= sigmask(nsig);
1817 return 0; 1708 return 0;
1818 } 1709 }
1819 1710
1820 int mswindows_sigrelse (int nsig) 1711 int msw_sigrelse (int nsig)
1821 { 1712 {
1822 if (nsig < 0 || nsig > SIG_MAX) 1713 if (nsig < 0 || nsig > SIG_MAX)
1823 return errno = EINVAL; 1714 return errno = EINVAL;
1824 1715
1825 signal_block_mask &= ~sigmask(nsig); 1716 signal_block_mask &= ~sigmask(nsig);
1826 1717
1827 if (signal_pending_mask & sigmask(nsig)) 1718 if (signal_pending_mask & sigmask(nsig))
1828 mswindows_raise (nsig); 1719 msw_raise (nsig);
1829 1720
1830 return 0; 1721 return 0;
1831 } 1722 }
1832 1723
1833 int mswindows_sigpause (int nsig) 1724 int msw_sigpause (int nsig)
1834 { 1725 {
1835 /* This is currently not called, because the only 1726 /* This is currently not called, because the only
1836 call to sigpause inside XEmacs is with SIGCHLD 1727 call to sigpause inside XEmacs is with SIGCHLD
1837 parameter. Just in case, we put an assert here, 1728 parameter. Just in case, we put an assert here,
1838 so anyone who will add a call to sigpause will 1729 so anyone who will add a call to sigpause will
1839 be surprised (or surprise someone else...) */ 1730 be surprised (or surprise someone else...) */
1840 assert (0); 1731 assert (0);
1841 return 0; 1732 return 0;
1842 } 1733 }
1843 1734
1844 int mswindows_raise (int nsig) 1735 int msw_raise (int nsig)
1845 { 1736 {
1846 /* We delegate some raises to the system routine */ 1737 /* We delegate some raises to the system routine */
1847 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) 1738 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT)
1848 return raise (nsig); 1739 return raise (nsig);
1849 1740
1905 1796
1906 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser, 1797 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser,
1907 DWORD dw1, DWORD dw2) 1798 DWORD dw1, DWORD dw2)
1908 { 1799 {
1909 /* Just raise a signal indicated by dwUser parameter */ 1800 /* Just raise a signal indicated by dwUser parameter */
1910 mswindows_raise (dwUser); 1801 msw_raise (dwUser);
1911 } 1802 }
1912 1803
1913 /* Divide time in ms specified by IT by DENOM. Return 1 ms 1804 /* Divide time in ms specified by IT by DENOM. Return 1 ms
1914 if division results in zero */ 1805 if division results in zero */
1915 static UINT period (const struct itimerval* it, UINT denom) 1806 static UINT period (const struct itimerval* it, UINT denom)
1988 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); 1879 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF);
1989 else 1880 else
1990 return errno = EINVAL; 1881 return errno = EINVAL;
1991 } 1882 }
1992 1883
1993
1994 /*--------------------------------------------------------------------*/
1995 /* Memory-mapped files */
1996 /*--------------------------------------------------------------------*/
1997
1998 int 1884 int
1999 open_input_file (file_data *p_file, const char *filename) 1885 open_input_file (file_data *p_file, CONST char *filename)
2000 { 1886 {
2001 /* Synched with FSF 20.6. We fixed some warnings. */
2002 HANDLE file; 1887 HANDLE file;
2003 HANDLE file_mapping; 1888 HANDLE file_mapping;
2004 void *file_base; 1889 void *file_base;
2005 DWORD size, upper_size; 1890 DWORD size, upper_size;
2006 1891
2017 1902
2018 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); 1903 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
2019 if (file_base == 0) 1904 if (file_base == 0)
2020 return FALSE; 1905 return FALSE;
2021 1906
2022 p_file->name = (char *)filename; 1907 p_file->name = (char*)filename;
2023 p_file->size = size; 1908 p_file->size = size;
2024 p_file->file = file; 1909 p_file->file = file;
2025 p_file->file_mapping = file_mapping; 1910 p_file->file_mapping = file_mapping;
2026 p_file->file_base = (char *)file_base; 1911 p_file->file_base = file_base;
2027 1912
2028 return TRUE; 1913 return TRUE;
2029 }
2030
2031 int
2032 open_output_file (file_data *p_file, const char *filename, unsigned long size)
2033 {
2034 /* Synched with FSF 20.6. We fixed some warnings. */
2035 HANDLE file;
2036 HANDLE file_mapping;
2037 void *file_base;
2038
2039 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2040 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2041 if (file == INVALID_HANDLE_VALUE)
2042 return FALSE;
2043
2044 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
2045 0, size, NULL);
2046 if (!file_mapping)
2047 return FALSE;
2048
2049 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
2050 if (file_base == NULL)
2051 return FALSE;
2052
2053 p_file->name = filename;
2054 p_file->size = size;
2055 p_file->file = file;
2056 p_file->file_mapping = file_mapping;
2057 p_file->file_base = (char*) file_base;
2058
2059 return TRUE;
2060 }
2061
2062 #if 1 /* !defined(MINGW) */
2063 /* Return pointer to section header for section containing the given
2064 relative virtual address. */
2065 static IMAGE_SECTION_HEADER *
2066 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
2067 {
2068 /* Synched with FSF 20.6. We added MINGW stuff. */
2069 PIMAGE_SECTION_HEADER section;
2070 int i;
2071
2072 section = IMAGE_FIRST_SECTION (nt_header);
2073
2074 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
2075 {
2076 /* Some linkers (eg. the NT SDK linker I believe) swapped the
2077 meaning of these two values - or rather, they ignored
2078 VirtualSize entirely and always set it to zero. This affects
2079 some very old exes (eg. gzip dated Dec 1993). Since
2080 mswindows_executable_type relies on this function to work reliably,
2081 we need to cope with this. */
2082 DWORD real_size = max (section->SizeOfRawData,
2083 section->Misc.VirtualSize);
2084 if (rva >= section->VirtualAddress
2085 && rva < section->VirtualAddress + real_size)
2086 return section;
2087 section++;
2088 }
2089 return NULL;
2090 }
2091 #endif
2092
2093 void
2094 mswindows_executable_type (const char * filename, int * is_dos_app,
2095 int * is_cygnus_app)
2096 {
2097 /* Synched with FSF 20.6. We added MINGW stuff and casts. */
2098 file_data executable;
2099 char * p;
2100
2101 /* Default values in case we can't tell for sure. */
2102 *is_dos_app = FALSE;
2103 *is_cygnus_app = FALSE;
2104
2105 if (!open_input_file (&executable, filename))
2106 return;
2107
2108 p = strrchr (filename, '.');
2109
2110 /* We can only identify DOS .com programs from the extension. */
2111 if (p && stricmp (p, ".com") == 0)
2112 *is_dos_app = TRUE;
2113 else if (p && (stricmp (p, ".bat") == 0 ||
2114 stricmp (p, ".cmd") == 0))
2115 {
2116 /* A DOS shell script - it appears that CreateProcess is happy to
2117 accept this (somewhat surprisingly); presumably it looks at
2118 COMSPEC to determine what executable to actually invoke.
2119 Therefore, we have to do the same here as well. */
2120 /* Actually, I think it uses the program association for that
2121 extension, which is defined in the registry. */
2122 p = egetenv ("COMSPEC");
2123 if (p)
2124 mswindows_executable_type (p, is_dos_app, is_cygnus_app);
2125 }
2126 else
2127 {
2128 /* Look for DOS .exe signature - if found, we must also check that
2129 it isn't really a 16- or 32-bit Windows exe, since both formats
2130 start with a DOS program stub. Note that 16-bit Windows
2131 executables use the OS/2 1.x format. */
2132
2133 #if 0 /* defined( MINGW ) */
2134 /* mingw32 doesn't have enough headers to detect cygwin
2135 apps, just do what we can. */
2136 FILHDR * exe_header;
2137
2138 exe_header = (FILHDR*) executable.file_base;
2139 if (exe_header->e_magic != DOSMAGIC)
2140 goto unwind;
2141
2142 if ((char*) exe_header->e_lfanew > (char*) executable.size)
2143 {
2144 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
2145 *is_dos_app = TRUE;
2146 }
2147 else if (exe_header->nt_signature != NT_SIGNATURE)
2148 {
2149 *is_dos_app = TRUE;
2150 }
2151 #else
2152 IMAGE_DOS_HEADER * dos_header;
2153 IMAGE_NT_HEADERS * nt_header;
2154
2155 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
2156 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
2157 goto unwind;
2158
2159 nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew);
2160
2161 if ((char*) nt_header > (char*) dos_header + executable.size)
2162 {
2163 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
2164 *is_dos_app = TRUE;
2165 }
2166 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
2167 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
2168 {
2169 *is_dos_app = TRUE;
2170 }
2171 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
2172 {
2173 /* Look for cygwin.dll in DLL import list. */
2174 IMAGE_DATA_DIRECTORY import_dir =
2175 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
2176 IMAGE_IMPORT_DESCRIPTOR * imports;
2177 IMAGE_SECTION_HEADER * section;
2178
2179 section = rva_to_section (import_dir.VirtualAddress, nt_header);
2180 imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
2181 section, executable);
2182
2183 for ( ; imports->Name; imports++)
2184 {
2185 char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable);
2186
2187 /* The exact name of the cygwin dll has changed with
2188 various releases, but hopefully this will be reasonably
2189 future proof. */
2190 if (strncmp (dllname, "cygwin", 6) == 0)
2191 {
2192 *is_cygnus_app = TRUE;
2193 break;
2194 }
2195 }
2196 }
2197 #endif
2198 }
2199
2200 unwind:
2201 close_file_data (&executable);
2202 } 1914 }
2203 1915
2204 /* Close the system structures associated with the given file. */ 1916 /* Close the system structures associated with the given file. */
2205 void 1917 void
2206 close_file_data (file_data *p_file) 1918 close_file_data (file_data *p_file)
2208 UnmapViewOfFile (p_file->file_base); 1920 UnmapViewOfFile (p_file->file_base);
2209 CloseHandle (p_file->file_mapping); 1921 CloseHandle (p_file->file_mapping);
2210 CloseHandle (p_file->file); 1922 CloseHandle (p_file->file);
2211 } 1923 }
2212 1924
2213 void
2214 vars_of_nt (void)
2215 {
2216 DEFVAR_INT ("nt-fake-unix-uid", &nt_fake_unix_uid /*
2217 *Set uid returned by `user-uid' and `user-real-uid'.
2218 Under NT and 9x, there is no uids, and even no almighty user called root.
2219 By setting this variable, you can have any uid of choice. Default is 0.
2220 Changes to this variable take effect immediately.
2221 */ );
2222 nt_fake_unix_uid = 0;
2223 }
2224
2225 /* end of nt.c */ 1925 /* end of nt.c */