diff 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
line wrap: on
line diff
--- a/src/process-unix.c	Thu May 03 21:08:39 2001 +0000
+++ b/src/process-unix.c	Fri May 04 22:42:35 2001 +0000
@@ -65,6 +65,11 @@
 #include <grp.h>		/* See grantpt fixups for HPUX below. */
 #endif
 
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GETNAMEINFO)
+#define USE_GETADDRINFO
+#endif
+
+
 /*
  * Implementation-specific data. Pointed to by Lisp_Process->process_data
  */
@@ -435,7 +440,7 @@
 
 #ifdef HAVE_SOCKETS
 
-#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO))
+#ifndef USE_GETADDRINFO
 static int
 get_internet_address (Lisp_Object host, struct sockaddr_in *address,
 		      Error_behavior errb)
@@ -468,7 +473,8 @@
   if (host_info_ptr)
     {
       address->sin_family = host_info_ptr->h_addrtype;
-      memcpy (&address->sin_addr, host_info_ptr->h_addr, host_info_ptr->h_length);
+      memcpy (&address->sin_addr, host_info_ptr->h_addr,
+	      host_info_ptr->h_length);
     }
   else
     {
@@ -491,7 +497,7 @@
 
   return 1;
 }
-#endif /*  !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */
+#endif /* !USE_GETADDRINFO */
 
 static void
 set_socket_nonblocking_maybe (int fd, int port, const char* proto)
@@ -1578,7 +1584,7 @@
 static Lisp_Object
 unix_canonicalize_host_name (Lisp_Object host)
 {
-#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)
+#ifdef USE_GETADDRINFO
   struct addrinfo hints, *res;
   static char addrbuf[NI_MAXHOST];
   Lisp_Object canonname;
@@ -1612,7 +1618,7 @@
     }
 
   return canonname;
-#else /* ! HAVE_GETADDRINFO */
+#else /* ! USE_GETADDRINFO */
   struct sockaddr_in address;
 
   if (!get_internet_address (host, &address, ERROR_ME_NOT))
@@ -1623,7 +1629,7 @@
   else
     /* #### any clue what to do here? */
     return host;
-#endif /* ! HAVE_GETADDRINFO */
+#endif /* ! USE_GETADDRINFO */
 }
 
 /* Open a TCP network connection to a given HOST/SERVICE.
@@ -1633,14 +1639,17 @@
    do is deactivate and close it via delete-process. */
 
 static void
-unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service,
-			  Lisp_Object protocol, void** vinfd, void** voutfd)
+unix_open_network_stream (Lisp_Object name, Lisp_Object host,
+			  Lisp_Object service, Lisp_Object protocol,
+			  void **vinfd, void **voutfd)
 {
   int inch;
   int outch;
-  volatile int s;
+  volatile int s = -1;
   volatile int port;
   volatile int retry = 0;
+  volatile int xerrno = 0;
+  volatile int failed_connect = 0;
   int retval;
 
   CHECK_STRING (host);
@@ -1649,12 +1658,11 @@
     invalid_argument ("Unsupported protocol", protocol);
 
   {
-#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)
+#ifdef USE_GETADDRINFO
+
     struct addrinfo hints, *res;
     struct addrinfo * volatile lres;
     char *portstring;
-    volatile int xerrno = 0;
-    volatile int failed_connect = 0;
     char *ext_host;
     /*
      * Caution: service can either be a string or int.
@@ -1694,118 +1702,11 @@
 
     /* address loop */
     for (lres = res; lres ; lres = lres->ai_next)
-      {
-	if (EQ (protocol, Qtcp))
-	  s = socket (lres->ai_family, SOCK_STREAM, 0);
-	else /* EQ (protocol, Qudp) */
-	  s = socket (lres->ai_family, SOCK_DGRAM, 0);
 
-	if (s < 0)
-	  continue;
-
-	/* Turn off interrupts here -- see comments below.  There used to
-	   be code which called bind_polling_period() to slow the polling
-	   period down rather than turn it off, but that seems rather
-	   bogus to me.  Best thing here is to use a non-blocking connect
-	   or something, to check for QUIT. */
-
-	/* Comments that are not quite valid: */
-
-	/* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
-	   when connect is interrupted.  So let's not let it get interrupted.
-	   Note we do not turn off polling, because polling is only used
-	   when not interrupt_input, and thus not normally used on the systems
-	   which have this bug.  On systems which use polling, there's no way
-	   to quit if polling is turned off.  */
-
-	/* Slow down polling.  Some kernels have a bug which causes retrying
-	   connect to fail after a connect.  */
-
-	slow_down_interrupts ();
-
-      loop:
-
-	/* A system call interrupted with a SIGALRM or SIGIO comes back
-	   here, with can_break_system_calls reset to 0. */
-	SETJMP (break_system_call_jump);
-	if (QUITP)
-	  {
-	    speed_up_interrupts ();
-	    REALLY_QUIT;
-	    /* In case something really weird happens ... */
-	    slow_down_interrupts ();
-	  }
+#else /* !USE_GETADDRINFO */
 
-	/* Break out of connect with a signal (it isn't otherwise possible).
-	   Thus you don't get screwed with a hung network. */
-	can_break_system_calls = 1;
-	retval = connect (s, lres->ai_addr, lres->ai_addrlen);
-	can_break_system_calls = 0;
-	if (retval == -1)
-	  {
-	    xerrno = errno;
-	    if (errno != EISCONN)
-	      {
-		if (errno == EINTR)
-		  goto loop;
-		if (errno == EADDRINUSE && retry < 20)
-		  {
-		    /* A delay here is needed on some FreeBSD systems,
-		       and it is harmless, since this retrying takes time anyway
-		       and should be infrequent.
-		       `sleep-for' allowed for quitting this loop with interrupts
-		       slowed down so it can't be used here.  Async timers should
-		       already be disabled at this point so we can use `sleep'. */
-		    sleep (1);
-		    retry++;
-		    goto loop;
-		  }
-	      }
-
-	    failed_connect = 1;
-	    close (s);
-            s = -1;
-
-	    speed_up_interrupts ();
-
-	    continue;
-	  }
-
-	if (port == 0)
-	  {
-	    int gni;
-	    char servbuf[NI_MAXSERV];
-
-	    if (EQ (protocol, Qtcp))
-	      gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
-				 NULL, 0, servbuf, sizeof(servbuf),
-				 NI_NUMERICSERV);
-	    else /* EQ (protocol, Qudp) */
-	      gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
-				 NULL, 0, servbuf, sizeof(servbuf),
-				 NI_NUMERICSERV | NI_DGRAM);
-
-	    if (gni == 0)
-	      port = strtol (servbuf, NULL, 10);
-	  }
-
-	break;
-      } /* address loop */
-
-    speed_up_interrupts ();
-
-    freeaddrinfo (res);
-    if (s < 0)
-      {
-	errno = xerrno;
-
-	if (failed_connect)
-	  report_file_error ("connection failed", list2 (host, name));
-	else
-	  report_file_error ("error creating socket", list1 (name));
-      }
-#else /* ! HAVE_GETADDRINFO */
     struct sockaddr_in address;
+    volatile int i;
 
     if (INTP (service))
       port = htons ((unsigned short) XINT (service));
@@ -1827,80 +1728,144 @@
     get_internet_address (host, &address, ERROR_ME);
     address.sin_port = port;
 
-    if (EQ (protocol, Qtcp))
-      s = socket (address.sin_family, SOCK_STREAM, 0);
-    else /* EQ (protocol, Qudp) */
-      s = socket (address.sin_family, SOCK_DGRAM, 0);
+    /* use a trivial address loop */
+    for (i = 0; i < 1; i++)
+
+#endif /* !USE_GETADDRINFO */
+      {
+#ifdef USE_GETADDRINFO
+	int family = lres->ai_family;
+#else
+	int family = address.sin_family;
+#endif
+
+	if (EQ (protocol, Qtcp))
+	  s = socket (family, SOCK_STREAM, 0);
+	else /* EQ (protocol, Qudp) */
+	  s = socket (family, SOCK_DGRAM, 0);
+
+	if (s < 0)
+	  {
+	    xerrno = errno;
+	    failed_connect = 0;
+	    continue;
+	  }
+
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
+	/* Slow down polling.  Some kernels have a bug which causes retrying
+	   connect to fail after a connect. (Note that the entire purpose
+	   for this code is a very old comment concerning an Ultrix bug that
+	   requires this code.  We used to do this ALWAYS despite this!
+	   This messes up C-g out of connect() in a big way.  So instead we
+	   just assume that anyone who sees such a kernel bug will define
+	   this constant, which for now is only defined under Ultrix.) --ben
+	*/
+	slow_down_interrupts ();
+#endif
+
+      loop:
+
+	/* A system call interrupted with a SIGALRM or SIGIO comes back
+	   here, with can_break_system_calls reset to 0. */
+	SETJMP (break_system_call_jump);
+	if (QUITP)
+	  {
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
+	    speed_up_interrupts ();
+#endif
+	    REALLY_QUIT;
+	    /* In case something really weird happens ... */
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
+	    slow_down_interrupts ();
+#endif
+	  }
+
+	/* Break out of connect with a signal (it isn't otherwise possible).
+	   Thus you don't get screwed with a hung network. */
+	can_break_system_calls = 1;
+
+#ifdef USE_GETADDRINFO
+	retval = connect (s, lres->ai_addr, lres->ai_addrlen);
+#else
+	retval = connect (s, (struct sockaddr *) &address, sizeof (address));
+#endif
+	can_break_system_calls = 0;
+	if (retval == -1 && errno != EISCONN)
+	  {
+	    xerrno = errno;
+	    if (errno == EINTR)
+	      goto loop;
+	    if (errno == EADDRINUSE && retry < 20)
+	      {
+#ifdef __FreeBSD__
+		/* A delay here is needed on some FreeBSD systems,
+		   and it is harmless, since this retrying takes
+		   time anyway and should be infrequent.
+		   `sleep-for' allowed for quitting this loop with
+		   interrupts slowed down so it can't be used
+		   here.  Async timers should already be disabled
+		   at this point so we can use `sleep'.
+
+		   (Again, this was not conditionalized on FreeBSD.
+		   Let's not mess up systems without the problem. --ben) 
+		*/
+		sleep (1);
+#endif
+		retry++;
+		goto loop;
+	      }
+
+	    failed_connect = 1;
+	    close (s);
+            s = -1;
+
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
+	    speed_up_interrupts ();
+#endif
+
+	    continue;
+	  }
+
+#ifdef USE_GETADDRINFO
+	if (port == 0)
+	  {
+	    int gni;
+	    char servbuf[NI_MAXSERV];
+
+	    if (EQ (protocol, Qtcp))
+	      gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
+				 NULL, 0, servbuf, sizeof(servbuf),
+				 NI_NUMERICSERV);
+	    else /* EQ (protocol, Qudp) */
+	      gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
+				 NULL, 0, servbuf, sizeof(servbuf),
+				 NI_NUMERICSERV | NI_DGRAM);
+
+	    if (gni == 0)
+	      port = strtol (servbuf, NULL, 10);
+	  }
+
+	break;
+#endif /* USE_GETADDRINFO */
+      } /* address loop */
+
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
+    speed_up_interrupts ();
+#endif
+
+#ifdef USE_GETADDRINFO
+    freeaddrinfo (res);
+#endif
 
     if (s < 0)
-      report_file_error ("error creating socket", list1 (name));
-
-    /* Turn off interrupts here -- see comments below.  There used to
-       be code which called bind_polling_period() to slow the polling
-       period down rather than turn it off, but that seems rather
-       bogus to me.  Best thing here is to use a non-blocking connect
-       or something, to check for QUIT. */
-
-    /* Comments that are not quite valid: */
-
-    /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
-       when connect is interrupted.  So let's not let it get interrupted.
-       Note we do not turn off polling, because polling is only used
-       when not interrupt_input, and thus not normally used on the systems
-       which have this bug.  On systems which use polling, there's no way
-       to quit if polling is turned off.  */
+      {
+	errno = xerrno;
 
-    /* Slow down polling.  Some kernels have a bug which causes retrying
-       connect to fail after a connect.  */
-
-    slow_down_interrupts ();
-
-  loop:
-
-    /* A system call interrupted with a SIGALRM or SIGIO comes back
-       here, with can_break_system_calls reset to 0. */
-    SETJMP (break_system_call_jump);
-    if (QUITP)
-      {
-	speed_up_interrupts ();
-	REALLY_QUIT;
-	/* In case something really weird happens ... */
-	slow_down_interrupts ();
+	if (failed_connect)
+	  report_file_error ("connection failed", list2 (host, name));
+	else
+	  report_file_error ("error creating socket", list1 (name));
       }
-
-    /* Break out of connect with a signal (it isn't otherwise possible).
-       Thus you don't get screwed with a hung network. */
-    can_break_system_calls = 1;
-    retval = connect (s, (struct sockaddr *) &address, sizeof (address));
-    can_break_system_calls = 0;
-    if (retval == -1 && errno != EISCONN)
-      {
-	int xerrno = errno;
-	if (errno == EINTR)
-	  goto loop;
-	if (errno == EADDRINUSE && retry < 20)
-	  {
-	    /* A delay here is needed on some FreeBSD systems,
-	       and it is harmless, since this retrying takes time anyway
-	       and should be infrequent.
-	       `sleep-for' allowed for quitting this loop with interrupts
-	       slowed down so it can't be used here.  Async timers should
-	       already be disabled at this point so we can use `sleep'. */
-	    sleep (1);
-	    retry++;
-	    goto loop;
-	  }
-
-	close (s);
-
-	speed_up_interrupts ();
-
-	errno = xerrno;
-	report_file_error ("connection failed", list2 (host, name));
-      }
-
-    speed_up_interrupts ();
-#endif /* ! HAVE_GETADDRINFO */
   }
 
   inch = s;
@@ -1913,8 +1878,8 @@
 
   set_socket_nonblocking_maybe (inch, port, "tcp");
 
-  *vinfd = (void*)inch;
-  *voutfd = (void*)outch;
+  *vinfd = (void *) inch;
+  *voutfd = (void *) outch;
 }
 
 
@@ -2015,7 +1980,9 @@
      instead of 'sendto'. Consequently, we 'connect' this socket. */
 
   /* See open-network-stream-internal for comments on this part of the code */
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
   slow_down_interrupts ();
+#endif
 
  loop:
 
@@ -2024,10 +1991,14 @@
   SETJMP (break_system_call_jump);
   if (QUITP)
     {
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
       speed_up_interrupts ();
+#endif
       REALLY_QUIT;
       /* In case something really weird happens ... */
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
       slow_down_interrupts ();
+#endif
     }
 
   /* Break out of connect with a signal (it isn't otherwise possible).
@@ -2056,13 +2027,17 @@
 
       close (rs);
       close (ws);
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
       speed_up_interrupts ();
+#endif
 
       errno = xerrno;
       report_file_error ("error connecting socket", list2(name, port));
     }
 
+#ifdef CONNECT_NEEDS_SLOWED_INTERRUPTS
   speed_up_interrupts ();
+#endif
 
   /* scope */
   if (setsockopt (ws, IPPROTO_IP, IP_MULTICAST_TTL,