diff options
| author | Richard M. Stallman | 1996-06-08 00:22:50 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1996-06-08 00:22:50 +0000 |
| commit | f249a012806470657c8c4c11e8390ea299b60597 (patch) | |
| tree | 140a0edd59f2fd99a6caa9521e86ec2bad86f54a /src | |
| parent | a11e68d017e1dd8a8759c0f63fa601fd92eb5d66 (diff) | |
| download | emacs-f249a012806470657c8c4c11e8390ea299b60597.tar.gz emacs-f249a012806470657c8c4c11e8390ea299b60597.zip | |
(init_environment): Read PRELOAD_WINSOCK from registry if
not set in environment.
(winsock_inuse) [HAVE_SOCKETS]: New variable.
(have_winsock) [HAVE_SOCKETS]: Obsolete variable removed.
(term_winsock) [HAVE_SOCKETS]: Only unload winsock library if there
are no active sockets still open, and if the cleanup function
succeeds. Return TRUE if winsock is unloaded.
(init_winsock) [HAVE_SOCKETS]: Load winsock if not already loaded,
and return TRUE if winsock support is available. Unload winsock
immediately if new parameter load_now is false. Check that
WSAStartup supports the winsock version we requested.
(set_errno, check_errno, sys_socket, sys_bind, sys_connect, sys_htons,
sys_ntohs, sys_inet_addr, sys_gethostname, sys_gethostbyname,
sys_getservbyname, sys_close, sys_read, sys_write) [HAVE_SOCKETS]:
Check winsock_lib instead of have_winsock to determine if winsock
support is available.
(sys_socket, sys_close) [HAVE_SOCKETS]: Count sockets in use.
(init_ntproc) [HAVE_SOCKETS]: Only load winsock library on startup
if PRELOAD_WINSOCK is set in environment (or registry).
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 102 |
1 files changed, 74 insertions, 28 deletions
| @@ -584,6 +584,7 @@ init_environment () | |||
| 584 | static char * env_vars[] = | 584 | static char * env_vars[] = |
| 585 | { | 585 | { |
| 586 | "HOME", | 586 | "HOME", |
| 587 | "PRELOAD_WINSOCK", | ||
| 587 | "emacs_dir", | 588 | "emacs_dir", |
| 588 | "EMACSLOADPATH", | 589 | "EMACSLOADPATH", |
| 589 | "SHELL", | 590 | "SHELL", |
| @@ -1389,25 +1390,35 @@ BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags) | |||
| 1389 | #define HANDLE_FLAG_INHERIT 1 | 1390 | #define HANDLE_FLAG_INHERIT 1 |
| 1390 | #endif | 1391 | #endif |
| 1391 | 1392 | ||
| 1392 | static int have_winsock; | 1393 | HANDLE winsock_lib; |
| 1393 | static HANDLE winsock_lib; | 1394 | static int winsock_inuse; |
| 1394 | 1395 | ||
| 1395 | static void | 1396 | BOOL |
| 1396 | term_winsock (void) | 1397 | term_winsock (void) |
| 1397 | { | 1398 | { |
| 1398 | if (have_winsock) | 1399 | if (winsock_lib != NULL && winsock_inuse == 0) |
| 1399 | { | 1400 | { |
| 1400 | pfn_WSACleanup (); | 1401 | /* Not sure what would cause WSAENETDOWN, or even if it can happen |
| 1401 | FreeLibrary (winsock_lib); | 1402 | after WSAStartup returns successfully, but it seems reasonable |
| 1403 | to allow unloading winsock anyway in that case. */ | ||
| 1404 | if (pfn_WSACleanup () == 0 || | ||
| 1405 | pfn_WSAGetLastError () == WSAENETDOWN) | ||
| 1406 | { | ||
| 1407 | if (FreeLibrary (winsock_lib)) | ||
| 1408 | winsock_lib = NULL; | ||
| 1409 | return TRUE; | ||
| 1410 | } | ||
| 1402 | } | 1411 | } |
| 1412 | return FALSE; | ||
| 1403 | } | 1413 | } |
| 1404 | 1414 | ||
| 1405 | static void | 1415 | BOOL |
| 1406 | init_winsock () | 1416 | init_winsock (int load_now) |
| 1407 | { | 1417 | { |
| 1408 | WSADATA winsockData; | 1418 | WSADATA winsockData; |
| 1409 | 1419 | ||
| 1410 | have_winsock = FALSE; | 1420 | if (winsock_lib != NULL) |
| 1421 | return TRUE; | ||
| 1411 | 1422 | ||
| 1412 | pfn_SetHandleInformation = NULL; | 1423 | pfn_SetHandleInformation = NULL; |
| 1413 | pfn_SetHandleInformation | 1424 | pfn_SetHandleInformation |
| @@ -1443,16 +1454,36 @@ init_winsock () | |||
| 1443 | LOAD_PROC( getservbyname ); | 1454 | LOAD_PROC( getservbyname ); |
| 1444 | LOAD_PROC( WSACleanup ); | 1455 | LOAD_PROC( WSACleanup ); |
| 1445 | 1456 | ||
| 1457 | #undef LOAD_PROC | ||
| 1458 | |||
| 1446 | /* specify version 1.1 of winsock */ | 1459 | /* specify version 1.1 of winsock */ |
| 1447 | if (pfn_WSAStartup (0x101, &winsockData) == 0) | 1460 | if (pfn_WSAStartup (0x101, &winsockData) == 0) |
| 1448 | { | 1461 | { |
| 1449 | have_winsock = TRUE; | 1462 | if (winsockData.wVersion != 0x101) |
| 1450 | return; | 1463 | goto fail; |
| 1464 | |||
| 1465 | if (!load_now) | ||
| 1466 | { | ||
| 1467 | /* Report that winsock exists and is usable, but leave | ||
| 1468 | socket functions disabled. I am assuming that calling | ||
| 1469 | WSAStartup does not require any network interaction, | ||
| 1470 | and in particular does not cause or require a dial-up | ||
| 1471 | connection to be established. */ | ||
| 1472 | |||
| 1473 | pfn_WSACleanup (); | ||
| 1474 | FreeLibrary (winsock_lib); | ||
| 1475 | winsock_lib = NULL; | ||
| 1476 | } | ||
| 1477 | winsock_inuse = 0; | ||
| 1478 | return TRUE; | ||
| 1451 | } | 1479 | } |
| 1452 | 1480 | ||
| 1453 | fail: | 1481 | fail: |
| 1454 | FreeLibrary (winsock_lib); | 1482 | FreeLibrary (winsock_lib); |
| 1483 | winsock_lib = NULL; | ||
| 1455 | } | 1484 | } |
| 1485 | |||
| 1486 | return FALSE; | ||
| 1456 | } | 1487 | } |
| 1457 | 1488 | ||
| 1458 | 1489 | ||
| @@ -1463,7 +1494,7 @@ int h_errno = 0; | |||
| 1463 | are already in <sys/socket.h> */ | 1494 | are already in <sys/socket.h> */ |
| 1464 | static void set_errno () | 1495 | static void set_errno () |
| 1465 | { | 1496 | { |
| 1466 | if (!have_winsock) | 1497 | if (winsock_lib == NULL) |
| 1467 | h_errno = EINVAL; | 1498 | h_errno = EINVAL; |
| 1468 | else | 1499 | else |
| 1469 | h_errno = pfn_WSAGetLastError (); | 1500 | h_errno = pfn_WSAGetLastError (); |
| @@ -1484,7 +1515,7 @@ static void set_errno () | |||
| 1484 | 1515 | ||
| 1485 | static void check_errno () | 1516 | static void check_errno () |
| 1486 | { | 1517 | { |
| 1487 | if (h_errno == 0 && have_winsock) | 1518 | if (h_errno == 0 && winsock_lib != NULL) |
| 1488 | pfn_WSASetLastError (0); | 1519 | pfn_WSASetLastError (0); |
| 1489 | } | 1520 | } |
| 1490 | 1521 | ||
| @@ -1507,7 +1538,7 @@ sys_socket(int af, int type, int protocol) | |||
| 1507 | long s; | 1538 | long s; |
| 1508 | child_process * cp; | 1539 | child_process * cp; |
| 1509 | 1540 | ||
| 1510 | if (!have_winsock) | 1541 | if (winsock_lib == NULL) |
| 1511 | { | 1542 | { |
| 1512 | h_errno = ENETDOWN; | 1543 | h_errno = ENETDOWN; |
| 1513 | return INVALID_SOCKET; | 1544 | return INVALID_SOCKET; |
| @@ -1587,6 +1618,7 @@ sys_socket(int af, int type, int protocol) | |||
| 1587 | fd_info[ fd ].cp = cp; | 1618 | fd_info[ fd ].cp = cp; |
| 1588 | 1619 | ||
| 1589 | /* success! */ | 1620 | /* success! */ |
| 1621 | winsock_inuse++; /* count open sockets */ | ||
| 1590 | return fd; | 1622 | return fd; |
| 1591 | } | 1623 | } |
| 1592 | 1624 | ||
| @@ -1605,7 +1637,7 @@ sys_socket(int af, int type, int protocol) | |||
| 1605 | int | 1637 | int |
| 1606 | sys_bind (int s, const struct sockaddr * addr, int namelen) | 1638 | sys_bind (int s, const struct sockaddr * addr, int namelen) |
| 1607 | { | 1639 | { |
| 1608 | if (!have_winsock) | 1640 | if (winsock_lib == NULL) |
| 1609 | { | 1641 | { |
| 1610 | h_errno = ENOTSOCK; | 1642 | h_errno = ENOTSOCK; |
| 1611 | return SOCKET_ERROR; | 1643 | return SOCKET_ERROR; |
| @@ -1627,7 +1659,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) | |||
| 1627 | int | 1659 | int |
| 1628 | sys_connect (int s, const struct sockaddr * name, int namelen) | 1660 | sys_connect (int s, const struct sockaddr * name, int namelen) |
| 1629 | { | 1661 | { |
| 1630 | if (!have_winsock) | 1662 | if (winsock_lib == NULL) |
| 1631 | { | 1663 | { |
| 1632 | h_errno = ENOTSOCK; | 1664 | h_errno = ENOTSOCK; |
| 1633 | return SOCKET_ERROR; | 1665 | return SOCKET_ERROR; |
| @@ -1648,28 +1680,28 @@ sys_connect (int s, const struct sockaddr * name, int namelen) | |||
| 1648 | u_short | 1680 | u_short |
| 1649 | sys_htons (u_short hostshort) | 1681 | sys_htons (u_short hostshort) |
| 1650 | { | 1682 | { |
| 1651 | return (have_winsock) ? | 1683 | return (winsock_lib != NULL) ? |
| 1652 | pfn_htons (hostshort) : hostshort; | 1684 | pfn_htons (hostshort) : hostshort; |
| 1653 | } | 1685 | } |
| 1654 | 1686 | ||
| 1655 | u_short | 1687 | u_short |
| 1656 | sys_ntohs (u_short netshort) | 1688 | sys_ntohs (u_short netshort) |
| 1657 | { | 1689 | { |
| 1658 | return (have_winsock) ? | 1690 | return (winsock_lib != NULL) ? |
| 1659 | pfn_ntohs (netshort) : netshort; | 1691 | pfn_ntohs (netshort) : netshort; |
| 1660 | } | 1692 | } |
| 1661 | 1693 | ||
| 1662 | unsigned long | 1694 | unsigned long |
| 1663 | sys_inet_addr (const char * cp) | 1695 | sys_inet_addr (const char * cp) |
| 1664 | { | 1696 | { |
| 1665 | return (have_winsock) ? | 1697 | return (winsock_lib != NULL) ? |
| 1666 | pfn_inet_addr (cp) : INADDR_NONE; | 1698 | pfn_inet_addr (cp) : INADDR_NONE; |
| 1667 | } | 1699 | } |
| 1668 | 1700 | ||
| 1669 | int | 1701 | int |
| 1670 | sys_gethostname (char * name, int namelen) | 1702 | sys_gethostname (char * name, int namelen) |
| 1671 | { | 1703 | { |
| 1672 | if (have_winsock) | 1704 | if (winsock_lib != NULL) |
| 1673 | return pfn_gethostname (name, namelen); | 1705 | return pfn_gethostname (name, namelen); |
| 1674 | 1706 | ||
| 1675 | if (namelen > MAX_COMPUTERNAME_LENGTH) | 1707 | if (namelen > MAX_COMPUTERNAME_LENGTH) |
| @@ -1684,7 +1716,7 @@ sys_gethostbyname(const char * name) | |||
| 1684 | { | 1716 | { |
| 1685 | struct hostent * host; | 1717 | struct hostent * host; |
| 1686 | 1718 | ||
| 1687 | if (!have_winsock) | 1719 | if (winsock_lib == NULL) |
| 1688 | { | 1720 | { |
| 1689 | h_errno = ENETDOWN; | 1721 | h_errno = ENETDOWN; |
| 1690 | return NULL; | 1722 | return NULL; |
| @@ -1702,7 +1734,7 @@ sys_getservbyname(const char * name, const char * proto) | |||
| 1702 | { | 1734 | { |
| 1703 | struct servent * serv; | 1735 | struct servent * serv; |
| 1704 | 1736 | ||
| 1705 | if (!have_winsock) | 1737 | if (winsock_lib == NULL) |
| 1706 | { | 1738 | { |
| 1707 | h_errno = ENETDOWN; | 1739 | h_errno = ENETDOWN; |
| 1708 | return NULL; | 1740 | return NULL; |
| @@ -1751,13 +1783,16 @@ sys_close (int fd) | |||
| 1751 | } | 1783 | } |
| 1752 | if (i == MAXDESC) | 1784 | if (i == MAXDESC) |
| 1753 | { | 1785 | { |
| 1754 | #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE) | 1786 | #ifdef HAVE_SOCKETS |
| 1755 | if (fd_info[fd].flags & FILE_SOCKET) | 1787 | if (fd_info[fd].flags & FILE_SOCKET) |
| 1756 | { | 1788 | { |
| 1757 | if (!have_winsock) abort (); | 1789 | #ifndef SOCK_REPLACE_HANDLE |
| 1790 | if (winsock_lib == NULL) abort (); | ||
| 1758 | 1791 | ||
| 1759 | pfn_shutdown (SOCK_HANDLE (fd), 2); | 1792 | pfn_shutdown (SOCK_HANDLE (fd), 2); |
| 1760 | rc = pfn_closesocket (SOCK_HANDLE (fd)); | 1793 | rc = pfn_closesocket (SOCK_HANDLE (fd)); |
| 1794 | #endif | ||
| 1795 | winsock_inuse--; /* count open sockets */ | ||
| 1761 | } | 1796 | } |
| 1762 | #endif | 1797 | #endif |
| 1763 | delete_child (cp); | 1798 | delete_child (cp); |
| @@ -2010,7 +2045,7 @@ sys_read (int fd, char * buffer, unsigned int count) | |||
| 2010 | #ifdef HAVE_SOCKETS | 2045 | #ifdef HAVE_SOCKETS |
| 2011 | else /* FILE_SOCKET */ | 2046 | else /* FILE_SOCKET */ |
| 2012 | { | 2047 | { |
| 2013 | if (!have_winsock) abort (); | 2048 | if (winsock_lib == NULL) abort (); |
| 2014 | 2049 | ||
| 2015 | /* do the equivalent of a non-blocking read */ | 2050 | /* do the equivalent of a non-blocking read */ |
| 2016 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); | 2051 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); |
| @@ -2070,7 +2105,7 @@ sys_write (int fd, const void * buffer, unsigned int count) | |||
| 2070 | #ifdef HAVE_SOCKETS | 2105 | #ifdef HAVE_SOCKETS |
| 2071 | if (fd_info[fd].flags & FILE_SOCKET) | 2106 | if (fd_info[fd].flags & FILE_SOCKET) |
| 2072 | { | 2107 | { |
| 2073 | if (!have_winsock) abort (); | 2108 | if (winsock_lib == NULL) abort (); |
| 2074 | nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); | 2109 | nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); |
| 2075 | if (nchars == SOCKET_ERROR) | 2110 | if (nchars == SOCKET_ERROR) |
| 2076 | { | 2111 | { |
| @@ -2103,8 +2138,19 @@ void | |||
| 2103 | init_ntproc () | 2138 | init_ntproc () |
| 2104 | { | 2139 | { |
| 2105 | #ifdef HAVE_SOCKETS | 2140 | #ifdef HAVE_SOCKETS |
| 2106 | /* initialise the socket interface if available */ | 2141 | /* Initialise the socket interface now if available and requested by |
| 2107 | init_winsock (); | 2142 | the user by defining PRELOAD_WINSOCK; otherwise loading will be |
| 2143 | delayed until open-network-stream is called (win32-has-winsock can | ||
| 2144 | also be used to dynamically load or reload winsock). | ||
| 2145 | |||
| 2146 | Conveniently, init_environment is called before us, so | ||
| 2147 | PRELOAD_WINSOCK can be set in the registry. */ | ||
| 2148 | |||
| 2149 | /* Always initialize this correctly. */ | ||
| 2150 | winsock_lib = NULL; | ||
| 2151 | |||
| 2152 | if (getenv ("PRELOAD_WINSOCK") != NULL) | ||
| 2153 | init_winsock (TRUE); | ||
| 2108 | #endif | 2154 | #endif |
| 2109 | 2155 | ||
| 2110 | /* Initial preparation for subprocess support: replace our standard | 2156 | /* Initial preparation for subprocess support: replace our standard |