Mercurial > hg > xemacs-beta
comparison src/nt.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 8626e4521993 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
32 #undef getwd | 32 #undef getwd |
33 | 33 |
34 #include "systime.h" | 34 #include "systime.h" |
35 #include "syssignal.h" | 35 #include "syssignal.h" |
36 #include "sysproc.h" | 36 #include "sysproc.h" |
37 #include "sysfile.h" | |
37 | 38 |
38 #include <ctype.h> | 39 #include <ctype.h> |
39 #include <direct.h> | 40 #include <direct.h> |
40 #include <errno.h> | 41 #include <errno.h> |
41 #include <fcntl.h> | 42 #include <fcntl.h> |
42 #include <io.h> | 43 #include <io.h> |
43 #include <pwd.h> | 44 #include <pwd.h> |
44 #include <signal.h> | 45 #include <signal.h> |
45 #include <stddef.h> /* for offsetof */ | |
46 #include <string.h> | 46 #include <string.h> |
47 #include <stdlib.h> | 47 #include <stdlib.h> |
48 #include <stdio.h> | 48 #include <stdio.h> |
49 | 49 |
50 #include <windows.h> | 50 #include <windows.h> |
51 #ifndef __MINGW32__ | |
51 #include <mmsystem.h> | 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 | |
52 | 65 |
53 #include "nt.h" | 66 #include "nt.h" |
54 #include <sys/dir.h> | 67 #include <sys/dir.h> |
55 #include "ntheap.h" | 68 #include "ntheap.h" |
56 | 69 |
59 #if 0 | 72 #if 0 |
60 extern Lisp_Object Vwin32_generate_fake_inodes; | 73 extern Lisp_Object Vwin32_generate_fake_inodes; |
61 #endif | 74 #endif |
62 extern Lisp_Object Vmswindows_get_true_file_attributes; | 75 extern Lisp_Object Vmswindows_get_true_file_attributes; |
63 | 76 |
64 extern char *get_home_directory(void); | 77 int nt_fake_unix_uid; |
65 | 78 |
66 static char startup_dir[ MAXPATHLEN ]; | 79 static char startup_dir[ MAXPATHLEN ]; |
67 | 80 |
68 /* Get the current working directory. */ | 81 /* Get the current working directory. */ |
69 char * | 82 char * |
116 the_passwd_gecos, | 129 the_passwd_gecos, |
117 the_passwd_dir, | 130 the_passwd_dir, |
118 the_passwd_shell, | 131 the_passwd_shell, |
119 }; | 132 }; |
120 | 133 |
121 int | 134 uid_t |
122 getuid () | 135 getuid () |
123 { | 136 { |
124 return the_passwd.pw_uid; | 137 return nt_fake_unix_uid; |
125 } | 138 } |
126 | 139 |
127 int | 140 uid_t |
128 geteuid () | 141 geteuid () |
129 { | 142 { |
130 /* I could imagine arguing for checking to see whether the user is | 143 return nt_fake_unix_uid; |
131 in the Administrators group and returning a UID of 0 for that | 144 } |
132 case, but I don't know how wise that would be in the long run. */ | 145 |
133 return getuid (); | 146 gid_t |
134 } | |
135 | |
136 int | |
137 getgid () | 147 getgid () |
138 { | 148 { |
139 return the_passwd.pw_gid; | 149 return the_passwd.pw_gid; |
140 } | 150 } |
141 | 151 |
142 int | 152 gid_t |
143 getegid () | 153 getegid () |
144 { | 154 { |
145 return getgid (); | 155 return getgid (); |
146 } | 156 } |
147 | 157 |
148 struct passwd * | 158 struct passwd * |
149 getpwuid (int uid) | 159 getpwuid (uid_t uid) |
150 { | 160 { |
151 if (uid == the_passwd.pw_uid) | 161 if (uid == nt_fake_unix_uid) |
152 return &the_passwd; | 162 { |
153 return NULL; | 163 the_passwd.pw_gid = the_passwd.pw_uid = uid; |
164 return &the_passwd; | |
165 } | |
166 else | |
167 return NULL; | |
154 } | 168 } |
155 | 169 |
156 struct passwd * | 170 struct passwd * |
157 getpwnam (const char *name) | 171 getpwnam (const char *name) |
158 { | 172 { |
169 } | 183 } |
170 | 184 |
171 void | 185 void |
172 init_user_info () | 186 init_user_info () |
173 { | 187 { |
188 /* 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 | |
190 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 | |
192 choice. --kkm, 02/03/2000 */ | |
193 #if 0 | |
174 /* Find the user's real name by opening the process token and | 194 /* Find the user's real name by opening the process token and |
175 looking up the name associated with the user-sid in that token. | 195 looking up the name associated with the user-sid in that token. |
176 | 196 |
177 Use the relative portion of the identifier authority value from | 197 Use the relative portion of the identifier authority value from |
178 the user-sid as the user id value (same for group id using the | 198 the user-sid as the user id value (same for group id using the |
244 strcpy (the_passwd.pw_name, "unknown"); | 264 strcpy (the_passwd.pw_name, "unknown"); |
245 the_passwd.pw_uid = 123; | 265 the_passwd.pw_uid = 123; |
246 the_passwd.pw_gid = 123; | 266 the_passwd.pw_gid = 123; |
247 } | 267 } |
248 | 268 |
269 if (token) | |
270 CloseHandle (token); | |
271 #else | |
272 /* Obtain only logon id here, uid part is moved to getuid */ | |
273 char name[256]; | |
274 DWORD length = sizeof (name); | |
275 if (GetUserName (name, &length)) | |
276 strcpy (the_passwd.pw_name, name); | |
277 else | |
278 strcpy (the_passwd.pw_name, "unknown"); | |
279 #endif | |
280 | |
249 /* Ensure HOME and SHELL are defined. */ | 281 /* Ensure HOME and SHELL are defined. */ |
250 #if 0 | 282 #if 0 |
251 /* | 283 /* |
252 * With XEmacs, setting $HOME is deprecated. | 284 * With XEmacs, setting $HOME is deprecated. |
253 */ | 285 */ |
258 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); | 290 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); |
259 | 291 |
260 /* Set dir and shell from environment variables. */ | 292 /* Set dir and shell from environment variables. */ |
261 strcpy (the_passwd.pw_dir, get_home_directory()); | 293 strcpy (the_passwd.pw_dir, get_home_directory()); |
262 strcpy (the_passwd.pw_shell, getenv ("SHELL")); | 294 strcpy (the_passwd.pw_shell, getenv ("SHELL")); |
263 | |
264 if (token) | |
265 CloseHandle (token); | |
266 } | 295 } |
267 | 296 |
268 /* Normalize filename by converting all path separators to | 297 /* Normalize filename by converting all path separators to |
269 the specified separator. Also conditionally convert upper | 298 the specified separator. Also conditionally convert upper |
270 case path name components to lower case. */ | 299 case path name components to lower case. */ |
531 LPDWORD lpdwtype; | 560 LPDWORD lpdwtype; |
532 { | 561 { |
533 LPBYTE lpvalue; | 562 LPBYTE lpvalue; |
534 HKEY hrootkey = NULL; | 563 HKEY hrootkey = NULL; |
535 DWORD cbData; | 564 DWORD cbData; |
536 BOOL ok = FALSE; | |
537 | 565 |
538 /* Check both the current user and the local machine to see if | 566 /* Check both the current user and the local machine to see if |
539 we have any resources. */ | 567 we have any resources. */ |
540 | 568 |
541 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) | 569 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) |
594 "EMACSPATH", | 622 "EMACSPATH", |
595 "EMACSPACKAGEPATH", | 623 "EMACSPACKAGEPATH", |
596 "EMACSLOCKDIR", | 624 "EMACSLOCKDIR", |
597 "INFOPATH" | 625 "INFOPATH" |
598 }; | 626 }; |
599 | 627 #ifdef HEAP_IN_DATA |
628 cache_system_info (); | |
629 #endif | |
600 for (i = 0; i < countof (env_vars); i++) | 630 for (i = 0; i < countof (env_vars); i++) |
601 { | 631 { |
602 if (!getenv (env_vars[i]) && | 632 if (!getenv (env_vars[i]) && |
603 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL) | 633 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL) |
604 { | 634 { |
940 map_win32_filename (const char * name, const char ** pPath) | 970 map_win32_filename (const char * name, const char ** pPath) |
941 { | 971 { |
942 static char shortname[MAX_PATH]; | 972 static char shortname[MAX_PATH]; |
943 char * str = shortname; | 973 char * str = shortname; |
944 char c; | 974 char c; |
945 char * path; | 975 const char * path; |
946 const char * save_name = name; | 976 const char * save_name = name; |
947 | 977 |
948 if (is_fat_volume (name, &path)) /* truncate to 8.3 */ | 978 if (is_fat_volume (name, &path)) /* truncate to 8.3 */ |
949 { | 979 { |
950 REGISTER int left = 8; /* maximum number of chars in part */ | 980 REGISTER int left = 8; /* maximum number of chars in part */ |
1050 DIR *dirp; | 1080 DIR *dirp; |
1051 | 1081 |
1052 /* Opening is done by FindFirstFile. However, a read is inherent to | 1082 /* Opening is done by FindFirstFile. However, a read is inherent to |
1053 this operation, so we defer the open until read time. */ | 1083 this operation, so we defer the open until read time. */ |
1054 | 1084 |
1055 if (!(dirp = (DIR *) xmalloc (sizeof (DIR)))) | 1085 if (!(dirp = xnew_and_zero(DIR))) |
1056 return NULL; | 1086 return NULL; |
1057 if (dir_find_handle != INVALID_HANDLE_VALUE) | 1087 if (dir_find_handle != INVALID_HANDLE_VALUE) |
1058 return NULL; | 1088 return NULL; |
1059 | 1089 |
1060 dirp->dd_fd = 0; | 1090 dirp->dd_fd = 0; |
1075 if (dir_find_handle != INVALID_HANDLE_VALUE) | 1105 if (dir_find_handle != INVALID_HANDLE_VALUE) |
1076 { | 1106 { |
1077 FindClose (dir_find_handle); | 1107 FindClose (dir_find_handle); |
1078 dir_find_handle = INVALID_HANDLE_VALUE; | 1108 dir_find_handle = INVALID_HANDLE_VALUE; |
1079 } | 1109 } |
1080 xfree ((char *) dirp); | 1110 xfree (dirp); |
1081 } | 1111 } |
1082 | 1112 |
1083 struct direct * | 1113 struct direct * |
1084 readdir (DIR *dirp) | 1114 readdir (DIR *dirp) |
1085 { | 1115 { |
1188 return rename (temp, newname); | 1218 return rename (temp, newname); |
1189 } | 1219 } |
1190 #endif /* 0 */ | 1220 #endif /* 0 */ |
1191 | 1221 |
1192 static FILETIME utc_base_ft; | 1222 static FILETIME utc_base_ft; |
1223 static int init = 0; | |
1224 | |
1225 #if 0 | |
1226 | |
1193 static long double utc_base; | 1227 static long double utc_base; |
1194 static int init = 0; | |
1195 | 1228 |
1196 time_t | 1229 time_t |
1197 convert_time (FILETIME ft) | 1230 convert_time (FILETIME ft) |
1198 { | 1231 { |
1199 long double ret; | 1232 long double ret; |
1222 | 1255 |
1223 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime; | 1256 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime; |
1224 ret -= utc_base; | 1257 ret -= utc_base; |
1225 return (time_t) (ret * 1e-7); | 1258 return (time_t) (ret * 1e-7); |
1226 } | 1259 } |
1227 | 1260 #else |
1228 #if 0 | 1261 |
1229 /* in case we ever have need of this */ | 1262 static LARGE_INTEGER utc_base_li; |
1230 void | 1263 |
1231 convert_from_time_t (time_t time, FILETIME * pft) | 1264 time_t |
1232 { | 1265 convert_time (FILETIME uft) |
1233 long double tmp; | 1266 { |
1267 time_t ret; | |
1268 #ifndef MAXLONGLONG | |
1269 SYSTEMTIME st; | |
1270 struct tm t; | |
1271 FILETIME ft; | |
1272 TIME_ZONE_INFORMATION tzi; | |
1273 DWORD tzid; | |
1274 #else | |
1275 LARGE_INTEGER lft; | |
1276 #endif | |
1234 | 1277 |
1235 if (!init) | 1278 if (!init) |
1236 { | 1279 { |
1237 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ | 1280 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ |
1238 SYSTEMTIME st; | 1281 SYSTEMTIME st; |
1244 st.wMinute = 0; | 1287 st.wMinute = 0; |
1245 st.wSecond = 0; | 1288 st.wSecond = 0; |
1246 st.wMilliseconds = 0; | 1289 st.wMilliseconds = 0; |
1247 | 1290 |
1248 SystemTimeToFileTime (&st, &utc_base_ft); | 1291 SystemTimeToFileTime (&st, &utc_base_ft); |
1292 | |
1293 utc_base_li.LowPart = utc_base_ft.dwLowDateTime; | |
1294 utc_base_li.HighPart = utc_base_ft.dwHighDateTime; | |
1295 | |
1296 init = 1; | |
1297 } | |
1298 | |
1299 #ifdef MAXLONGLONG | |
1300 | |
1301 /* On a compiler that supports long integers, do it the easy way */ | |
1302 lft.LowPart = uft.dwLowDateTime; | |
1303 lft.HighPart = uft.dwHighDateTime; | |
1304 ret = (time_t) ((lft.QuadPart - utc_base_li.QuadPart) / 10000000); | |
1305 | |
1306 #else | |
1307 | |
1308 /* Do it the hard way using mktime. */ | |
1309 FileTimeToLocalFileTime(&uft, &ft); | |
1310 FileTimeToSystemTime (&ft, &st); | |
1311 tzid = GetTimeZoneInformation (&tzi); | |
1312 t.tm_year = st.wYear - 1900; | |
1313 t.tm_mon = st.wMonth - 1; | |
1314 t.tm_mday = st.wDay; | |
1315 t.tm_hour = st.wHour; | |
1316 t.tm_min = st.wMinute; | |
1317 t.tm_sec = st.wSecond; | |
1318 t.tm_isdst = (tzid == TIME_ZONE_ID_DAYLIGHT); | |
1319 /* st.wMilliseconds not applicable */ | |
1320 ret = mktime(&t); | |
1321 if (ret == -1) | |
1322 { | |
1323 ret = 0; | |
1324 } | |
1325 | |
1326 #endif | |
1327 | |
1328 return ret; | |
1329 } | |
1330 #endif | |
1331 | |
1332 #if 0 | |
1333 /* in case we ever have need of this */ | |
1334 void | |
1335 convert_from_time_t (time_t time, FILETIME * pft) | |
1336 { | |
1337 long double tmp; | |
1338 | |
1339 if (!init) | |
1340 { | |
1341 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ | |
1342 SYSTEMTIME st; | |
1343 | |
1344 st.wYear = 1970; | |
1345 st.wMonth = 1; | |
1346 st.wDay = 1; | |
1347 st.wHour = 0; | |
1348 st.wMinute = 0; | |
1349 st.wSecond = 0; | |
1350 st.wMilliseconds = 0; | |
1351 | |
1352 SystemTimeToFileTime (&st, &utc_base_ft); | |
1249 utc_base = (long double) utc_base_ft.dwHighDateTime | 1353 utc_base = (long double) utc_base_ft.dwHighDateTime |
1250 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime; | 1354 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime; |
1251 init = 1; | 1355 init = 1; |
1252 } | 1356 } |
1253 | 1357 |
1298 _strlwr (p); | 1402 _strlwr (p); |
1299 return hashval (p); | 1403 return hashval (p); |
1300 } | 1404 } |
1301 | 1405 |
1302 #endif | 1406 #endif |
1407 | |
1408 /* stat has been fixed since MSVC 5.0. | |
1409 Oh, and do not encapsulater stat for non-MS compilers, too */ | |
1410 /* #### popineau@ese-metz.fr says they still might be broken. | |
1411 Oh well... Let's add that `1 ||' condition.... --kkm */ | |
1412 #if 1 || defined(_MSC_VER) && _MSC_VER < 1100 | |
1413 | |
1414 /* Since stat is encapsulated on Windows NT, we need to encapsulate | |
1415 the equally broken fstat as well. */ | |
1416 int _cdecl | |
1417 fstat (int handle, struct stat *buffer) | |
1418 { | |
1419 int ret; | |
1420 BY_HANDLE_FILE_INFORMATION lpFileInfo; | |
1421 /* Initialize values */ | |
1422 buffer->st_mode = 0; | |
1423 buffer->st_size = 0; | |
1424 buffer->st_dev = 0; | |
1425 buffer->st_rdev = 0; | |
1426 buffer->st_atime = 0; | |
1427 buffer->st_ctime = 0; | |
1428 buffer->st_mtime = 0; | |
1429 buffer->st_nlink = 0; | |
1430 ret = GetFileInformationByHandle((HANDLE) _get_osfhandle(handle), &lpFileInfo); | |
1431 if (!ret) | |
1432 { | |
1433 return -1; | |
1434 } | |
1435 else | |
1436 { | |
1437 buffer->st_mtime = convert_time (lpFileInfo.ftLastWriteTime); | |
1438 buffer->st_atime = convert_time (lpFileInfo.ftLastAccessTime); | |
1439 if (buffer->st_atime == 0) buffer->st_atime = buffer->st_mtime; | |
1440 buffer->st_ctime = convert_time (lpFileInfo.ftCreationTime); | |
1441 if (buffer->st_ctime == 0) buffer->st_ctime = buffer->st_mtime; | |
1442 buffer->st_size = lpFileInfo.nFileSizeLow; | |
1443 buffer->st_nlink = (short) lpFileInfo.nNumberOfLinks; | |
1444 return 0; | |
1445 } | |
1446 } | |
1303 | 1447 |
1304 /* MSVC stat function can't cope with UNC names and has other bugs, so | 1448 /* MSVC stat function can't cope with UNC names and has other bugs, so |
1305 replace it with our own. This also allows us to calculate consistent | 1449 replace it with our own. This also allows us to calculate consistent |
1306 inode values without hacks in the main Emacs code. */ | 1450 inode values without hacks in the main Emacs code. */ |
1307 int | 1451 int |
1451 | 1595 |
1452 /* #### MSVC defines _ino_t to be short; other libc's might not. */ | 1596 /* #### MSVC defines _ino_t to be short; other libc's might not. */ |
1453 buf->st_ino = (unsigned short) (fake_inode ^ (fake_inode >> 16)); | 1597 buf->st_ino = (unsigned short) (fake_inode ^ (fake_inode >> 16)); |
1454 | 1598 |
1455 /* consider files to belong to current user */ | 1599 /* consider files to belong to current user */ |
1456 buf->st_uid = the_passwd.pw_uid; | 1600 buf->st_uid = buf->st_gid = nt_fake_unix_uid; |
1457 buf->st_gid = the_passwd.pw_gid; | |
1458 | 1601 |
1459 /* volume_info is set indirectly by map_win32_filename */ | 1602 /* volume_info is set indirectly by map_win32_filename */ |
1460 buf->st_dev = volume_info.serialnum; | 1603 buf->st_dev = volume_info.serialnum; |
1461 buf->st_rdev = volume_info.serialnum; | 1604 buf->st_rdev = volume_info.serialnum; |
1462 | |
1463 | 1605 |
1464 buf->st_size = wfd.nFileSizeLow; | 1606 buf->st_size = wfd.nFileSizeLow; |
1465 | 1607 |
1466 /* Convert timestamps to Unix format. */ | 1608 /* Convert timestamps to Unix format. */ |
1467 buf->st_mtime = convert_time (wfd.ftLastWriteTime); | 1609 buf->st_mtime = convert_time (wfd.ftLastWriteTime); |
1491 | 1633 |
1492 buf->st_mode |= permission | (permission >> 3) | (permission >> 6); | 1634 buf->st_mode |= permission | (permission >> 3) | (permission >> 6); |
1493 | 1635 |
1494 return 0; | 1636 return 0; |
1495 } | 1637 } |
1638 #endif /* defined(_MSC_VER) && _MSC_VER < 1100 */ | |
1496 | 1639 |
1497 /* From callproc.c */ | 1640 /* From callproc.c */ |
1498 extern Lisp_Object Vbinary_process_input; | 1641 extern Lisp_Object Vbinary_process_input; |
1499 extern Lisp_Object Vbinary_process_output; | 1642 extern Lisp_Object Vbinary_process_output; |
1500 | 1643 |
1523 flags |= FILE_BINARY; | 1666 flags |= FILE_BINARY; |
1524 fd_info[phandles[1]].flags = flags; | 1667 fd_info[phandles[1]].flags = flags; |
1525 } | 1668 } |
1526 | 1669 |
1527 return rc; | 1670 return rc; |
1528 } | |
1529 | |
1530 /* From ntproc.c */ | |
1531 extern Lisp_Object Vwin32_pipe_read_delay; | |
1532 | |
1533 /* Function to do blocking read of one byte, needed to implement | |
1534 select. It is only allowed on sockets and pipes. */ | |
1535 int | |
1536 _sys_read_ahead (int fd) | |
1537 { | |
1538 child_process * cp; | |
1539 int rc; | |
1540 | |
1541 if (fd < 0 || fd >= MAXDESC) | |
1542 return STATUS_READ_ERROR; | |
1543 | |
1544 cp = fd_info[fd].cp; | |
1545 | |
1546 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY) | |
1547 return STATUS_READ_ERROR; | |
1548 | |
1549 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0 | |
1550 || (fd_info[fd].flags & FILE_READ) == 0) | |
1551 { | |
1552 /* fd is not a pipe or socket */ | |
1553 abort (); | |
1554 } | |
1555 | |
1556 cp->status = STATUS_READ_IN_PROGRESS; | |
1557 | |
1558 if (fd_info[fd].flags & FILE_PIPE) | |
1559 { | |
1560 rc = _read (fd, &cp->chr, sizeof (char)); | |
1561 | |
1562 /* Give subprocess time to buffer some more output for us before | |
1563 reporting that input is available; we need this because Win95 | |
1564 connects DOS programs to pipes by making the pipe appear to be | |
1565 the normal console stdout - as a result most DOS programs will | |
1566 write to stdout without buffering, ie. one character at a | |
1567 time. Even some Win32 programs do this - "dir" in a command | |
1568 shell on NT is very slow if we don't do this. */ | |
1569 if (rc > 0) | |
1570 { | |
1571 int wait = XINT (Vwin32_pipe_read_delay); | |
1572 | |
1573 if (wait > 0) | |
1574 Sleep (wait); | |
1575 else if (wait < 0) | |
1576 while (++wait <= 0) | |
1577 /* Yield remainder of our time slice, effectively giving a | |
1578 temporary priority boost to the child process. */ | |
1579 Sleep (0); | |
1580 } | |
1581 } | |
1582 | |
1583 if (rc == sizeof (char)) | |
1584 cp->status = STATUS_READ_SUCCEEDED; | |
1585 else | |
1586 cp->status = STATUS_READ_FAILED; | |
1587 | |
1588 return cp->status; | |
1589 } | 1671 } |
1590 | 1672 |
1591 void | 1673 void |
1592 term_ntproc (int unused) | 1674 term_ntproc (int unused) |
1593 { | 1675 { |
1808 /* Default signal actions */ | 1890 /* Default signal actions */ |
1809 if (nsig == SIGALRM || nsig == SIGPROF) | 1891 if (nsig == SIGALRM || nsig == SIGPROF) |
1810 exit (3); | 1892 exit (3); |
1811 | 1893 |
1812 /* Other signals are ignored by default */ | 1894 /* Other signals are ignored by default */ |
1895 return 0; | |
1813 } | 1896 } |
1814 | 1897 |
1815 /*--------------------------------------------------------------------*/ | 1898 /*--------------------------------------------------------------------*/ |
1816 /* Async timers */ | 1899 /* Async timers */ |
1817 /*--------------------------------------------------------------------*/ | 1900 /*--------------------------------------------------------------------*/ |
1926 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); | 2009 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); |
1927 else | 2010 else |
1928 return errno = EINVAL; | 2011 return errno = EINVAL; |
1929 } | 2012 } |
1930 | 2013 |
2014 int | |
2015 open_input_file (file_data *p_file, const char *filename) | |
2016 { | |
2017 HANDLE file; | |
2018 HANDLE file_mapping; | |
2019 void *file_base; | |
2020 DWORD size, upper_size; | |
2021 | |
2022 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
2023 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
2024 if (file == INVALID_HANDLE_VALUE) | |
2025 return FALSE; | |
2026 | |
2027 size = GetFileSize (file, &upper_size); | |
2028 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY, | |
2029 0, size, NULL); | |
2030 if (!file_mapping) | |
2031 return FALSE; | |
2032 | |
2033 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); | |
2034 if (file_base == 0) | |
2035 return FALSE; | |
2036 | |
2037 p_file->name = (char*)filename; | |
2038 p_file->size = size; | |
2039 p_file->file = file; | |
2040 p_file->file_mapping = file_mapping; | |
2041 p_file->file_base = file_base; | |
2042 | |
2043 return TRUE; | |
2044 } | |
2045 | |
2046 /* Close the system structures associated with the given file. */ | |
2047 void | |
2048 close_file_data (file_data *p_file) | |
2049 { | |
2050 UnmapViewOfFile (p_file->file_base); | |
2051 CloseHandle (p_file->file_mapping); | |
2052 CloseHandle (p_file->file); | |
2053 } | |
2054 | |
2055 void | |
2056 vars_of_nt (void) | |
2057 { | |
2058 DEFVAR_INT ("nt-fake-unix-uid", &nt_fake_unix_uid /* | |
2059 *Set uid returned by `user-uid' and `user-real-uid'. | |
2060 Under NT and 9x, there is no uids, and even no almighty user called root. | |
2061 By setting this variable, you can have any uid of choice. Default is 0. | |
2062 Changes to this variable take effect immediately. | |
2063 */ ); | |
2064 nt_fake_unix_uid = 0; | |
2065 } | |
2066 | |
1931 /* end of nt.c */ | 2067 /* end of nt.c */ |