Mercurial > hg > xemacs-beta
comparison src/process-unix.c @ 502:7039e6323819
[xemacs-hg @ 2001-05-04 22:41:46 by ben]
----------------------- byte-comp warning fixes -----------------
New functions for cleanly eliminating byte-compiler warnings.
Their definitions require no changes at all in bytecomp.el,
meaning that any package that wants to use them and be compatible
with older versions of XEmacs need only copy the code and rename
the functions (i.e. prefix them with the package name).
Eliminate byte-compiler warnings using the new functions in
bytecomp-runtime.el.
Move coding-system-put,get,category, since they're not
Mule-specific and are used in prefer-coding-system.
font.el was incredibly ugly. Clean it up. Avoid using defsubst
for any exported functions, to avoid possible compatibility
problems if we later change the internal interface. (It happened
before, with face accessors, between 19.8 and 19.9). Fix tons
of warnings.
Clean up (new function gpm-is-supported-p eliminates duplicate
code in gpm-create/delete-device-hook) and eliminate warnings.
---------- make byte-recompile-directory work in the ---------
core `lisp' dir, even in the absence of
a Mule XEmacs (i.e. make it skip the Mule
files rather than trying to compile them).
now you should be able to do `touch *.el'
in the `lisp' dir, then
M-x byte-recompile-directory, and get no
warnings.
Avoid trying to compile Mule files in byte-recompile-directory
when we're not in a Mule XEmacs, since we're highly likely to get
syntax errors.
Add a coding-system cookie to all Mule files so that
byte-recompile-directory ignores them.
Magic cookie function moved to files.el from code-files.el (for
use by bytecomp even in a non-coding-system XEmacs), and changed
names and semantics for use by bytecomp. NOTE: IMO this is an
internal function that we can change as we like (and there is
absolutely no code anywhere else using the function).
---------------- GUI improvements: menus, help -------------------
Rearrange order of keymap declarations to be alphabetical.
Improve help on help to include all bindings, and group by
category. Add bindings for new Info commands. Remove
warnings. Use command-hyper-apropos in place of command-apropos.
Add a function to do the equivalent of command-apropos.
Evals its help-text argument so you can put expressions there.
Used now by help-for-help.
Add binding to continue text searches. Expand index searches to
work over multiple info documents. Add commands to search
text/index in User and Lispref.
Add new entry, "Uncomment Region" (parallels "Comment Out Region").
Redo Help menu; add bindings for new Info commands to search the
index or text of the User and Lispref manuals. Add command for
mark-paragraph, activate-region. Make Edit->R accelerator be
rectangle, not register (more commonly used), and put rectangle
first. Fix the Edit Init File entry to never load the .elc file.
Simplify the default-popup-menu. Add Cmds->Tabs menu.
Use kp-left not kp_left, etc.
---------------- Miscellaneous bug fixes/cleanup -------------------
byte-compiler-options: Correct doc string.
easy-menu-do-define: fix extra quote.
fill-paragraph-or-region:Rewrite to be more correct -- use
call-interactively so that we always get exactly the same
behavior as if the functions were called directly.
No need to fiddle with zmacs-region-stays, now that bogus
clearing of it (2001-04-28 src/ChangeLog) is removed.
Put dialog titles back in -- this time correctly. Fix various
other problems with leaks and such.
key-sequence-list-description:
Clean up fun to always correctly canonicalize.
Clean up Kinsoku comments, synch comment-region with FSF 20.7.
* simple.el (region-exists-p):
* simple.el (region-active-p):
Add comment about which one is correct to use in menu specs.
* sound.el (load-sound-file):
Minor code clean up.
* startup.el:
* startup.el (command-line-early):
* startup.el (initial-scratch-message):
Comment changes. Add info about sample.init.el to splash screen.
Improve initial-scratch-message and clarify purpose of Scratch
buffer. Fix byte-compile warning.
------------------------ Added features -------------------------
Add new variable to control whether etags checks all parent
directories for tag files. (On by default.)
* hash-table.el: New file, useful utility functions.
* dumped-lisp.el (preloaded-file-list): Dump hash-table.el.
------------ notable bug fix: Windows event code --------------
Get critical quit working.
------------ notable bug fix and new feature: regex code --------------
Shy groups were implemented in a horrible, half-assed way that
would cause them to screw up regex searching in most cases.
Fixed to work correctly.
Also extended back-reference syntax past 9. Only is recognized
as such if there are at least that many non-shy groups; and
optionally will warn about such uses, to catch old code that
might be using them differently. (Added variable to control
this in search.c -- `warn-about-possibly-incompatible-back-
references', on by default for the moment. Declared in lisp.h.
---------------- process/SIGIO improvements -------------------
define USE_GETADDRINFO to replace more complex conditional,
and use it. the code conditionalized on this in
unix_open_network_stream had *serious* problems handling errors.
it's now fixed, and major amounts of duplicate code between
the two versions were combined.
don't disable SIGIO and other interrupts unless
CONNECT_NEEDS_SLOWED_INTERRUPTS is defined -- don't penalize OS's
without bugs. similarly for a freebsd bug that was affecting all
OS's.
* s\ultrix.h:
define CONNECT_NEEDS_SLOWED_INTERRUPTS, since that's the OS
mentioned as having a kernel bug.
* sysdep.c (request_sigio_on_device):
* sysdep.c (unrequest_sigio_on_device):
fix SIGIO problems on Linux. add check for O_ASYNC in case it's
defined and FASYNC isn't. add comment about other ways to do
SIGIO on Linux.
* callproc.c (Fold_call_process_internal):
* process.c (Fstart_process_internal):
Deal with the possibility that `default-directory' doesn't
have terminating slash. Correct comments about vfork.
---------------- Miscellaneous bug fixes/cleanup -------------------
* callint.c (Finteractive):
Add lots of documentation -- exactly what the Lisp equivalents of
all the interactive specs are.
* console.h (struct console): change type of quit_char to Emchar.
* event-msw.c (lstream_type_create_mswindows_selectable): spacing
change.
Eliminate events-mod.h and combine into events.h.
* emacs.c:
* emacs.c (make_arg_list_1):
* emacs.c (main_1):
A couple of char->Extbyte changes, add a comment.
* glyphs-msw.c:
Correct indentation of function defns to not exceed 80 cols.
Try (sort of) to fix some code that sets the colors of the
progress gauge. (Commented out)
* keymap.c (syms_of_keymap):
use DEFSYMBOL.
* process.c (read_process_output):
No need to fiddle with zmacs_region_stays, now that bogus
clearing of it (see below) is removed.
* search.c (Freplace_match): warning fix.
author | ben |
---|---|
date | Fri, 04 May 2001 22:42:35 +0000 |
parents | f42052c80e1c |
children | c69610198c35 |
comparison
equal
deleted
inserted
replaced
501:0a255b32b157 | 502:7039e6323819 |
---|---|
62 #include "syswait.h" | 62 #include "syswait.h" |
63 | 63 |
64 #ifdef HPUX | 64 #ifdef HPUX |
65 #include <grp.h> /* See grantpt fixups for HPUX below. */ | 65 #include <grp.h> /* See grantpt fixups for HPUX below. */ |
66 #endif | 66 #endif |
67 | |
68 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GETNAMEINFO) | |
69 #define USE_GETADDRINFO | |
70 #endif | |
71 | |
67 | 72 |
68 /* | 73 /* |
69 * Implementation-specific data. Pointed to by Lisp_Process->process_data | 74 * Implementation-specific data. Pointed to by Lisp_Process->process_data |
70 */ | 75 */ |
71 | 76 |
433 } | 438 } |
434 | 439 |
435 | 440 |
436 #ifdef HAVE_SOCKETS | 441 #ifdef HAVE_SOCKETS |
437 | 442 |
438 #if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)) | 443 #ifndef USE_GETADDRINFO |
439 static int | 444 static int |
440 get_internet_address (Lisp_Object host, struct sockaddr_in *address, | 445 get_internet_address (Lisp_Object host, struct sockaddr_in *address, |
441 Error_behavior errb) | 446 Error_behavior errb) |
442 { | 447 { |
443 struct hostent *host_info_ptr = NULL; | 448 struct hostent *host_info_ptr = NULL; |
466 Fsleep_for (make_int (1)); | 471 Fsleep_for (make_int (1)); |
467 } | 472 } |
468 if (host_info_ptr) | 473 if (host_info_ptr) |
469 { | 474 { |
470 address->sin_family = host_info_ptr->h_addrtype; | 475 address->sin_family = host_info_ptr->h_addrtype; |
471 memcpy (&address->sin_addr, host_info_ptr->h_addr, host_info_ptr->h_length); | 476 memcpy (&address->sin_addr, host_info_ptr->h_addr, |
477 host_info_ptr->h_length); | |
472 } | 478 } |
473 else | 479 else |
474 { | 480 { |
475 IN_ADDR numeric_addr; | 481 IN_ADDR numeric_addr; |
476 /* Attempt to interpret host as numeric inet address */ | 482 /* Attempt to interpret host as numeric inet address */ |
489 * (IN_ADDR *) &address->sin_addr = numeric_addr; | 495 * (IN_ADDR *) &address->sin_addr = numeric_addr; |
490 } | 496 } |
491 | 497 |
492 return 1; | 498 return 1; |
493 } | 499 } |
494 #endif /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */ | 500 #endif /* !USE_GETADDRINFO */ |
495 | 501 |
496 static void | 502 static void |
497 set_socket_nonblocking_maybe (int fd, int port, const char* proto) | 503 set_socket_nonblocking_maybe (int fd, int port, const char* proto) |
498 { | 504 { |
499 #ifdef PROCESS_IO_BLOCKING | 505 #ifdef PROCESS_IO_BLOCKING |
1576 | 1582 |
1577 #ifdef HAVE_SOCKETS | 1583 #ifdef HAVE_SOCKETS |
1578 static Lisp_Object | 1584 static Lisp_Object |
1579 unix_canonicalize_host_name (Lisp_Object host) | 1585 unix_canonicalize_host_name (Lisp_Object host) |
1580 { | 1586 { |
1581 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO) | 1587 #ifdef USE_GETADDRINFO |
1582 struct addrinfo hints, *res; | 1588 struct addrinfo hints, *res; |
1583 static char addrbuf[NI_MAXHOST]; | 1589 static char addrbuf[NI_MAXHOST]; |
1584 Lisp_Object canonname; | 1590 Lisp_Object canonname; |
1585 int retval; | 1591 int retval; |
1586 char *ext_host; | 1592 char *ext_host; |
1610 | 1616 |
1611 freeaddrinfo (res); | 1617 freeaddrinfo (res); |
1612 } | 1618 } |
1613 | 1619 |
1614 return canonname; | 1620 return canonname; |
1615 #else /* ! HAVE_GETADDRINFO */ | 1621 #else /* ! USE_GETADDRINFO */ |
1616 struct sockaddr_in address; | 1622 struct sockaddr_in address; |
1617 | 1623 |
1618 if (!get_internet_address (host, &address, ERROR_ME_NOT)) | 1624 if (!get_internet_address (host, &address, ERROR_ME_NOT)) |
1619 return host; | 1625 return host; |
1620 | 1626 |
1621 if (address.sin_family == AF_INET) | 1627 if (address.sin_family == AF_INET) |
1622 return build_string (inet_ntoa (address.sin_addr)); | 1628 return build_string (inet_ntoa (address.sin_addr)); |
1623 else | 1629 else |
1624 /* #### any clue what to do here? */ | 1630 /* #### any clue what to do here? */ |
1625 return host; | 1631 return host; |
1626 #endif /* ! HAVE_GETADDRINFO */ | 1632 #endif /* ! USE_GETADDRINFO */ |
1627 } | 1633 } |
1628 | 1634 |
1629 /* Open a TCP network connection to a given HOST/SERVICE. | 1635 /* Open a TCP network connection to a given HOST/SERVICE. |
1630 Treated exactly like a normal process when reading and writing. | 1636 Treated exactly like a normal process when reading and writing. |
1631 Only differences are in status display and process deletion. | 1637 Only differences are in status display and process deletion. |
1632 A network connection has no PID; you cannot signal it. All you can | 1638 A network connection has no PID; you cannot signal it. All you can |
1633 do is deactivate and close it via delete-process. */ | 1639 do is deactivate and close it via delete-process. */ |
1634 | 1640 |
1635 static void | 1641 static void |
1636 unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service, | 1642 unix_open_network_stream (Lisp_Object name, Lisp_Object host, |
1637 Lisp_Object protocol, void** vinfd, void** voutfd) | 1643 Lisp_Object service, Lisp_Object protocol, |
1644 void **vinfd, void **voutfd) | |
1638 { | 1645 { |
1639 int inch; | 1646 int inch; |
1640 int outch; | 1647 int outch; |
1641 volatile int s; | 1648 volatile int s = -1; |
1642 volatile int port; | 1649 volatile int port; |
1643 volatile int retry = 0; | 1650 volatile int retry = 0; |
1651 volatile int xerrno = 0; | |
1652 volatile int failed_connect = 0; | |
1644 int retval; | 1653 int retval; |
1645 | 1654 |
1646 CHECK_STRING (host); | 1655 CHECK_STRING (host); |
1647 | 1656 |
1648 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) | 1657 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) |
1649 invalid_argument ("Unsupported protocol", protocol); | 1658 invalid_argument ("Unsupported protocol", protocol); |
1650 | 1659 |
1651 { | 1660 { |
1652 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO) | 1661 #ifdef USE_GETADDRINFO |
1662 | |
1653 struct addrinfo hints, *res; | 1663 struct addrinfo hints, *res; |
1654 struct addrinfo * volatile lres; | 1664 struct addrinfo * volatile lres; |
1655 char *portstring; | 1665 char *portstring; |
1656 volatile int xerrno = 0; | |
1657 volatile int failed_connect = 0; | |
1658 char *ext_host; | 1666 char *ext_host; |
1659 /* | 1667 /* |
1660 * Caution: service can either be a string or int. | 1668 * Caution: service can either be a string or int. |
1661 * Convert to a C string for later use by getaddrinfo. | 1669 * Convert to a C string for later use by getaddrinfo. |
1662 */ | 1670 */ |
1692 error ("%s/%s %s", XSTRING_DATA (host), portstring, gai_error); | 1700 error ("%s/%s %s", XSTRING_DATA (host), portstring, gai_error); |
1693 } | 1701 } |
1694 | 1702 |
1695 /* address loop */ | 1703 /* address loop */ |
1696 for (lres = res; lres ; lres = lres->ai_next) | 1704 for (lres = res; lres ; lres = lres->ai_next) |
1705 | |
1706 #else /* !USE_GETADDRINFO */ | |
1707 | |
1708 struct sockaddr_in address; | |
1709 volatile int i; | |
1710 | |
1711 if (INTP (service)) | |
1712 port = htons ((unsigned short) XINT (service)); | |
1713 else | |
1697 { | 1714 { |
1715 struct servent *svc_info; | |
1716 CHECK_STRING (service); | |
1717 | |
1698 if (EQ (protocol, Qtcp)) | 1718 if (EQ (protocol, Qtcp)) |
1699 s = socket (lres->ai_family, SOCK_STREAM, 0); | 1719 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); |
1700 else /* EQ (protocol, Qudp) */ | 1720 else /* EQ (protocol, Qudp) */ |
1701 s = socket (lres->ai_family, SOCK_DGRAM, 0); | 1721 svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp"); |
1722 | |
1723 if (svc_info == 0) | |
1724 invalid_argument ("Unknown service", service); | |
1725 port = svc_info->s_port; | |
1726 } | |
1727 | |
1728 get_internet_address (host, &address, ERROR_ME); | |
1729 address.sin_port = port; | |
1730 | |
1731 /* use a trivial address loop */ | |
1732 for (i = 0; i < 1; i++) | |
1733 | |
1734 #endif /* !USE_GETADDRINFO */ | |
1735 { | |
1736 #ifdef USE_GETADDRINFO | |
1737 int family = lres->ai_family; | |
1738 #else | |
1739 int family = address.sin_family; | |
1740 #endif | |
1741 | |
1742 if (EQ (protocol, Qtcp)) | |
1743 s = socket (family, SOCK_STREAM, 0); | |
1744 else /* EQ (protocol, Qudp) */ | |
1745 s = socket (family, SOCK_DGRAM, 0); | |
1702 | 1746 |
1703 if (s < 0) | 1747 if (s < 0) |
1704 continue; | 1748 { |
1705 | 1749 xerrno = errno; |
1706 /* Turn off interrupts here -- see comments below. There used to | 1750 failed_connect = 0; |
1707 be code which called bind_polling_period() to slow the polling | 1751 continue; |
1708 period down rather than turn it off, but that seems rather | 1752 } |
1709 bogus to me. Best thing here is to use a non-blocking connect | 1753 |
1710 or something, to check for QUIT. */ | 1754 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS |
1711 | |
1712 /* Comments that are not quite valid: */ | |
1713 | |
1714 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) | |
1715 when connect is interrupted. So let's not let it get interrupted. | |
1716 Note we do not turn off polling, because polling is only used | |
1717 when not interrupt_input, and thus not normally used on the systems | |
1718 which have this bug. On systems which use polling, there's no way | |
1719 to quit if polling is turned off. */ | |
1720 | |
1721 /* Slow down polling. Some kernels have a bug which causes retrying | 1755 /* Slow down polling. Some kernels have a bug which causes retrying |
1722 connect to fail after a connect. */ | 1756 connect to fail after a connect. (Note that the entire purpose |
1723 | 1757 for this code is a very old comment concerning an Ultrix bug that |
1758 requires this code. We used to do this ALWAYS despite this! | |
1759 This messes up C-g out of connect() in a big way. So instead we | |
1760 just assume that anyone who sees such a kernel bug will define | |
1761 this constant, which for now is only defined under Ultrix.) --ben | |
1762 */ | |
1724 slow_down_interrupts (); | 1763 slow_down_interrupts (); |
1764 #endif | |
1725 | 1765 |
1726 loop: | 1766 loop: |
1727 | 1767 |
1728 /* A system call interrupted with a SIGALRM or SIGIO comes back | 1768 /* A system call interrupted with a SIGALRM or SIGIO comes back |
1729 here, with can_break_system_calls reset to 0. */ | 1769 here, with can_break_system_calls reset to 0. */ |
1730 SETJMP (break_system_call_jump); | 1770 SETJMP (break_system_call_jump); |
1731 if (QUITP) | 1771 if (QUITP) |
1732 { | 1772 { |
1773 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
1733 speed_up_interrupts (); | 1774 speed_up_interrupts (); |
1775 #endif | |
1734 REALLY_QUIT; | 1776 REALLY_QUIT; |
1735 /* In case something really weird happens ... */ | 1777 /* In case something really weird happens ... */ |
1778 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
1736 slow_down_interrupts (); | 1779 slow_down_interrupts (); |
1780 #endif | |
1737 } | 1781 } |
1738 | 1782 |
1739 /* Break out of connect with a signal (it isn't otherwise possible). | 1783 /* Break out of connect with a signal (it isn't otherwise possible). |
1740 Thus you don't get screwed with a hung network. */ | 1784 Thus you don't get screwed with a hung network. */ |
1741 can_break_system_calls = 1; | 1785 can_break_system_calls = 1; |
1786 | |
1787 #ifdef USE_GETADDRINFO | |
1742 retval = connect (s, lres->ai_addr, lres->ai_addrlen); | 1788 retval = connect (s, lres->ai_addr, lres->ai_addrlen); |
1789 #else | |
1790 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); | |
1791 #endif | |
1743 can_break_system_calls = 0; | 1792 can_break_system_calls = 0; |
1744 if (retval == -1) | 1793 if (retval == -1 && errno != EISCONN) |
1745 { | 1794 { |
1746 xerrno = errno; | 1795 xerrno = errno; |
1747 if (errno != EISCONN) | 1796 if (errno == EINTR) |
1797 goto loop; | |
1798 if (errno == EADDRINUSE && retry < 20) | |
1748 { | 1799 { |
1749 if (errno == EINTR) | 1800 #ifdef __FreeBSD__ |
1750 goto loop; | 1801 /* A delay here is needed on some FreeBSD systems, |
1751 if (errno == EADDRINUSE && retry < 20) | 1802 and it is harmless, since this retrying takes |
1752 { | 1803 time anyway and should be infrequent. |
1753 /* A delay here is needed on some FreeBSD systems, | 1804 `sleep-for' allowed for quitting this loop with |
1754 and it is harmless, since this retrying takes time anyway | 1805 interrupts slowed down so it can't be used |
1755 and should be infrequent. | 1806 here. Async timers should already be disabled |
1756 `sleep-for' allowed for quitting this loop with interrupts | 1807 at this point so we can use `sleep'. |
1757 slowed down so it can't be used here. Async timers should | 1808 |
1758 already be disabled at this point so we can use `sleep'. */ | 1809 (Again, this was not conditionalized on FreeBSD. |
1759 sleep (1); | 1810 Let's not mess up systems without the problem. --ben) |
1760 retry++; | 1811 */ |
1761 goto loop; | 1812 sleep (1); |
1762 } | 1813 #endif |
1814 retry++; | |
1815 goto loop; | |
1763 } | 1816 } |
1764 | 1817 |
1765 failed_connect = 1; | 1818 failed_connect = 1; |
1766 close (s); | 1819 close (s); |
1767 s = -1; | 1820 s = -1; |
1768 | 1821 |
1822 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
1769 speed_up_interrupts (); | 1823 speed_up_interrupts (); |
1824 #endif | |
1770 | 1825 |
1771 continue; | 1826 continue; |
1772 } | 1827 } |
1773 | 1828 |
1829 #ifdef USE_GETADDRINFO | |
1774 if (port == 0) | 1830 if (port == 0) |
1775 { | 1831 { |
1776 int gni; | 1832 int gni; |
1777 char servbuf[NI_MAXSERV]; | 1833 char servbuf[NI_MAXSERV]; |
1778 | 1834 |
1788 if (gni == 0) | 1844 if (gni == 0) |
1789 port = strtol (servbuf, NULL, 10); | 1845 port = strtol (servbuf, NULL, 10); |
1790 } | 1846 } |
1791 | 1847 |
1792 break; | 1848 break; |
1849 #endif /* USE_GETADDRINFO */ | |
1793 } /* address loop */ | 1850 } /* address loop */ |
1794 | 1851 |
1852 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
1795 speed_up_interrupts (); | 1853 speed_up_interrupts (); |
1796 | 1854 #endif |
1855 | |
1856 #ifdef USE_GETADDRINFO | |
1797 freeaddrinfo (res); | 1857 freeaddrinfo (res); |
1858 #endif | |
1859 | |
1798 if (s < 0) | 1860 if (s < 0) |
1799 { | 1861 { |
1800 errno = xerrno; | 1862 errno = xerrno; |
1801 | 1863 |
1802 if (failed_connect) | 1864 if (failed_connect) |
1803 report_file_error ("connection failed", list2 (host, name)); | 1865 report_file_error ("connection failed", list2 (host, name)); |
1804 else | 1866 else |
1805 report_file_error ("error creating socket", list1 (name)); | 1867 report_file_error ("error creating socket", list1 (name)); |
1806 } | 1868 } |
1807 #else /* ! HAVE_GETADDRINFO */ | |
1808 struct sockaddr_in address; | |
1809 | |
1810 if (INTP (service)) | |
1811 port = htons ((unsigned short) XINT (service)); | |
1812 else | |
1813 { | |
1814 struct servent *svc_info; | |
1815 CHECK_STRING (service); | |
1816 | |
1817 if (EQ (protocol, Qtcp)) | |
1818 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); | |
1819 else /* EQ (protocol, Qudp) */ | |
1820 svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp"); | |
1821 | |
1822 if (svc_info == 0) | |
1823 invalid_argument ("Unknown service", service); | |
1824 port = svc_info->s_port; | |
1825 } | |
1826 | |
1827 get_internet_address (host, &address, ERROR_ME); | |
1828 address.sin_port = port; | |
1829 | |
1830 if (EQ (protocol, Qtcp)) | |
1831 s = socket (address.sin_family, SOCK_STREAM, 0); | |
1832 else /* EQ (protocol, Qudp) */ | |
1833 s = socket (address.sin_family, SOCK_DGRAM, 0); | |
1834 | |
1835 if (s < 0) | |
1836 report_file_error ("error creating socket", list1 (name)); | |
1837 | |
1838 /* Turn off interrupts here -- see comments below. There used to | |
1839 be code which called bind_polling_period() to slow the polling | |
1840 period down rather than turn it off, but that seems rather | |
1841 bogus to me. Best thing here is to use a non-blocking connect | |
1842 or something, to check for QUIT. */ | |
1843 | |
1844 /* Comments that are not quite valid: */ | |
1845 | |
1846 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) | |
1847 when connect is interrupted. So let's not let it get interrupted. | |
1848 Note we do not turn off polling, because polling is only used | |
1849 when not interrupt_input, and thus not normally used on the systems | |
1850 which have this bug. On systems which use polling, there's no way | |
1851 to quit if polling is turned off. */ | |
1852 | |
1853 /* Slow down polling. Some kernels have a bug which causes retrying | |
1854 connect to fail after a connect. */ | |
1855 | |
1856 slow_down_interrupts (); | |
1857 | |
1858 loop: | |
1859 | |
1860 /* A system call interrupted with a SIGALRM or SIGIO comes back | |
1861 here, with can_break_system_calls reset to 0. */ | |
1862 SETJMP (break_system_call_jump); | |
1863 if (QUITP) | |
1864 { | |
1865 speed_up_interrupts (); | |
1866 REALLY_QUIT; | |
1867 /* In case something really weird happens ... */ | |
1868 slow_down_interrupts (); | |
1869 } | |
1870 | |
1871 /* Break out of connect with a signal (it isn't otherwise possible). | |
1872 Thus you don't get screwed with a hung network. */ | |
1873 can_break_system_calls = 1; | |
1874 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); | |
1875 can_break_system_calls = 0; | |
1876 if (retval == -1 && errno != EISCONN) | |
1877 { | |
1878 int xerrno = errno; | |
1879 if (errno == EINTR) | |
1880 goto loop; | |
1881 if (errno == EADDRINUSE && retry < 20) | |
1882 { | |
1883 /* A delay here is needed on some FreeBSD systems, | |
1884 and it is harmless, since this retrying takes time anyway | |
1885 and should be infrequent. | |
1886 `sleep-for' allowed for quitting this loop with interrupts | |
1887 slowed down so it can't be used here. Async timers should | |
1888 already be disabled at this point so we can use `sleep'. */ | |
1889 sleep (1); | |
1890 retry++; | |
1891 goto loop; | |
1892 } | |
1893 | |
1894 close (s); | |
1895 | |
1896 speed_up_interrupts (); | |
1897 | |
1898 errno = xerrno; | |
1899 report_file_error ("connection failed", list2 (host, name)); | |
1900 } | |
1901 | |
1902 speed_up_interrupts (); | |
1903 #endif /* ! HAVE_GETADDRINFO */ | |
1904 } | 1869 } |
1905 | 1870 |
1906 inch = s; | 1871 inch = s; |
1907 outch = dup (s); | 1872 outch = dup (s); |
1908 if (outch < 0) | 1873 if (outch < 0) |
1911 report_file_error ("error duplicating socket", list1 (name)); | 1876 report_file_error ("error duplicating socket", list1 (name)); |
1912 } | 1877 } |
1913 | 1878 |
1914 set_socket_nonblocking_maybe (inch, port, "tcp"); | 1879 set_socket_nonblocking_maybe (inch, port, "tcp"); |
1915 | 1880 |
1916 *vinfd = (void*)inch; | 1881 *vinfd = (void *) inch; |
1917 *voutfd = (void*)outch; | 1882 *voutfd = (void *) outch; |
1918 } | 1883 } |
1919 | 1884 |
1920 | 1885 |
1921 #ifdef HAVE_MULTICAST | 1886 #ifdef HAVE_MULTICAST |
1922 | 1887 |
2013 'sendto' and 'recvfrom'. However, in order to handle this connection in | 1978 'sendto' and 'recvfrom'. However, in order to handle this connection in |
2014 the process-like way it is done for TCP, we must be able to use 'write' | 1979 the process-like way it is done for TCP, we must be able to use 'write' |
2015 instead of 'sendto'. Consequently, we 'connect' this socket. */ | 1980 instead of 'sendto'. Consequently, we 'connect' this socket. */ |
2016 | 1981 |
2017 /* See open-network-stream-internal for comments on this part of the code */ | 1982 /* See open-network-stream-internal for comments on this part of the code */ |
1983 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
2018 slow_down_interrupts (); | 1984 slow_down_interrupts (); |
1985 #endif | |
2019 | 1986 |
2020 loop: | 1987 loop: |
2021 | 1988 |
2022 /* A system call interrupted with a SIGALRM or SIGIO comes back | 1989 /* A system call interrupted with a SIGALRM or SIGIO comes back |
2023 here, with can_break_system_calls reset to 0. */ | 1990 here, with can_break_system_calls reset to 0. */ |
2024 SETJMP (break_system_call_jump); | 1991 SETJMP (break_system_call_jump); |
2025 if (QUITP) | 1992 if (QUITP) |
2026 { | 1993 { |
1994 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
2027 speed_up_interrupts (); | 1995 speed_up_interrupts (); |
1996 #endif | |
2028 REALLY_QUIT; | 1997 REALLY_QUIT; |
2029 /* In case something really weird happens ... */ | 1998 /* In case something really weird happens ... */ |
1999 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
2030 slow_down_interrupts (); | 2000 slow_down_interrupts (); |
2001 #endif | |
2031 } | 2002 } |
2032 | 2003 |
2033 /* Break out of connect with a signal (it isn't otherwise possible). | 2004 /* Break out of connect with a signal (it isn't otherwise possible). |
2034 Thus you don't get screwed with a hung network. */ | 2005 Thus you don't get screwed with a hung network. */ |
2035 can_break_system_calls = 1; | 2006 can_break_system_calls = 1; |
2054 goto loop; | 2025 goto loop; |
2055 } | 2026 } |
2056 | 2027 |
2057 close (rs); | 2028 close (rs); |
2058 close (ws); | 2029 close (ws); |
2030 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
2059 speed_up_interrupts (); | 2031 speed_up_interrupts (); |
2032 #endif | |
2060 | 2033 |
2061 errno = xerrno; | 2034 errno = xerrno; |
2062 report_file_error ("error connecting socket", list2(name, port)); | 2035 report_file_error ("error connecting socket", list2(name, port)); |
2063 } | 2036 } |
2064 | 2037 |
2038 #ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS | |
2065 speed_up_interrupts (); | 2039 speed_up_interrupts (); |
2040 #endif | |
2066 | 2041 |
2067 /* scope */ | 2042 /* scope */ |
2068 if (setsockopt (ws, IPPROTO_IP, IP_MULTICAST_TTL, | 2043 if (setsockopt (ws, IPPROTO_IP, IP_MULTICAST_TTL, |
2069 &thettl, sizeof (thettl)) < 0) | 2044 &thettl, sizeof (thettl)) < 0) |
2070 { | 2045 { |