diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 45 |
1 files changed, 34 insertions, 11 deletions
| @@ -1338,6 +1338,12 @@ unsigned long (PASCAL *pfn_inet_addr) (const char * cp); | |||
| 1338 | int (PASCAL *pfn_gethostname) (char * name, int namelen); | 1338 | int (PASCAL *pfn_gethostname) (char * name, int namelen); |
| 1339 | struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); | 1339 | struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); |
| 1340 | struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); | 1340 | struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); |
| 1341 | |||
| 1342 | /* SetHandleInformation is only needed to make sockets non-inheritable. */ | ||
| 1343 | BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags); | ||
| 1344 | #ifndef HANDLE_FLAG_INHERIT | ||
| 1345 | #define HANDLE_FLAG_INHERIT 1 | ||
| 1346 | #endif | ||
| 1341 | 1347 | ||
| 1342 | static int have_winsock; | 1348 | static int have_winsock; |
| 1343 | static HANDLE winsock_lib; | 1349 | static HANDLE winsock_lib; |
| @@ -1357,6 +1363,13 @@ init_winsock () | |||
| 1357 | { | 1363 | { |
| 1358 | WSADATA winsockData; | 1364 | WSADATA winsockData; |
| 1359 | 1365 | ||
| 1366 | have_winsock = FALSE; | ||
| 1367 | |||
| 1368 | pfn_SetHandleInformation = NULL; | ||
| 1369 | pfn_SetHandleInformation | ||
| 1370 | = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"), | ||
| 1371 | "SetHandleInformation"); | ||
| 1372 | |||
| 1360 | winsock_lib = LoadLibrary ("wsock32.dll"); | 1373 | winsock_lib = LoadLibrary ("wsock32.dll"); |
| 1361 | 1374 | ||
| 1362 | if (winsock_lib != NULL) | 1375 | if (winsock_lib != NULL) |
| @@ -1396,7 +1409,6 @@ init_winsock () | |||
| 1396 | fail: | 1409 | fail: |
| 1397 | FreeLibrary (winsock_lib); | 1410 | FreeLibrary (winsock_lib); |
| 1398 | } | 1411 | } |
| 1399 | have_winsock = FALSE; | ||
| 1400 | } | 1412 | } |
| 1401 | 1413 | ||
| 1402 | 1414 | ||
| @@ -1488,16 +1500,27 @@ sys_socket(int af, int type, int protocol) | |||
| 1488 | 1500 | ||
| 1489 | parent = GetCurrentProcess (); | 1501 | parent = GetCurrentProcess (); |
| 1490 | 1502 | ||
| 1491 | DuplicateHandle (parent, | 1503 | /* Apparently there is a bug in NT 3.51 with some service |
| 1492 | (HANDLE) s, | 1504 | packs, which prevents using DuplicateHandle to make a |
| 1493 | parent, | 1505 | socket handle non-inheritable (causes WSACleanup to |
| 1494 | &new_s, | 1506 | hang). The work-around is to use SetHandleInformation |
| 1495 | 0, | 1507 | instead if it is available and implemented. */ |
| 1496 | FALSE, | 1508 | if (!pfn_SetHandleInformation |
| 1497 | DUPLICATE_SAME_ACCESS); | 1509 | || !pfn_SetHandleInformation ((HANDLE) s, |
| 1498 | pfn_closesocket (s); | 1510 | HANDLE_FLAG_INHERIT, |
| 1499 | fd_info[fd].hnd = new_s; | 1511 | HANDLE_FLAG_INHERIT)) |
| 1500 | s = (SOCKET) new_s; | 1512 | { |
| 1513 | DuplicateHandle (parent, | ||
| 1514 | (HANDLE) s, | ||
| 1515 | parent, | ||
| 1516 | &new_s, | ||
| 1517 | 0, | ||
| 1518 | FALSE, | ||
| 1519 | DUPLICATE_SAME_ACCESS); | ||
| 1520 | pfn_closesocket (s); | ||
| 1521 | s = (SOCKET) new_s; | ||
| 1522 | } | ||
| 1523 | fd_info[fd].hnd = (HANDLE) s; | ||
| 1501 | } | 1524 | } |
| 1502 | #endif | 1525 | #endif |
| 1503 | 1526 | ||