Changeset 3677
- Timestamp:
- 04/10/05 17:53:48 (4 years ago)
- Files:
-
- branches/2.2/src/ChangeLog.Meadow (modified) (1 diff)
- branches/2.2/src/puresize.h (modified) (4 diffs)
- branches/2.2/src/w32.c (modified) (39 diffs)
- branches/2.2/src/w32.h (modified) (3 diffs)
- branches/2.2/src/w32inevt.c (modified) (3 diffs)
- branches/2.2/src/w32proc.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/2.2/src/ChangeLog.Meadow
r3676 r3677 1 2005-04-10 MIYOSHI Masanori <miyoshi@meadowy.org> 2 3 * puresize.h: Sync up with Emacs CVS HEAD. 4 5 * w32.c: Ditto. 6 7 * w32.h: Ditto. 8 9 * w32inevt.c (w32_console_read_socket): Ditto. 10 11 * w32proc.c (syms_of_ntproc): Ditto. 12 1 13 2005-04-10 MIYOSHI Masanori <miyoshi@meadowy.org> 2 14 branches/2.2/src/puresize.h
r3601 r3677 48 48 /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ 49 49 #ifndef PURESIZE_RATIO 50 #if VALBITS + GCTYPEBITS + 1> 3251 #define PURESIZE_RATIO 8/5 /* Don't surround with `()'. */50 #if BITS_PER_EMACS_INT > 32 51 #define PURESIZE_RATIO 9/5 /* Don't surround with `()'. */ 52 52 #else 53 53 #define PURESIZE_RATIO 1 … … 63 63 #ifdef PDUMP 64 64 #define CHECK_IMPURE(obj) 65 #else /* PDUMP */65 #else /* not PDUMP */ 66 66 #define CHECK_IMPURE(obj) \ 67 67 { if (PURE_P (obj)) \ 68 68 pure_write_error (); } 69 #endif /* PDUMP */69 #endif /* not PDUMP */ 70 70 71 71 extern void pure_write_error P_ ((void)); … … 75 75 #ifdef PDUMP 76 76 #define PURE_P(obj) 0 77 #else /* PDUMP */78 #if def VIRT_ADDR_VARIES77 #else /* not PDUMP */ 78 #if defined(VIRT_ADDR_VARIES) || defined(CYGWIN) 79 79 /* For machines like APOLLO where text and data can go anywhere 80 80 in virtual memory. */ … … 104 104 #endif /* PNTR_COMPARISON_TYPE */ 105 105 #endif /* VIRT_ADDRESS_VARIES */ 106 #endif /* PDUMP */106 #endif /* not PDUMP */ 107 107 108 108 branches/2.2/src/w32.c
r3664 r3677 69 69 #include <grp.h> 70 70 71 #include <windows.h>72 73 #ifdef MEADOW74 #include <tchar.h>75 #include "mw32reg.h"76 #include "mw32sync.h"77 #endif78 #include "charset.h"79 #include "coding.h"80 extern Lisp_Object Vfile_name_coding_system;81 82 #include <shellapi.h>83 84 71 #ifdef __GNUC__ 85 72 #define _ANONYMOUS_UNION 86 73 #define _ANONYMOUS_STRUCT 74 #endif 75 #include <windows.h> 76 77 #ifdef MEADOW 78 #include <tchar.h> 79 #include <shellapi.h> 80 #include "mw32reg.h" 81 #include "mw32sync.h" 82 83 extern Lisp_Object Vfile_name_coding_system; 87 84 #endif 88 85 … … 120 117 #endif 121 118 119 void globals_of_w32 (); 120 122 121 extern Lisp_Object Vw32_downcase_file_names; 123 122 extern Lisp_Object Vw32_generate_fake_inodes; … … 126 125 extern Lisp_Object Vw32_get_true_file_link_count; 127 126 #endif 127 extern int w32_num_mouse_buttons; 128 129 130 /* 131 Initialization states 132 */ 133 static BOOL g_b_init_is_windows_9x; 134 static BOOL g_b_init_open_process_token; 135 static BOOL g_b_init_get_token_information; 136 static BOOL g_b_init_lookup_account_sid; 137 static BOOL g_b_init_get_sid_identifier_authority; 138 139 /* 140 BEGIN: Wrapper functions around OpenProcessToken 141 and other functions in advapi32.dll that are only 142 supported in Windows NT / 2k / XP 143 */ 144 /* ** Function pointer typedefs ** */ 145 typedef BOOL (WINAPI * OpenProcessToken_Proc) ( 146 HANDLE ProcessHandle, 147 DWORD DesiredAccess, 148 PHANDLE TokenHandle); 149 typedef BOOL (WINAPI * GetTokenInformation_Proc) ( 150 HANDLE TokenHandle, 151 TOKEN_INFORMATION_CLASS TokenInformationClass, 152 LPVOID TokenInformation, 153 DWORD TokenInformationLength, 154 PDWORD ReturnLength); 155 #ifdef _UNICODE 156 const char * const LookupAccountSid_Name = "LookupAccountSidW"; 157 #else 158 const char * const LookupAccountSid_Name = "LookupAccountSidA"; 159 #endif 160 typedef BOOL (WINAPI * LookupAccountSid_Proc) ( 161 LPCTSTR lpSystemName, 162 PSID Sid, 163 LPTSTR Name, 164 LPDWORD cbName, 165 LPTSTR DomainName, 166 LPDWORD cbDomainName, 167 PSID_NAME_USE peUse); 168 typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) ( 169 PSID pSid); 170 171 /* ** A utility function ** */ 172 static BOOL is_windows_9x () 173 { 174 static BOOL s_b_ret=0; 175 OSVERSIONINFO os_ver; 176 if (g_b_init_is_windows_9x == 0) 177 { 178 g_b_init_is_windows_9x = 1; 179 ZeroMemory(&os_ver, sizeof(OSVERSIONINFO)); 180 os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 181 if (GetVersionEx (&os_ver)) 182 { 183 s_b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); 184 } 185 } 186 return s_b_ret; 187 } 188 189 /* ** The wrapper functions ** */ 190 191 BOOL WINAPI open_process_token ( 192 HANDLE ProcessHandle, 193 DWORD DesiredAccess, 194 PHANDLE TokenHandle) 195 { 196 static OpenProcessToken_Proc s_pfn_Open_Process_Token = NULL; 197 HMODULE hm_advapi32 = NULL; 198 if (is_windows_9x () == TRUE) 199 { 200 return FALSE; 201 } 202 if (g_b_init_open_process_token == 0) 203 { 204 g_b_init_open_process_token = 1; 205 hm_advapi32 = LoadLibrary ("Advapi32.dll"); 206 s_pfn_Open_Process_Token = 207 (OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken"); 208 } 209 if (s_pfn_Open_Process_Token == NULL) 210 { 211 return FALSE; 212 } 213 return ( 214 s_pfn_Open_Process_Token ( 215 ProcessHandle, 216 DesiredAccess, 217 TokenHandle) 218 ); 219 } 220 221 BOOL WINAPI get_token_information ( 222 HANDLE TokenHandle, 223 TOKEN_INFORMATION_CLASS TokenInformationClass, 224 LPVOID TokenInformation, 225 DWORD TokenInformationLength, 226 PDWORD ReturnLength) 227 { 228 static GetTokenInformation_Proc s_pfn_Get_Token_Information = NULL; 229 HMODULE hm_advapi32 = NULL; 230 if (is_windows_9x () == TRUE) 231 { 232 return FALSE; 233 } 234 if (g_b_init_get_token_information == 0) 235 { 236 g_b_init_get_token_information = 1; 237 hm_advapi32 = LoadLibrary ("Advapi32.dll"); 238 s_pfn_Get_Token_Information = 239 (GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation"); 240 } 241 if (s_pfn_Get_Token_Information == NULL) 242 { 243 return FALSE; 244 } 245 return ( 246 s_pfn_Get_Token_Information ( 247 TokenHandle, 248 TokenInformationClass, 249 TokenInformation, 250 TokenInformationLength, 251 ReturnLength) 252 ); 253 } 254 255 BOOL WINAPI lookup_account_sid ( 256 LPCTSTR lpSystemName, 257 PSID Sid, 258 LPTSTR Name, 259 LPDWORD cbName, 260 LPTSTR DomainName, 261 LPDWORD cbDomainName, 262 PSID_NAME_USE peUse) 263 { 264 static LookupAccountSid_Proc s_pfn_Lookup_Account_Sid = NULL; 265 HMODULE hm_advapi32 = NULL; 266 if (is_windows_9x () == TRUE) 267 { 268 return FALSE; 269 } 270 if (g_b_init_lookup_account_sid == 0) 271 { 272 g_b_init_lookup_account_sid = 1; 273 hm_advapi32 = LoadLibrary ("Advapi32.dll"); 274 s_pfn_Lookup_Account_Sid = 275 (LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name); 276 } 277 if (s_pfn_Lookup_Account_Sid == NULL) 278 { 279 return FALSE; 280 } 281 return ( 282 s_pfn_Lookup_Account_Sid ( 283 lpSystemName, 284 Sid, 285 Name, 286 cbName, 287 DomainName, 288 cbDomainName, 289 peUse) 290 ); 291 } 292 293 PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority ( 294 PSID pSid) 295 { 296 static GetSidIdentifierAuthority_Proc s_pfn_Get_Sid_Identifier_Authority = NULL; 297 HMODULE hm_advapi32 = NULL; 298 if (is_windows_9x () == TRUE) 299 { 300 return NULL; 301 } 302 if (g_b_init_get_sid_identifier_authority == 0) 303 { 304 g_b_init_get_sid_identifier_authority = 1; 305 hm_advapi32 = LoadLibrary ("Advapi32.dll"); 306 s_pfn_Get_Sid_Identifier_Authority = 307 (GetSidIdentifierAuthority_Proc) GetProcAddress ( 308 hm_advapi32, "GetSidIdentifierAuthority"); 309 } 310 if (s_pfn_Get_Sid_Identifier_Authority == NULL) 311 { 312 return NULL; 313 } 314 return (s_pfn_Get_Sid_Identifier_Authority (pSid)); 315 } 128 316 129 317 /* Array of W32 filename special characters */ … … 133 321 w32_filename_special_characters[] = {'*', '?', '<', '>', '\"', '\\', '/', 0}; 134 322 135 #ifndef MEADOW 136 extern Lisp_Object Vw32_num_mouse_buttons; 137 #endif 323 /* 324 END: Wrapper functions around OpenProcessToken 325 and other functions in advapi32.dll that are only 326 supported in Windows NT / 2k / XP 327 */ 138 328 139 329 … … 172 362 conflicts when trying to rename or delete directories. */ 173 363 strcpy (dir, startup_dir); 174 dostounix_filename (dir);364 dostounix_filename (dir); 175 365 return dir; 176 366 #endif … … 302 492 SID_NAME_USE user_type; 303 493 304 if ( OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token)305 && GetTokenInformation (token, TokenUser,494 if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token) 495 && get_token_information (token, TokenUser, 306 496 (PVOID) user_sid, sizeof (user_sid), &trash) 307 && LookupAccountSid (NULL, *((PSID *) user_sid), name, &length,497 && lookup_account_sid (NULL, *((PSID *) user_sid), name, &length, 308 498 domain, &dlength, &user_type)) 309 499 { … … 319 509 SID_IDENTIFIER_AUTHORITY * pSIA; 320 510 321 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));511 pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); 322 512 /* I believe the relative portion is the last 4 bytes (of 6) 323 513 with msb first. */ … … 330 520 331 521 /* Get group id */ 332 if ( GetTokenInformation (token, TokenPrimaryGroup,522 if (get_token_information (token, TokenPrimaryGroup, 333 523 (PVOID) user_sid, sizeof (user_sid), &trash)) 334 524 { 335 525 SID_IDENTIFIER_AUTHORITY * pSIA; 336 526 337 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));527 pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); 338 528 the_passwd.pw_gid = ((pSIA->Value[2] << 24) + 339 529 (pSIA->Value[3] << 16) + … … 415 605 the specified separator. Also conditionally convert upper 416 606 case path name components to lower case. */ 607 417 608 static void 418 609 normalize_filename (LPTSTR fp, TCHAR path_sep) … … 428 619 functions that are case-sensitive. Even case-preserving filesystems 429 620 do not distinguish case in drive letters. */ 430 if ((*fp >= 'A' && *fp <= 'Z') 431 && (*(CharNext (fp)) == ':')) 621 if (*(CharNext (fp)) == ':' && *fp >= 'A' && *fp <= 'Z') 432 622 { 433 623 next_char = tolower (*fp); … … 564 754 } 565 755 566 567 756 /* Destructively turn backslashes into slashes. */ 568 757 void … … 610 799 } 611 800 612 /* Parse the root part of file name, if present. Return bytelength and801 /* Parse the root part of file name, if present. Return length and 613 802 optionally store pointer to char after root. */ 614 803 static int … … 656 845 *pPath = name; 657 846 658 return (name - start) / sizeof (TCHAR);847 return (name - start) / sizeof (TCHAR); 659 848 } 660 849 … … 675 864 { 676 865 if ((len = lstrlen (find_data.cFileName)) < size) 677 memcpy (buf, find_data.cFileName, sizeof (TCHAR) * (len + 1));866 memcpy (buf, find_data.cFileName, sizeof (TCHAR) * (len + 1)); 678 867 else 679 868 len = 0; … … 698 887 699 888 /* Use local copy for destructive modification. */ 700 memcpy (full, name, sizeof (TCHAR) * (len + 1));889 memcpy (full, name, sizeof (TCHAR) * (len + 1)); 701 890 unixtodos_filename (full); 702 891 703 892 /* Copy root part verbatim. */ 704 893 len = parse_root (full, &p); 705 memcpy (o, full, sizeof (TCHAR) * len);894 memcpy (o, full, sizeof (TCHAR) * len); 706 895 o += len; 707 896 *o = '\0'; … … 870 1059 return (NULL); 871 1060 } 872 #else /* not MEADOW */ 873 #endif 1061 #endif /* not MEADOW */ 874 1062 875 1063 char *get_emacs_configuration (void); … … 877 1065 878 1066 void 879 init_time_zone_info () 880 { 881 char *tzstr; 882 tzstr = getenv ("TZ"); 883 if (!tzstr) 884 { 885 TIME_ZONE_INFORMATION tzi; 886 DWORD ret; 887 char tmp[256]; 888 ret = GetTimeZoneInformation (&tzi); 889 if (ret == 0xFFFFFFFF) 890 { 891 putenv ("TZ=GMT+0"); /* can't help setting this. */ 892 } 893 else 894 { 895 int biashour, biasmin, dlhour, dlmin; 896 897 biashour = tzi.Bias / 60; 898 biasmin = (tzi.Bias >= 0) ? tzi.Bias : -tzi.Bias; 899 biasmin %= 60; 900 dlmin = tzi.Bias + tzi.DaylightBias; 901 dlhour = dlmin / 60; 902 dlmin = (dlmin >= 0) ? dlmin : -dlmin; 903 dlmin %= 60; 904 905 if (ret == TIME_ZONE_ID_UNKNOWN) 906 { 907 if (tzi.DaylightBias != 0) 908 { 909 sprintf (tmp, "TZ=LMT%+d:%02dLDT%+d:%02d", 910 biashour, biasmin, 911 dlhour, dlmin); 912 } 913 else 914 { 915 sprintf (tmp, "TZ=LMT%+d:%02d", 916 biashour, biasmin); 917 } 918 putenv (tmp); 919 } 920 else if (ret == TIME_ZONE_ID_STANDARD) 921 { 922 #if 0 923 sprintf (tmp, "TZ=%s%+d:%02d", 924 tzi.StandardName, 925 biashour, biasmin); 926 #else 927 sprintf (tmp, "TZ=LMT%+d:%02d", 928 biashour, biasmin); 929 #endif 930 putenv (tmp); 931 } 932 else if (ret == TIME_ZONE_ID_DAYLIGHT) 933 { 934 #if 0 935 sprintf (tmp, "TZ=%s%+d:%02d%s%+d:%02d", 936 tzi.StandardName, 937 biashour, biasmin, 938 tzi.DaylightName, 939 dlhour, dlmin); 940 #else 941 sprintf (tmp, "TZ=LMT%+d:%02dLDT%+d:%02d", 942 biashour, biasmin, 943 dlhour, dlmin); 944 #endif 945 putenv (tmp); 946 } 947 } 948 } 949 _tzset (); 950 } 951 952 void 953 init_environment (char **argv) 1067 init_environment (char ** argv) 954 1068 { 955 1069 static const char * const tempdirs[] = { … … 1009 1123 {"EMACSDATA", "%emacs_dir%/etc"}, 1010 1124 {"EMACSPATH", "%emacs_dir%/bin"}, 1011 {"EMACSLOCKDIR", "%emacs_dir%/lock"},1012 1125 /* We no longer set INFOPATH because Info-default-directory-list 1013 1126 is then ignored. */ … … 1063 1176 _putenv (strdup (buf)); 1064 1177 } 1178 /* Handle running emacs from the build directory: src/oo-spd/i386/ */ 1179 1180 /* FIXME: should use substring of get_emacs_configuration (). 1181 But I don't think the Windows build supports alpha, mips etc 1182 anymore, so have taken the easy option for now. */ 1183 else if (p && stricmp (p, "\\i386") == 0) 1184 { 1185 *p = 0; 1186 p = strrchr (modname, '\\'); 1187 if (p != NULL) 1188 { 1189 *p = 0; 1190 p = strrchr (modname, '\\'); 1191 if (p && stricmp (p, "\\src") == 0) 1192 { 1193 char buf[SET_ENV_BUF_SIZE]; 1194 1195 *p = 0; 1196 for (p = modname; *p; p++) 1197 if (*p == '\\') *p = '/'; 1198 1199 _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname); 1200 _putenv (strdup (buf)); 1201 } 1202 } 1203 } 1065 1204 } 1066 1205 … … 1110 1249 Vsystem_configuration = build_string (EMACS_CONFIGURATION); 1111 1250 1112 /* Initialize time zone infomation */1113 init_time_zone_info ();1114 1115 1251 /* Another special case: on NT, the PATH variable is actually named 1116 1252 "Path" although cmd.exe (perhaps NT itself) arranges for … … 1165 1301 to decide whether right mouse events should be mouse-2 or 1166 1302 mouse-3. */ 1167 XSETINT (Vw32_num_mouse_buttons, GetSystemMetrics (SM_CMOUSEBUTTONS));1303 w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS); 1168 1304 #endif 1169 1305 … … 1197 1333 int build_num; 1198 1334 static char configuration_buffer[32]; 1199 OSVERSIONINFO osinfo ;1200 1201 osinfo .dwOSVersionInfoSize = sizeof (OSVERSIONINFO);1202 GetVersionEx (&osinfo );1335 OSVERSIONINFO osinfo_cache; 1336 1337 osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 1338 GetVersionEx (&osinfo_cache); 1203 1339 1204 1340 /* Determine the processor type. */ … … 1251 1387 oem = COMPILER_NAME; 1252 1388 1253 switch (osinfo .dwPlatformId) {1389 switch (osinfo_cache.dwPlatformId) { 1254 1390 case VER_PLATFORM_WIN32_NT: 1255 1391 os = "nt"; 1256 build_num = osinfo .dwBuildNumber;1392 build_num = osinfo_cache.dwBuildNumber; 1257 1393 break; 1258 1394 case VER_PLATFORM_WIN32_WINDOWS: 1259 if (osinfo .dwMinorVersion == 0) {1395 if (osinfo_cache.dwMinorVersion == 0) { 1260 1396 os = "windows95"; 1261 1397 } else { 1262 1398 os = "windows98"; 1263 1399 } 1264 build_num = LOWORD (osinfo .dwBuildNumber);1400 build_num = LOWORD (osinfo_cache.dwBuildNumber); 1265 1401 break; 1266 1402 case VER_PLATFORM_WIN32s: 1267 1403 /* Not supported, should not happen. */ 1268 1404 os = "windows32s"; 1269 build_num = LOWORD (osinfo .dwBuildNumber);1405 build_num = LOWORD (osinfo_cache.dwBuildNumber); 1270 1406 break; 1271 1407 default: … … 1275 1411 } 1276 1412 1277 if (osinfo .dwPlatformId == VER_PLATFORM_WIN32_NT) {1413 if (osinfo_cache.dwPlatformId == VER_PLATFORM_WIN32_NT) { 1278 1414 sprintf (configuration_buffer, "%s-%s-%s%d.%d.%d", arch, oem, os, 1279 1415 get_w32_major_version (), get_w32_minor_version (), build_num); … … 2533 2669 { 2534 2670 /* Don't bother to make this information more accurate. */ 2535 buf->st_mode = _S_IFREG; 2671 buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 2672 _S_IFDIR : _S_IFREG; 2536 2673 buf->st_nlink = 1; 2537 2674 fake_inode = 0; … … 2895 3032 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); 2896 3033 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); 3034 int (PASCAL *pfn_getpeername) (SOCKET s, struct sockaddr *addr, int * namelen); 3035 int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname, 3036 const char * optval, int optlen); 3037 int (PASCAL *pfn_listen) (SOCKET s, int backlog); 3038 int (PASCAL *pfn_getsockname) (SOCKET s, struct sockaddr * name, 3039 int * namelen); 3040 SOCKET (PASCAL *pfn_accept) (SOCKET s, struct sockaddr * addr, int * addrlen); 3041 int (PASCAL *pfn_recvfrom) (SOCKET s, char * buf, int len, int flags, 3042 struct sockaddr * from, int * fromlen); 3043 int (PASCAL *pfn_sendto) (SOCKET s, const char * buf, int len, int flags, 3044 const struct sockaddr * to, int tolen); 2897 3045 2898 3046 /* SetHandleInformation is only needed to make sockets non-inheritable. */ … … 2964 3112 LOAD_PROC( gethostbyname ); 2965 3113 LOAD_PROC( getservbyname ); 3114 LOAD_PROC( getpeername ); 2966 3115 LOAD_PROC( WSACleanup ); 2967 3116 LOAD_PROC( setsockopt ); 3117 LOAD_PROC( listen ); 3118 LOAD_PROC( getsockname ); 3119 LOAD_PROC( accept ); 3120 LOAD_PROC( recvfrom ); 3121 LOAD_PROC( sendto ); 2968 3122 #undef LOAD_PROC 2969 3123 … … 3136 3290 #endif 3137 3291 3292 int socket_to_fd (SOCKET s); 3293 3138 3294 int 3139 3295 sys_socket(int af, int type, int protocol) 3140 3296 { 3141 int fd; 3142 long s; 3143 child_process * cp; 3297 SOCKET s; 3144 3298 3145 3299 if (winsock_lib == NULL) … … 3152 3306 3153 3307 /* call the real socket function */ 3154 s = (long)pfn_socket (af, type, protocol);3308 s = pfn_socket (af, type, protocol); 3155 3309 3156 3310 if (s != INVALID_SOCKET) 3157 { 3158 /* Although under NT 3.5 _open_osfhandle will accept a socket 3159 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT, 3160 that does not work under NT 3.1. However, we can get the same 3161 effect by using a backdoor function to replace an existing 3162 descriptor handle with the one we want. */ 3163 3164 /* allocate a file descriptor (with appropriate flags) */ 3165 fd = _open ("NUL:", _O_RDWR); 3166 if (fd >= 0) 3167 { 3311 return socket_to_fd (s); 3312 3313 set_errno (); 3314 return -1; 3315 } 3316 3317 /* Convert a SOCKET to a file descriptor. */ 3318 int 3319 socket_to_fd (SOCKET s) 3320 { 3321 int fd; 3322 child_process * cp; 3323 3324 /* Although under NT 3.5 _open_osfhandle will accept a socket 3325 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT, 3326 that does not work under NT 3.1. However, we can get the same 3327 effect by using a backdoor function to replace an existing 3328 descriptor handle with the one we want. */ 3329 3330 /* allocate a file descriptor (with appropriate flags) */ 3331 fd = _open ("NUL:", _O_RDWR); 3332 if (fd >= 0) 3333 { 3168 3334 #ifdef SOCK_REPLACE_HANDLE 3169 /* now replace handle to NUL with our socket handle */3170 CloseHandle ((HANDLE) _get_osfhandle (fd));3171 _free_osfhnd (fd);3172 _set_osfhnd (fd, s);3173 /* setmode (fd, _O_BINARY); */3335 /* now replace handle to NUL with our socket handle */ 3336 CloseHandle ((HANDLE) _get_osfhandle (fd)); 3337 _free_osfhnd (fd); 3338 _set_osfhnd (fd, s); 3339 /* setmode (fd, _O_BINARY); */ 3174 3340 #else 3175 /* Make a non-inheritable copy of the socket handle. Note 3176 that it is possible that sockets aren't actually kernel 3177 handles, which appears to be the case on Windows 9x when 3178 the MS Proxy winsock client is installed. */ 3341 /* Make a non-inheritable copy of the socket handle. Note 3342 that it is possible that sockets aren't actually kernel 3343 handles, which appears to be the case on Windows 9x when 3344 the MS Proxy winsock client is installed. */ 3345 { 3346 /* Apparently there is a bug in NT 3.51 with some service 3347 packs, which prevents using DuplicateHandle to make a 3348 socket handle non-inheritable (causes WSACleanup to 3349 hang). The work-around is to use SetHandleInformation 3350 instead if it is available and implemented. */ 3351 if (pfn_SetHandleInformation) 3179 3352 { 3180 /* Apparently there is a bug in NT 3.51 with some service 3181 packs, which prevents using DuplicateHandle to make a 3182 socket handle non-inheritable (causes WSACleanup to 3183 hang). The work-around is to use SetHandleInformation 3184 instead if it is available and implemented. */ 3185 if (pfn_SetHandleInformation) 3353 pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0); 3354 } 3355 else 3356 { 3357 HANDLE parent = GetCurrentProcess (); 3358 HANDLE new_s = INVALID_HANDLE_VALUE; 3359 3360 if (DuplicateHandle (parent, 3361 (HANDLE) s, 3362 parent, 3363 &new_s, 3364 0, 3365 FALSE, 3366 DUPLICATE_SAME_ACCESS)) 3186 3367 { 3187 pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0); 3188 } 3189 else 3190 { 3191 HANDLE parent = GetCurrentProcess (); 3192 HANDLE new_s = INVALID_HANDLE_VALUE; 3193 3194 if (DuplicateHandle (parent, 3195 (HANDLE) s, 3196 parent, 3197 &new_s, 3198 0, 3199 FALSE, 3200 DUPLICATE_SAME_ACCESS)) 3368 /* It is possible that DuplicateHandle succeeds even 3369 though the socket wasn't really a kernel handle, 3370 because a real handle has the same value. So 3371 test whether the new handle really is a socket. */ 3372 long nonblocking = 0; 3373 if (pfn_ioctlsocket ((SOCKET) new_s, FIONBIO, &nonblocking) == 0) 3201 3374 { 3202 /* It is possible that DuplicateHandle succeeds even 3203 though the socket wasn't really a kernel handle, 3204 because a real handle has the same value. So 3205 test whether the new handle really is a socket. */ 3206 long nonblocking = 0; 3207 if (pfn_ioctlsocket ((SOCKET) new_s, FIONBIO, &nonblocking) == 0) 3208 { 3209 pfn_closesocket (s); 3210 s = (SOCKET) new_s; 3211 } 3212 else 3213 { 3214 CloseHandle (new_s); 3215 } 3375 pfn_closesocket (s); 3376 s = (SOCKET) new_s; 3377 } 3378 else 3379 { 3380 CloseHandle (new_s); 3216 3381 } 3217 3382 } 3218 3383 } 3219 fd_info[fd].hnd = (HANDLE) s; 3384 } 3385 fd_info[fd].hnd = (HANDLE) s; 3220 3386 #endif 3221 3387 3222 /* set our own internal flags */ 3223 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE; 3224 3225 cp = new_child (); 3226 if (cp) 3388 /* set our own internal flags */ 3389 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE; 3390 3391 cp = new_child (); 3392 if (cp) 3393 { 3394 cp->fd = fd; 3395 cp->status = STATUS_READ_ACKNOWLEDGED; 3396 3397 /* attach child_process to fd_info */ 3398 if (fd_info[ fd ].cp != NULL) 3227 3399 { 3228 cp->fd = fd; 3229 cp->status = STATUS_READ_ACKNOWLEDGED; 3230 3231 /* attach child_process to fd_info */ 3232 if (fd_info[ fd ].cp != NULL) 3233 { 3234 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd)); 3235 abort (); 3236 } 3237 3238 fd_info[ fd ].cp = cp; 3239 3240 /* success! */ 3241 winsock_inuse++; /* count open sockets */ 3242 return fd; 3400 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd)); 3401 abort (); 3243 3402 } 3244 3403 3245 /* clean up */ 3246 _close (fd); 3247 } 3248 pfn_closesocket (s); 3249 h_errno = EMFILE; 3250 } 3251 set_errno (); 3252 3404 fd_info[ fd ].cp = cp; 3405 3406 /* success! */ 3407 winsock_inuse++; /* count open sockets */ 3408 return fd; 3409 } 3410 3411 /* clean up */ 3412 _close (fd); 3413 } 3414 pfn_closesocket (s); 3415 h_errno = EMFILE; 3253 3416 return -1; 3254 3417 } … … 3369 3532 3370 3533 int 3534 sys_getpeername (int s, struct sockaddr *addr, int * namelen) 3535 { 3536 if (winsock_lib == NULL) 3537 { 3538 h_errno = ENETDOWN; 3539 return SOCKET_ERROR; 3540 } 3541 3542 check_errno (); 3543 if (fd_info[s].flags & FILE_SOCKET) 3544 { 3545 int rc = pfn_getpeername (SOCK_HANDLE (s), addr, namelen); 3546 if (rc == SOCKET_ERROR) 3547 set_errno (); 3548 return rc; 3549 } 3550 h_errno = ENOTSOCK; 3551 return SOCKET_ERROR; 3552 } 3553 3554 3555 int 3371 3556 sys_shutdown (int s, int how) 3372 3557 { … … 3384 3569 set_errno (); 3385 3570 return rc; 3571 } 3572 h_errno = ENOTSOCK; 3573 return SOCKET_ERROR; 3574 } 3575 3576 int 3577 sys_setsockopt (int s, int level, int optname, const char * optval, int optlen) 3578 { 3579 if (winsock_lib == NULL) 3580 { 3581 h_errno = ENETDOWN; 3582 return SOCKET_ERROR; 3583 } 3584 3585 check_errno (); 3586 if (fd_info[s].flags & FILE_SOCKET) 3587 { 3588 int rc = pfn_setsockopt (SOCK_HANDLE (s), level, optname, 3589 optval, optlen); 3590 if (rc == SOCKET_ERROR) 3591 set_errno (); 3592 return rc; 3593 } 3594 h_errno = ENOTSOCK; 3595 return SOCKET_ERROR; 3596 } 3597 3598 int 3599 sys_listen (int s, int backlog) 3600 { 3601 if (winsock_lib == NULL) 3602 { 3603 h_errno = ENETDOWN; 3604 return SOCKET_ERROR; 3605 } 3606 3607 check_errno (); 3608 if (fd_info[s].flags & FILE_SOCKET) 3609 { 3610 int rc = pfn_listen (SOCK_HANDLE (s), backlog); 3611 if (rc == SOCKET_ERROR) 3612 set_errno (); 3613 return rc; 3614 } 3615 h_errno = ENOTSOCK; 3616 return SOCKET_ERROR; 3617 } 3618 3619 int 3620 sys_getsockname (int s, struct sockaddr * name, int * namelen) 3621 { 3622 if (winsock_lib == NULL) 3623 { 3624 h_errno = ENETDOWN; 3625 return SOCKET_ERROR; 3626 } 3627 3628 check_errno (); 3629 if (fd_info[s].flags & FILE_SOCKET) 3630 { 3631 int rc = pfn_getsockname (SOCK_HANDLE (s), name, namelen); 3632 if (rc == SOCKET_ERROR) 3633 set_errno (); 3634 return rc; 3635 } 3636 h_errno = ENOTSOCK; 3637 return SOCKET_ERROR; 3638 } 3639 3640 int 3641 sys_accept (int s, struct sockaddr * addr, int * addrlen) 3642 { 3643 if (winsock_lib == NULL) 3644 { 3645 h_errno = ENETDOWN; 3646 return -1; 3647 } 3648 3649 check_errno (); 3650 if (fd_info[s].flags & FILE_SOCKET) 3651 { 3652 SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen); 3653 if (t != INVALID_SOCKET) 3654 return socket_to_fd (t); 3655 3656 set_errno (); 3657 return -1; 3658 } 3659 h_errno = ENOTSOCK; 3660 return -1; 3661 } 3662 3663 int 3664 sys_recvfrom (int s, char * buf, int len, int flags, 3665 struct sockaddr * from, int * fromlen) 3666 { 3667 if (winsock_lib == NULL) 3668 { 3669 h_errno = ENETDOWN; 3670 return SOCKET_ERROR; 3671 } 3672 3673 check_errno (); 3674 if (fd_info[s].flags & FILE_SOCKET) 3675 { 3676 int rc = pfn_recvfrom (SOCK_HANDLE (s), buf, len, flags, from, fromlen); 3677 if (rc == SOCKET_ERROR) 3678 set_errno (); 3679 return rc; 3680 } 3681 h_errno = ENOTSOCK; 3682 return SOCKET_ERROR; 3683 } 3684 3685 int 3686 sys_sendto (int s, const char * buf, int len, int flags, 3687 const struct sockaddr * to, int tolen) 3688 { 3689 if (winsock_lib == NULL) 3690 { 3691 h_errno = ENETDOWN; 3692 return SOCKET_ERROR; 3693 } 3694 3695 check_errno (); 3696 if (fd_info[s].flags & FILE_SOCKET) 3697 { 3698 int rc = pfn_sendto (SOCK_HANDLE (s), buf, len, flags, to, tolen); 3699 if (rc == SOCKET_ERROR) 3700 set_errno (); 3701 return rc; 3702 } 3703 h_errno = ENOTSOCK; 3704 return SOCKET_ERROR; 3705 } 3706 3707 /* Windows does not have an fcntl function. Provide an implementation 3708 solely for making sockets non-blocking. */ 3709 int 3710 fcntl (int s, int cmd, int options) 3711 { 3712 if (winsock_lib == NULL) 3713 { 3714 h_errno = ENETDOWN; 3715 return -1; 3716 } 3717 3718 check_errno (); 3719 if (fd_info[s].flags & FILE_SOCKET) 3720 { 3721 if (cmd == F_SETFL && options == O_NDELAY) 3722 { 3723 unsigned long nblock = 1; 3724 int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock); 3725 if (rc == SOCKET_ERROR) 3726 set_errno(); 3727 /* Keep track of the fact that we set this to non-blocking. */ 3728 fd_info[s].flags |= FILE_NDELAY; 3729 return rc; 3730 } 3731 else 3732 { 3733 h_errno = EINVAL; 3734 return SOCKET_ERROR; 3735 } 3386 3736 } 3387 3737 h_errno = ENOTSOCK; … … 3508 3858 if (rc == 0) 3509 3859 { 3860 /* Protect against overflow, since Windows can open more handles than 3861 our fd_info array has room for. */ 3510 3862 if (phandles[0] >= MAXDESC || phandles[1] >= MAXDESC) 3511 3863 {
