Mercurial > hg > xemacs-beta
comparison src/nt.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 3078fd1074e8 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
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 | |
30 #define getwd _getwd | 28 #define getwd _getwd |
31 #include "lisp.h" | 29 #include "lisp.h" |
32 #undef getwd | 30 #undef getwd |
33 | 31 |
34 #include "systime.h" | 32 #include "systime.h" |
35 #include "syssignal.h" | 33 #include "syssignal.h" |
36 #include "sysproc.h" | 34 #include "sysproc.h" |
37 #include "sysfile.h" | 35 #include "sysfile.h" |
38 | 36 #include "syspwd.h" |
39 #include <ctype.h> | 37 #include "sysdir.h" |
40 #include <direct.h> | 38 |
41 #include <errno.h> | 39 #include "syswindows.h" |
42 #include <fcntl.h> | |
43 #include <io.h> | |
44 #include <pwd.h> | |
45 #include <signal.h> | |
46 #include <string.h> | |
47 #include <stdlib.h> | |
48 #include <stdio.h> | |
49 | |
50 #include <windows.h> | |
51 #ifndef __MINGW32__ | |
52 #include <mmsystem.h> | |
53 #else | |
54 typedef void (CALLBACK TIMECALLBACK)(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); | |
55 | |
56 typedef TIMECALLBACK FAR *LPTIMECALLBACK; | |
57 DWORD WINAPI timeGetTime(void); | |
58 MMRESULT WINAPI timeSetEvent(UINT uDelay, UINT uResolution, | |
59 LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent); | |
60 MMRESULT WINAPI timeKillEvent(UINT uTimerID); | |
61 MMRESULT WINAPI timeGetDevCaps(TIMECAPS* ptc, UINT cbtc); | |
62 MMRESULT WINAPI timeBeginPeriod(UINT uPeriod); | |
63 MMRESULT WINAPI timeEndPeriod(UINT uPeriod); | |
64 #endif | |
65 | 40 |
66 #include "nt.h" | 41 #include "nt.h" |
67 #include <sys/dir.h> | |
68 #include "ntheap.h" | 42 #include "ntheap.h" |
69 | 43 |
70 | 44 |
71 extern Lisp_Object Vmswindows_downcase_file_names; | 45 extern Lisp_Object Vmswindows_downcase_file_names; |
72 #if 0 | 46 #if 0 |
93 strcpy (dir, startup_dir); | 67 strcpy (dir, startup_dir); |
94 return dir; | 68 return dir; |
95 #endif | 69 #endif |
96 } | 70 } |
97 | 71 |
98 /* Emulate getloadavg. */ | |
99 int | |
100 getloadavg (double loadavg[], int nelem) | |
101 { | |
102 int i; | |
103 | |
104 /* A faithful emulation is going to have to be saved for a rainy day. */ | |
105 for (i = 0; i < nelem; i++) | |
106 { | |
107 loadavg[i] = 0.0; | |
108 } | |
109 return i; | |
110 } | |
111 | |
112 /* Emulate getpwuid, getpwnam and others. */ | 72 /* Emulate getpwuid, getpwnam and others. */ |
113 | 73 |
114 #define PASSWD_FIELD_SIZE 256 | 74 #define PASSWD_FIELD_SIZE 256 |
115 | 75 |
116 static char the_passwd_name[PASSWD_FIELD_SIZE]; | 76 static char the_passwd_name[PASSWD_FIELD_SIZE]; |
130 the_passwd_dir, | 90 the_passwd_dir, |
131 the_passwd_shell, | 91 the_passwd_shell, |
132 }; | 92 }; |
133 | 93 |
134 uid_t | 94 uid_t |
135 getuid () | 95 getuid (void) |
136 { | 96 { |
137 return nt_fake_unix_uid; | 97 return nt_fake_unix_uid; |
138 } | 98 } |
139 | 99 |
140 uid_t | 100 uid_t |
141 geteuid () | 101 geteuid (void) |
142 { | 102 { |
143 return nt_fake_unix_uid; | 103 return nt_fake_unix_uid; |
144 } | 104 } |
145 | 105 |
146 gid_t | 106 gid_t |
147 getgid () | 107 getgid (void) |
148 { | 108 { |
149 return the_passwd.pw_gid; | 109 return the_passwd.pw_gid; |
150 } | 110 } |
151 | 111 |
152 gid_t | 112 gid_t |
153 getegid () | 113 getegid (void) |
154 { | 114 { |
155 return getgid (); | 115 return getgid (); |
156 } | 116 } |
157 | 117 |
158 struct passwd * | 118 struct passwd * |
181 | 141 |
182 return pw; | 142 return pw; |
183 } | 143 } |
184 | 144 |
185 void | 145 void |
186 init_user_info () | 146 init_user_info (void) |
187 { | 147 { |
188 /* This code is pretty much of ad hoc nature. There is no unix-like | 148 /* This code is pretty much of ad hoc nature. There is no unix-like |
189 UIDs under Windows NT. There is no concept of root user, because | 149 UIDs under Windows NT. There is no concept of root user, because |
190 all security is ACL-based. Instead, let's use a simple variable, | 150 all security is ACL-based. Instead, let's use a simple variable, |
191 nt-fake-unix-uid, which would allow the user to have a uid of | 151 nt-fake-unix-uid, which would allow the user to have a uid of |
288 #endif | 248 #endif |
289 if (getenv ("SHELL") == NULL) | 249 if (getenv ("SHELL") == NULL) |
290 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); | 250 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); |
291 | 251 |
292 /* Set dir and shell from environment variables. */ | 252 /* Set dir and shell from environment variables. */ |
293 strcpy (the_passwd.pw_dir, get_home_directory()); | 253 strcpy (the_passwd.pw_dir, (char *)get_home_directory()); |
294 strcpy (the_passwd.pw_shell, getenv ("SHELL")); | 254 strcpy (the_passwd.pw_shell, getenv ("SHELL")); |
295 } | 255 } |
296 | 256 |
297 /* Normalize filename by converting all path separators to | 257 /* Normalize filename by converting all path separators to |
298 the specified separator. Also conditionally convert upper | 258 the specified separator. Also conditionally convert upper |
299 case path name components to lower case. */ | 259 case path name components to lower case. */ |
300 | 260 |
301 static void | 261 static void |
302 normalize_filename (fp, path_sep) | 262 normalize_filename (char *fp, char path_sep) |
303 REGISTER char *fp; | |
304 char path_sep; | |
305 { | 263 { |
306 char sep; | 264 char sep; |
307 char *elem; | 265 char *elem; |
308 | 266 |
309 /* Always lower-case drive letters a-z, even if the filesystem | 267 /* Always lower-case drive letters a-z, even if the filesystem |
355 } while (*fp++); | 313 } while (*fp++); |
356 } | 314 } |
357 | 315 |
358 /* Destructively turn backslashes into slashes. */ | 316 /* Destructively turn backslashes into slashes. */ |
359 void | 317 void |
360 dostounix_filename (p) | 318 dostounix_filename (char *p) |
361 REGISTER char *p; | |
362 { | 319 { |
363 normalize_filename (p, '/'); | 320 normalize_filename (p, '/'); |
364 } | 321 } |
365 | 322 |
366 /* Destructively turn slashes into backslashes. */ | 323 /* Destructively turn slashes into backslashes. */ |
367 void | 324 void |
368 unixtodos_filename (p) | 325 unixtodos_filename (char *p) |
369 REGISTER char *p; | |
370 { | 326 { |
371 normalize_filename (p, '\\'); | 327 normalize_filename (p, '\\'); |
372 } | 328 } |
373 | 329 |
374 /* Remove all CR's that are followed by a LF. | 330 /* Remove all CR's that are followed by a LF. |
375 (From msdos.c...probably should figure out a way to share it, | 331 (From msdos.c...probably should figure out a way to share it, |
376 although this code isn't going to ever change.) */ | 332 although this code isn't going to ever change.) */ |
377 int | 333 int |
378 crlf_to_lf (n, buf, lf_count) | 334 crlf_to_lf (int n, unsigned char *buf, unsigned *lf_count) |
379 REGISTER int n; | |
380 REGISTER unsigned char *buf; | |
381 REGISTER unsigned *lf_count; | |
382 { | 335 { |
383 unsigned char *np = buf; | 336 unsigned char *np = buf; |
384 unsigned char *startp = buf; | 337 unsigned char *startp = buf; |
385 unsigned char *endp = buf + n; | 338 unsigned char *endp = buf + n; |
386 | 339 |
553 #endif /* 0 */ | 506 #endif /* 0 */ |
554 | 507 |
555 #define REG_ROOT "SOFTWARE\\GNU\\XEmacs" | 508 #define REG_ROOT "SOFTWARE\\GNU\\XEmacs" |
556 | 509 |
557 LPBYTE | 510 LPBYTE |
558 nt_get_resource (key, lpdwtype) | 511 nt_get_resource (char *key, LPDWORD lpdwtype) |
559 char *key; | |
560 LPDWORD lpdwtype; | |
561 { | 512 { |
562 LPBYTE lpvalue; | 513 LPBYTE lpvalue; |
563 HKEY hrootkey = NULL; | 514 HKEY hrootkey = NULL; |
564 DWORD cbData; | 515 DWORD cbData; |
565 | 516 |
600 | 551 |
601 return (NULL); | 552 return (NULL); |
602 } | 553 } |
603 | 554 |
604 void | 555 void |
605 init_environment () | 556 init_environment (void) |
606 { | 557 { |
607 /* Check for environment variables and use registry if they don't exist */ | 558 /* Check for environment variables and use registry if they don't exist */ |
608 { | 559 { |
609 int i; | 560 int i; |
610 LPBYTE lpval; | 561 LPBYTE lpval; |
622 "EMACSPATH", | 573 "EMACSPATH", |
623 "EMACSPACKAGEPATH", | 574 "EMACSPACKAGEPATH", |
624 "EMACSLOCKDIR", | 575 "EMACSLOCKDIR", |
625 "INFOPATH" | 576 "INFOPATH" |
626 }; | 577 }; |
627 #ifdef HEAP_IN_DATA | 578 #if defined (HEAP_IN_DATA) && !defined(PDUMP) |
628 cache_system_info (); | 579 cache_system_info (); |
629 #endif | 580 #endif |
630 for (i = 0; i < countof (env_vars); i++) | 581 for (i = 0; i < countof (env_vars); i++) |
631 { | 582 { |
632 if (!getenv (env_vars[i]) && | 583 if (!getenv (env_vars[i]) && |
1096 dir_is_fat = is_fat_volume (filename, NULL); | 1047 dir_is_fat = is_fat_volume (filename, NULL); |
1097 | 1048 |
1098 return dirp; | 1049 return dirp; |
1099 } | 1050 } |
1100 | 1051 |
1101 void | 1052 int |
1102 closedir (DIR *dirp) | 1053 closedir (DIR *dirp) |
1103 { | 1054 { |
1055 BOOL retval; | |
1056 | |
1104 /* If we have a find-handle open, close it. */ | 1057 /* If we have a find-handle open, close it. */ |
1105 if (dir_find_handle != INVALID_HANDLE_VALUE) | 1058 if (dir_find_handle != INVALID_HANDLE_VALUE) |
1106 { | 1059 { |
1107 FindClose (dir_find_handle); | 1060 retval = FindClose (dir_find_handle); |
1108 dir_find_handle = INVALID_HANDLE_VALUE; | 1061 dir_find_handle = INVALID_HANDLE_VALUE; |
1109 } | 1062 } |
1110 xfree (dirp); | 1063 xfree (dirp); |
1064 if (retval) | |
1065 return 0; | |
1066 else | |
1067 return -1; | |
1111 } | 1068 } |
1112 | 1069 |
1113 struct direct * | 1070 struct direct * |
1114 readdir (DIR *dirp) | 1071 readdir (DIR *dirp) |
1115 { | 1072 { |
1135 if (!FindNextFile (dir_find_handle, &dir_find_data)) | 1092 if (!FindNextFile (dir_find_handle, &dir_find_data)) |
1136 return NULL; | 1093 return NULL; |
1137 } | 1094 } |
1138 | 1095 |
1139 /* Emacs never uses this value, so don't bother making it match | 1096 /* Emacs never uses this value, so don't bother making it match |
1140 value returned by stat(). */ | 1097 value returned by xemacs_stat(). */ |
1141 dir_static.d_ino = 1; | 1098 dir_static.d_ino = 1; |
1142 | 1099 |
1143 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + | 1100 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + |
1144 dir_static.d_namlen - dir_static.d_namlen % 4; | 1101 dir_static.d_namlen - dir_static.d_namlen % 4; |
1145 | 1102 |
1256 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime; | 1213 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime; |
1257 ret -= utc_base; | 1214 ret -= utc_base; |
1258 return (time_t) (ret * 1e-7); | 1215 return (time_t) (ret * 1e-7); |
1259 } | 1216 } |
1260 #else | 1217 #else |
1218 | |
1219 #if defined(MINGW) && CYGWIN_VERSION_DLL_MAJOR <= 21 | |
1220 #define LowPart u.LowPart | |
1221 #define HighPart u.HighPart | |
1222 #endif | |
1261 | 1223 |
1262 static LARGE_INTEGER utc_base_li; | 1224 static LARGE_INTEGER utc_base_li; |
1263 | 1225 |
1264 time_t | 1226 time_t |
1265 convert_time (FILETIME uft) | 1227 convert_time (FILETIME uft) |
1326 #endif | 1288 #endif |
1327 | 1289 |
1328 return ret; | 1290 return ret; |
1329 } | 1291 } |
1330 #endif | 1292 #endif |
1293 #if defined(MINGW) && CYGWIN_VERSION_DLL_MAJOR <= 21 | |
1294 #undef LowPart | |
1295 #undef HighPart | |
1296 #endif | |
1331 | 1297 |
1332 #if 0 | 1298 #if 0 |
1333 /* in case we ever have need of this */ | 1299 /* in case we ever have need of this */ |
1334 void | 1300 void |
1335 convert_from_time_t (time_t time, FILETIME * pft) | 1301 convert_from_time_t (time_t time, FILETIME * pft) |
1403 return hashval (p); | 1369 return hashval (p); |
1404 } | 1370 } |
1405 | 1371 |
1406 #endif | 1372 #endif |
1407 | 1373 |
1408 /* stat has been fixed since MSVC 5.0. | 1374 /* #### aichner@ecf.teradyne.com reported that with the library |
1409 Oh, and do not encapsulater stat for non-MS compilers, too */ | 1375 provided stat/fstat, (file-exist "d:\\tmp\\") =>> nil, |
1410 /* #### popineau@ese-metz.fr says they still might be broken. | 1376 (file-exist "d:\\tmp") =>> t, when d:\tmp exists. Whenever |
1411 Oh well... Let's add that `1 ||' condition.... --kkm */ | 1377 we opt to use non-encapsulated stat(), this should serve as |
1412 #if 1 || defined(_MSC_VER) && _MSC_VER < 1100 | 1378 a compatibility test. --kkm */ |
1413 | 1379 |
1414 /* Since stat is encapsulated on Windows NT, we need to encapsulate | 1380 /* Since stat is encapsulated on Windows NT, we need to encapsulate |
1415 the equally broken fstat as well. */ | 1381 the equally broken fstat as well. */ |
1416 int _cdecl | 1382 int |
1417 fstat (int handle, struct stat *buffer) | 1383 mswindows_fstat (int handle, struct stat *buffer) |
1418 { | 1384 { |
1419 int ret; | 1385 int ret; |
1420 BY_HANDLE_FILE_INFORMATION lpFileInfo; | 1386 BY_HANDLE_FILE_INFORMATION lpFileInfo; |
1421 /* Initialize values */ | 1387 /* Initialize values */ |
1422 buffer->st_mode = 0; | 1388 buffer->st_mode = 0; |
1447 | 1413 |
1448 /* MSVC stat function can't cope with UNC names and has other bugs, so | 1414 /* MSVC stat function can't cope with UNC names and has other bugs, so |
1449 replace it with our own. This also allows us to calculate consistent | 1415 replace it with our own. This also allows us to calculate consistent |
1450 inode values without hacks in the main Emacs code. */ | 1416 inode values without hacks in the main Emacs code. */ |
1451 int | 1417 int |
1452 stat (const char * path, struct stat * buf) | 1418 mswindows_stat (const char * path, struct stat * buf) |
1453 { | 1419 { |
1454 char * name; | 1420 char * name; |
1455 WIN32_FIND_DATA wfd; | 1421 WIN32_FIND_DATA wfd; |
1456 HANDLE fh; | 1422 HANDLE fh; |
1457 DWORD fake_inode; | 1423 DWORD fake_inode; |
1477 directory of a drive or UNC volume in which case ensure there | 1443 directory of a drive or UNC volume in which case ensure there |
1478 is a trailing separator. */ | 1444 is a trailing separator. */ |
1479 len = strlen (name); | 1445 len = strlen (name); |
1480 rootdir = (path >= name + len - 1 | 1446 rootdir = (path >= name + len - 1 |
1481 && (IS_DIRECTORY_SEP (*path) || *path == 0)); | 1447 && (IS_DIRECTORY_SEP (*path) || *path == 0)); |
1482 name = strcpy (alloca (len + 2), name); | 1448 name = strcpy ((char *)alloca (len + 2), name); |
1483 | 1449 |
1484 if (rootdir) | 1450 if (rootdir) |
1485 { | 1451 { |
1486 if (!IS_DIRECTORY_SEP (name[len-1])) | 1452 if (!IS_DIRECTORY_SEP (name[len-1])) |
1487 strcat (name, "\\"); | 1453 strcat (name, "\\"); |
1633 | 1599 |
1634 buf->st_mode |= permission | (permission >> 3) | (permission >> 6); | 1600 buf->st_mode |= permission | (permission >> 3) | (permission >> 6); |
1635 | 1601 |
1636 return 0; | 1602 return 0; |
1637 } | 1603 } |
1638 #endif /* defined(_MSC_VER) && _MSC_VER < 1100 */ | |
1639 | 1604 |
1640 /* From callproc.c */ | 1605 /* From callproc.c */ |
1641 extern Lisp_Object Vbinary_process_input; | 1606 extern Lisp_Object Vbinary_process_input; |
1642 extern Lisp_Object Vbinary_process_output; | 1607 extern Lisp_Object Vbinary_process_output; |
1643 | 1608 |
1674 term_ntproc (int unused) | 1639 term_ntproc (int unused) |
1675 { | 1640 { |
1676 } | 1641 } |
1677 | 1642 |
1678 void | 1643 void |
1679 init_ntproc () | 1644 init_ntproc (void) |
1680 { | 1645 { |
1681 /* Initial preparation for subprocess support: replace our standard | 1646 /* Initial preparation for subprocess support: replace our standard |
1682 handles with non-inheritable versions. */ | 1647 handles with non-inheritable versions. */ |
1683 { | 1648 { |
1684 HANDLE parent; | 1649 HANDLE parent; |
1807 unsigned signal_block_mask = 0; | 1772 unsigned signal_block_mask = 0; |
1808 | 1773 |
1809 /* Signal pending mask: bit set to 1 means sig is pending */ | 1774 /* Signal pending mask: bit set to 1 means sig is pending */ |
1810 unsigned signal_pending_mask = 0; | 1775 unsigned signal_pending_mask = 0; |
1811 | 1776 |
1812 msw_sighandler msw_sigset (int nsig, msw_sighandler handler) | 1777 mswindows_sighandler mswindows_sigset (int nsig, mswindows_sighandler handler) |
1813 { | 1778 { |
1814 /* We delegate some signals to the system function */ | 1779 /* We delegate some signals to the system function */ |
1815 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | 1780 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) |
1816 return signal (nsig, handler); | 1781 return signal (nsig, handler); |
1817 | 1782 |
1821 return NULL; | 1786 return NULL; |
1822 } | 1787 } |
1823 | 1788 |
1824 /* Store handler ptr */ | 1789 /* Store handler ptr */ |
1825 { | 1790 { |
1826 msw_sighandler old_handler = signal_handlers[nsig]; | 1791 mswindows_sighandler old_handler = signal_handlers[nsig]; |
1827 signal_handlers[nsig] = handler; | 1792 signal_handlers[nsig] = handler; |
1828 return old_handler; | 1793 return old_handler; |
1829 } | 1794 } |
1830 } | 1795 } |
1831 | 1796 |
1832 int msw_sighold (int nsig) | 1797 int mswindows_sighold (int nsig) |
1833 { | 1798 { |
1834 if (nsig < 0 || nsig > SIG_MAX) | 1799 if (nsig < 0 || nsig > SIG_MAX) |
1835 return errno = EINVAL; | 1800 return errno = EINVAL; |
1836 | 1801 |
1837 signal_block_mask |= sigmask(nsig); | 1802 signal_block_mask |= sigmask(nsig); |
1838 return 0; | 1803 return 0; |
1839 } | 1804 } |
1840 | 1805 |
1841 int msw_sigrelse (int nsig) | 1806 int mswindows_sigrelse (int nsig) |
1842 { | 1807 { |
1843 if (nsig < 0 || nsig > SIG_MAX) | 1808 if (nsig < 0 || nsig > SIG_MAX) |
1844 return errno = EINVAL; | 1809 return errno = EINVAL; |
1845 | 1810 |
1846 signal_block_mask &= ~sigmask(nsig); | 1811 signal_block_mask &= ~sigmask(nsig); |
1847 | 1812 |
1848 if (signal_pending_mask & sigmask(nsig)) | 1813 if (signal_pending_mask & sigmask(nsig)) |
1849 msw_raise (nsig); | 1814 mswindows_raise (nsig); |
1850 | 1815 |
1851 return 0; | 1816 return 0; |
1852 } | 1817 } |
1853 | 1818 |
1854 int msw_sigpause (int nsig) | 1819 int mswindows_sigpause (int nsig) |
1855 { | 1820 { |
1856 /* This is currently not called, because the only | 1821 /* This is currently not called, because the only |
1857 call to sigpause inside XEmacs is with SIGCHLD | 1822 call to sigpause inside XEmacs is with SIGCHLD |
1858 parameter. Just in case, we put an assert here, | 1823 parameter. Just in case, we put an assert here, |
1859 so anyone who will add a call to sigpause will | 1824 so anyone who will add a call to sigpause will |
1860 be surprised (or surprise someone else...) */ | 1825 be surprised (or surprise someone else...) */ |
1861 assert (0); | 1826 assert (0); |
1862 return 0; | 1827 return 0; |
1863 } | 1828 } |
1864 | 1829 |
1865 int msw_raise (int nsig) | 1830 int mswindows_raise (int nsig) |
1866 { | 1831 { |
1867 /* We delegate some raises to the system routine */ | 1832 /* We delegate some raises to the system routine */ |
1868 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | 1833 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) |
1869 return raise (nsig); | 1834 return raise (nsig); |
1870 | 1835 |
1926 | 1891 |
1927 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser, | 1892 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser, |
1928 DWORD dw1, DWORD dw2) | 1893 DWORD dw1, DWORD dw2) |
1929 { | 1894 { |
1930 /* Just raise a signal indicated by dwUser parameter */ | 1895 /* Just raise a signal indicated by dwUser parameter */ |
1931 msw_raise (dwUser); | 1896 mswindows_raise (dwUser); |
1932 } | 1897 } |
1933 | 1898 |
1934 /* Divide time in ms specified by IT by DENOM. Return 1 ms | 1899 /* Divide time in ms specified by IT by DENOM. Return 1 ms |
1935 if division results in zero */ | 1900 if division results in zero */ |
1936 static UINT period (const struct itimerval* it, UINT denom) | 1901 static UINT period (const struct itimerval* it, UINT denom) |
2009 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); | 1974 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); |
2010 else | 1975 else |
2011 return errno = EINVAL; | 1976 return errno = EINVAL; |
2012 } | 1977 } |
2013 | 1978 |
1979 | |
1980 /*--------------------------------------------------------------------*/ | |
1981 /* Memory-mapped files */ | |
1982 /*--------------------------------------------------------------------*/ | |
1983 | |
2014 int | 1984 int |
2015 open_input_file (file_data *p_file, CONST char *filename) | 1985 open_input_file (file_data *p_file, const char *filename) |
2016 { | 1986 { |
1987 /* Synched with FSF 20.6. We fixed some warnings. */ | |
2017 HANDLE file; | 1988 HANDLE file; |
2018 HANDLE file_mapping; | 1989 HANDLE file_mapping; |
2019 void *file_base; | 1990 void *file_base; |
2020 DWORD size, upper_size; | 1991 DWORD size, upper_size; |
2021 | 1992 |
2032 | 2003 |
2033 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); | 2004 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); |
2034 if (file_base == 0) | 2005 if (file_base == 0) |
2035 return FALSE; | 2006 return FALSE; |
2036 | 2007 |
2037 p_file->name = (char*)filename; | 2008 p_file->name = (char *)filename; |
2038 p_file->size = size; | 2009 p_file->size = size; |
2039 p_file->file = file; | 2010 p_file->file = file; |
2040 p_file->file_mapping = file_mapping; | 2011 p_file->file_mapping = file_mapping; |
2041 p_file->file_base = file_base; | 2012 p_file->file_base = (char *)file_base; |
2042 | 2013 |
2043 return TRUE; | 2014 return TRUE; |
2015 } | |
2016 | |
2017 int | |
2018 open_output_file (file_data *p_file, const char *filename, unsigned long size) | |
2019 { | |
2020 /* Synched with FSF 20.6. We fixed some warnings. */ | |
2021 HANDLE file; | |
2022 HANDLE file_mapping; | |
2023 void *file_base; | |
2024 | |
2025 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, | |
2026 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |
2027 if (file == INVALID_HANDLE_VALUE) | |
2028 return FALSE; | |
2029 | |
2030 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE, | |
2031 0, size, NULL); | |
2032 if (!file_mapping) | |
2033 return FALSE; | |
2034 | |
2035 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size); | |
2036 if (file_base == NULL) | |
2037 return FALSE; | |
2038 | |
2039 p_file->name = filename; | |
2040 p_file->size = size; | |
2041 p_file->file = file; | |
2042 p_file->file_mapping = file_mapping; | |
2043 p_file->file_base = (char*) file_base; | |
2044 | |
2045 return TRUE; | |
2046 } | |
2047 | |
2048 #if 1 /* !defined(MINGW) */ | |
2049 /* Return pointer to section header for section containing the given | |
2050 relative virtual address. */ | |
2051 static IMAGE_SECTION_HEADER * | |
2052 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header) | |
2053 { | |
2054 /* Synched with FSF 20.6. We added MINGW stuff. */ | |
2055 PIMAGE_SECTION_HEADER section; | |
2056 int i; | |
2057 | |
2058 section = IMAGE_FIRST_SECTION (nt_header); | |
2059 | |
2060 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
2061 { | |
2062 /* Some linkers (eg. the NT SDK linker I believe) swapped the | |
2063 meaning of these two values - or rather, they ignored | |
2064 VirtualSize entirely and always set it to zero. This affects | |
2065 some very old exes (eg. gzip dated Dec 1993). Since | |
2066 mswindows_executable_type relies on this function to work reliably, | |
2067 we need to cope with this. */ | |
2068 DWORD real_size = max (section->SizeOfRawData, | |
2069 section->Misc.VirtualSize); | |
2070 if (rva >= section->VirtualAddress | |
2071 && rva < section->VirtualAddress + real_size) | |
2072 return section; | |
2073 section++; | |
2074 } | |
2075 return NULL; | |
2076 } | |
2077 #endif | |
2078 | |
2079 void | |
2080 mswindows_executable_type (const char * filename, int * is_dos_app, | |
2081 int * is_cygnus_app) | |
2082 { | |
2083 /* Synched with FSF 20.6. We added MINGW stuff and casts. */ | |
2084 file_data executable; | |
2085 char * p; | |
2086 | |
2087 /* Default values in case we can't tell for sure. */ | |
2088 *is_dos_app = FALSE; | |
2089 *is_cygnus_app = FALSE; | |
2090 | |
2091 if (!open_input_file (&executable, filename)) | |
2092 return; | |
2093 | |
2094 p = strrchr (filename, '.'); | |
2095 | |
2096 /* We can only identify DOS .com programs from the extension. */ | |
2097 if (p && stricmp (p, ".com") == 0) | |
2098 *is_dos_app = TRUE; | |
2099 else if (p && (stricmp (p, ".bat") == 0 || | |
2100 stricmp (p, ".cmd") == 0)) | |
2101 { | |
2102 /* A DOS shell script - it appears that CreateProcess is happy to | |
2103 accept this (somewhat surprisingly); presumably it looks at | |
2104 COMSPEC to determine what executable to actually invoke. | |
2105 Therefore, we have to do the same here as well. */ | |
2106 /* Actually, I think it uses the program association for that | |
2107 extension, which is defined in the registry. */ | |
2108 p = egetenv ("COMSPEC"); | |
2109 if (p) | |
2110 mswindows_executable_type (p, is_dos_app, is_cygnus_app); | |
2111 } | |
2112 else | |
2113 { | |
2114 /* Look for DOS .exe signature - if found, we must also check that | |
2115 it isn't really a 16- or 32-bit Windows exe, since both formats | |
2116 start with a DOS program stub. Note that 16-bit Windows | |
2117 executables use the OS/2 1.x format. */ | |
2118 | |
2119 #if 0 /* defined( MINGW ) */ | |
2120 /* mingw32 doesn't have enough headers to detect cygwin | |
2121 apps, just do what we can. */ | |
2122 FILHDR * exe_header; | |
2123 | |
2124 exe_header = (FILHDR*) executable.file_base; | |
2125 if (exe_header->e_magic != DOSMAGIC) | |
2126 goto unwind; | |
2127 | |
2128 if ((char*) exe_header->e_lfanew > (char*) executable.size) | |
2129 { | |
2130 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ | |
2131 *is_dos_app = TRUE; | |
2132 } | |
2133 else if (exe_header->nt_signature != NT_SIGNATURE) | |
2134 { | |
2135 *is_dos_app = TRUE; | |
2136 } | |
2137 #else | |
2138 IMAGE_DOS_HEADER * dos_header; | |
2139 IMAGE_NT_HEADERS * nt_header; | |
2140 | |
2141 dos_header = (PIMAGE_DOS_HEADER) executable.file_base; | |
2142 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) | |
2143 goto unwind; | |
2144 | |
2145 nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew); | |
2146 | |
2147 if ((char*) nt_header > (char*) dos_header + executable.size) | |
2148 { | |
2149 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ | |
2150 *is_dos_app = TRUE; | |
2151 } | |
2152 else if (nt_header->Signature != IMAGE_NT_SIGNATURE && | |
2153 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE) | |
2154 { | |
2155 *is_dos_app = TRUE; | |
2156 } | |
2157 else if (nt_header->Signature == IMAGE_NT_SIGNATURE) | |
2158 { | |
2159 /* Look for cygwin.dll in DLL import list. */ | |
2160 IMAGE_DATA_DIRECTORY import_dir = | |
2161 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; | |
2162 IMAGE_IMPORT_DESCRIPTOR * imports; | |
2163 IMAGE_SECTION_HEADER * section; | |
2164 | |
2165 section = rva_to_section (import_dir.VirtualAddress, nt_header); | |
2166 imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress, | |
2167 section, executable); | |
2168 | |
2169 for ( ; imports->Name; imports++) | |
2170 { | |
2171 char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable); | |
2172 | |
2173 /* The exact name of the cygwin dll has changed with | |
2174 various releases, but hopefully this will be reasonably | |
2175 future proof. */ | |
2176 if (strncmp (dllname, "cygwin", 6) == 0) | |
2177 { | |
2178 *is_cygnus_app = TRUE; | |
2179 break; | |
2180 } | |
2181 } | |
2182 } | |
2183 #endif | |
2184 } | |
2185 | |
2186 unwind: | |
2187 close_file_data (&executable); | |
2044 } | 2188 } |
2045 | 2189 |
2046 /* Close the system structures associated with the given file. */ | 2190 /* Close the system structures associated with the given file. */ |
2047 void | 2191 void |
2048 close_file_data (file_data *p_file) | 2192 close_file_data (file_data *p_file) |