Changeset 3677

Show
Ignore:
Timestamp:
04/10/05 17:53:48 (4 years ago)
Author:
miyoshi
Message:

* puresize.h: Sync up with Emacs CVS HEAD.

* w32.c: Ditto.

* w32.h: Ditto.

* w32inevt.c (w32_console_read_socket): Ditto.

* w32proc.c (syms_of_ntproc): Ditto.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/2.2/src/ChangeLog.Meadow

    r3676 r3677  
     12005-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 
    1132005-04-10  MIYOSHI Masanori  <miyoshi@meadowy.org> 
    214 
  • branches/2.2/src/puresize.h

    r3601 r3677  
    4848/* Increase BASE_PURESIZE by a ratio depending on the machine's word size.  */ 
    4949#ifndef PURESIZE_RATIO 
    50 #if VALBITS + GCTYPEBITS + 1 > 32 
    51 #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 `()'. */ 
    5252#else 
    5353#define PURESIZE_RATIO 1 
     
    6363#ifdef PDUMP 
    6464#define CHECK_IMPURE(obj) 
    65 #else /* PDUMP */ 
     65#else /* not PDUMP */ 
    6666#define CHECK_IMPURE(obj) \ 
    6767  { if (PURE_P (obj))     \ 
    6868      pure_write_error (); } 
    69 #endif /* PDUMP */ 
     69#endif /* not PDUMP */ 
    7070 
    7171extern void pure_write_error P_ ((void)); 
     
    7575#ifdef PDUMP 
    7676#define PURE_P(obj) 0 
    77 #else /* PDUMP */ 
    78 #ifdef VIRT_ADDR_VARIES 
     77#else /* not PDUMP */ 
     78#if defined(VIRT_ADDR_VARIES) || defined(CYGWIN) 
    7979/* For machines like APOLLO where text and data can go anywhere 
    8080   in virtual memory.  */ 
     
    104104#endif /* PNTR_COMPARISON_TYPE */ 
    105105#endif /* VIRT_ADDRESS_VARIES */ 
    106 #endif /* PDUMP */ 
     106#endif /* not PDUMP */ 
    107107 
    108108 
  • branches/2.2/src/w32.c

    r3664 r3677  
    6969#include <grp.h> 
    7070 
    71 #include <windows.h> 
    72  
    73 #ifdef MEADOW 
    74 #include <tchar.h> 
    75 #include "mw32reg.h" 
    76 #include "mw32sync.h" 
    77 #endif 
    78 #include "charset.h" 
    79 #include "coding.h" 
    80 extern Lisp_Object Vfile_name_coding_system; 
    81  
    82 #include <shellapi.h> 
    83  
    8471#ifdef __GNUC__ 
    8572#define _ANONYMOUS_UNION 
    8673#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 
     83extern Lisp_Object Vfile_name_coding_system; 
    8784#endif 
    8885 
     
    120117#endif 
    121118 
     119void globals_of_w32 (); 
     120 
    122121extern Lisp_Object Vw32_downcase_file_names; 
    123122extern Lisp_Object Vw32_generate_fake_inodes; 
     
    126125extern Lisp_Object Vw32_get_true_file_link_count; 
    127126#endif 
     127extern int w32_num_mouse_buttons; 
     128 
     129  
     130/* 
     131        Initialization states 
     132 */ 
     133static BOOL g_b_init_is_windows_9x; 
     134static BOOL g_b_init_open_process_token; 
     135static BOOL g_b_init_get_token_information; 
     136static BOOL g_b_init_lookup_account_sid; 
     137static 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 ** */ 
     145typedef BOOL (WINAPI * OpenProcessToken_Proc) ( 
     146    HANDLE ProcessHandle, 
     147    DWORD DesiredAccess, 
     148    PHANDLE TokenHandle); 
     149typedef BOOL (WINAPI * GetTokenInformation_Proc) ( 
     150    HANDLE TokenHandle, 
     151    TOKEN_INFORMATION_CLASS TokenInformationClass, 
     152    LPVOID TokenInformation, 
     153    DWORD TokenInformationLength, 
     154    PDWORD ReturnLength); 
     155#ifdef _UNICODE 
     156const char * const LookupAccountSid_Name = "LookupAccountSidW"; 
     157#else 
     158const char * const LookupAccountSid_Name = "LookupAccountSidA"; 
     159#endif 
     160typedef 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); 
     168typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) ( 
     169    PSID pSid); 
     170 
     171  /* ** A utility function ** */ 
     172static 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 
     191BOOL 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 
     221BOOL 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 
     255BOOL 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 
     293PSID_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} 
    128316 
    129317/* Array of W32 filename special characters */ 
     
    133321w32_filename_special_characters[] = {'*', '?', '<', '>', '\"', '\\', '/', 0}; 
    134322 
    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*/ 
    138328 
    139329  
     
    172362     conflicts when trying to rename or delete directories.  */ 
    173363  strcpy (dir, startup_dir); 
    174   dostounix_filename(dir); 
     364  dostounix_filename (dir); 
    175365  return dir; 
    176366#endif 
     
    302492  SID_NAME_USE    user_type; 
    303493 
    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, 
    306496                              (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, 
    308498                           domain, &dlength, &user_type)) 
    309499    { 
     
    319509          SID_IDENTIFIER_AUTHORITY * pSIA; 
    320510 
    321           pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); 
     511          pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); 
    322512          /* I believe the relative portion is the last 4 bytes (of 6) 
    323513             with msb first. */ 
     
    330520 
    331521          /* Get group id */ 
    332           if (GetTokenInformation (token, TokenPrimaryGroup, 
     522          if (get_token_information (token, TokenPrimaryGroup, 
    333523                                   (PVOID) user_sid, sizeof (user_sid), &trash)) 
    334524            { 
    335525              SID_IDENTIFIER_AUTHORITY * pSIA; 
    336526 
    337               pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); 
     527              pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); 
    338528              the_passwd.pw_gid = ((pSIA->Value[2] << 24) + 
    339529                                   (pSIA->Value[3] << 16) + 
     
    415605   the specified separator.  Also conditionally convert upper 
    416606   case path name components to lower case.  */ 
     607 
    417608static void 
    418609normalize_filename (LPTSTR fp, TCHAR path_sep) 
     
    428619     functions that are case-sensitive.  Even case-preserving filesystems 
    429620     do not distinguish case in drive letters.  */ 
    430   if ((*fp >= 'A' && *fp <= 'Z') 
    431       && (*(CharNext (fp)) == ':')) 
     621  if (*(CharNext (fp)) == ':' && *fp >= 'A' && *fp <= 'Z') 
    432622    { 
    433623      next_char = tolower (*fp); 
     
    564754} 
    565755 
    566  
    567756/* Destructively turn backslashes into slashes.  */ 
    568757void 
     
    610799} 
    611800 
    612 /* Parse the root part of file name, if present.  Return byte length and 
     801/* Parse the root part of file name, if present.  Return length and 
    613802    optionally store pointer to char after root.  */ 
    614803static int 
     
    656845    *pPath = name; 
    657846 
    658   return (name - start) / sizeof(TCHAR); 
     847  return (name - start) / sizeof (TCHAR); 
    659848} 
    660849 
     
    675864    { 
    676865      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)); 
    678867      else 
    679868        len = 0; 
     
    698887 
    699888  /* Use local copy for destructive modification.  */ 
    700   memcpy (full, name, sizeof(TCHAR) * (len + 1)); 
     889  memcpy (full, name, sizeof (TCHAR) * (len + 1)); 
    701890  unixtodos_filename (full); 
    702891 
    703892  /* Copy root part verbatim.  */ 
    704893  len = parse_root (full, &p); 
    705   memcpy (o, full, sizeof(TCHAR) * len); 
     894  memcpy (o, full, sizeof (TCHAR) * len); 
    706895  o += len; 
    707896  *o = '\0'; 
     
    8701059  return (NULL); 
    8711060} 
    872 #else /* not MEADOW */ 
    873 #endif 
     1061#endif /* not MEADOW */ 
    8741062 
    8751063char *get_emacs_configuration (void); 
     
    8771065 
    8781066void 
    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) 
     1067init_environment (char ** argv) 
    9541068{ 
    9551069  static const char * const tempdirs[] = { 
     
    10091123      {"EMACSDATA", "%emacs_dir%/etc"}, 
    10101124      {"EMACSPATH", "%emacs_dir%/bin"}, 
    1011       {"EMACSLOCKDIR", "%emacs_dir%/lock"}, 
    10121125      /* We no longer set INFOPATH because Info-default-directory-list 
    10131126         is then ignored.  */ 
     
    10631176          _putenv (strdup (buf)); 
    10641177        } 
     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        } 
    10651204    } 
    10661205 
     
    11101249  Vsystem_configuration = build_string (EMACS_CONFIGURATION); 
    11111250 
    1112   /* Initialize time zone infomation */ 
    1113   init_time_zone_info (); 
    1114  
    11151251  /* Another special case: on NT, the PATH variable is actually named 
    11161252     "Path" although cmd.exe (perhaps NT itself) arranges for 
     
    11651301     to decide whether right mouse events should be mouse-2 or 
    11661302     mouse-3. */ 
    1167   XSETINT (Vw32_num_mouse_buttons, GetSystemMetrics (SM_CMOUSEBUTTONS)); 
     1303  w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS); 
    11681304#endif 
    11691305 
     
    11971333  int build_num; 
    11981334  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); 
    12031339 
    12041340  /* Determine the processor type.  */ 
     
    12511387  oem = COMPILER_NAME; 
    12521388 
    1253   switch (osinfo.dwPlatformId) { 
     1389  switch (osinfo_cache.dwPlatformId) { 
    12541390  case VER_PLATFORM_WIN32_NT: 
    12551391    os = "nt"; 
    1256     build_num = osinfo.dwBuildNumber; 
     1392    build_num = osinfo_cache.dwBuildNumber; 
    12571393    break; 
    12581394  case VER_PLATFORM_WIN32_WINDOWS: 
    1259     if (osinfo.dwMinorVersion == 0) { 
     1395    if (osinfo_cache.dwMinorVersion == 0) { 
    12601396      os = "windows95"; 
    12611397    } else { 
    12621398      os = "windows98"; 
    12631399    } 
    1264     build_num = LOWORD (osinfo.dwBuildNumber); 
     1400    build_num = LOWORD (osinfo_cache.dwBuildNumber); 
    12651401    break; 
    12661402  case VER_PLATFORM_WIN32s: 
    12671403    /* Not supported, should not happen. */ 
    12681404    os = "windows32s"; 
    1269     build_num = LOWORD (osinfo.dwBuildNumber); 
     1405    build_num = LOWORD (osinfo_cache.dwBuildNumber); 
    12701406    break; 
    12711407  default: 
     
    12751411  } 
    12761412 
    1277   if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { 
     1413  if (osinfo_cache.dwPlatformId == VER_PLATFORM_WIN32_NT) { 
    12781414    sprintf (configuration_buffer, "%s-%s-%s%d.%d.%d", arch, oem, os, 
    12791415             get_w32_major_version (), get_w32_minor_version (), build_num); 
     
    25332669    { 
    25342670      /* 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; 
    25362673      buf->st_nlink = 1; 
    25372674      fake_inode = 0; 
     
    28953032struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); 
    28963033struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); 
     3034int (PASCAL *pfn_getpeername) (SOCKET s, struct sockaddr *addr, int * namelen); 
     3035int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname, 
     3036                              const char * optval, int optlen); 
     3037int (PASCAL *pfn_listen) (SOCKET s, int backlog); 
     3038int (PASCAL *pfn_getsockname) (SOCKET s, struct sockaddr * name, 
     3039                               int * namelen); 
     3040SOCKET (PASCAL *pfn_accept) (SOCKET s, struct sockaddr * addr, int * addrlen); 
     3041int (PASCAL *pfn_recvfrom) (SOCKET s, char * buf, int len, int flags, 
     3042                       struct sockaddr * from, int * fromlen); 
     3043int (PASCAL *pfn_sendto) (SOCKET s, const char * buf, int len, int flags, 
     3044                          const struct sockaddr * to, int tolen); 
    28973045 
    28983046/* SetHandleInformation is only needed to make sockets non-inheritable. */ 
     
    29643112      LOAD_PROC( gethostbyname ); 
    29653113      LOAD_PROC( getservbyname ); 
     3114      LOAD_PROC( getpeername ); 
    29663115      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 ); 
    29683122#undef LOAD_PROC 
    29693123 
     
    31363290#endif 
    31373291 
     3292int socket_to_fd (SOCKET s); 
     3293 
    31383294int 
    31393295sys_socket(int af, int type, int protocol) 
    31403296{ 
    3141   int fd; 
    3142   long s; 
    3143   child_process * cp; 
     3297  SOCKET s; 
    31443298 
    31453299  if (winsock_lib == NULL) 
     
    31523306 
    31533307  /* call the real socket function */ 
    3154   s = (long) pfn_socket (af, type, protocol); 
     3308  s = pfn_socket (af, type, protocol); 
    31553309 
    31563310  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.  */ 
     3318int 
     3319socket_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    { 
    31683334#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); */ 
    31743340#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) 
    31793352          { 
    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)) 
    31863367              { 
    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) 
    32013374                  { 
    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); 
    32163381                  } 
    32173382              } 
    32183383          } 
    3219           fd_info[fd].hnd = (HANDLE) s; 
     3384      } 
     3385      fd_info[fd].hnd = (HANDLE) s; 
    32203386#endif 
    32213387 
    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) 
    32273399            { 
    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 (); 
    32433402            } 
    32443403 
    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; 
    32533416  return -1; 
    32543417} 
     
    33693532 
    33703533int 
     3534sys_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 
     3555int 
    33713556sys_shutdown (int s, int how) 
    33723557{ 
     
    33843569        set_errno (); 
    33853570      return rc; 
     3571    } 
     3572  h_errno = ENOTSOCK; 
     3573  return SOCKET_ERROR; 
     3574} 
     3575 
     3576int 
     3577sys_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 
     3598int 
     3599sys_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 
     3619int 
     3620sys_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 
     3640int 
     3641sys_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 
     3663int 
     3664sys_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 
     3685int 
     3686sys_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.  */ 
     3709int 
     3710fcntl (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        } 
    33863736    } 
    33873737  h_errno = ENOTSOCK; 
     
    35083858  if (rc == 0) 
    35093859    { 
     3860      /* Protect against overflow, since Windows can open more handles than 
     3861         our fd_info array has room for.  */ 
    35103862      if (phandles[0] >= MAXDESC || phandles[1] >= MAXDESC) 
    35113863        {