Changes for Irix 4.0, tested this time:
[bpt/emacs.git] / src / sysdep.c
index c790901..8e7858f 100644 (file)
@@ -104,10 +104,14 @@ extern char *sys_errlist[];
 #endif
 #endif /* not 4.1 bsd */
 
-/* Get DGUX definition for FASYNC - DJB */
-#ifdef DGUX
-#include <sys/file.h>
-#endif /* DGUX */
+#ifdef BROKEN_FASYNC
+/* On some systems (DGUX comes to mind real fast) FASYNC causes
+   background writes to the terminal to stop all processes in the
+   process group when invoked under the csh (and probably any shell
+   with job control). This stops Emacs dead in its tracks when coming
+   up under X11. */
+#undef FASYNC
+#endif
 
 #include <sys/ioctl.h>
 #include "systty.h"
@@ -239,7 +243,7 @@ init_baud_rate ()
 
       sg.c_cflag = (sg.c_cflag & ~CBAUD) | B9600;
       tcgetattr (0, &sg);
-      ospeed = sg.c_cflag & CBAUD;
+      ospeed = cfgetospeed (&sg);
 #else /* neither VMS nor TERMIOS */
 #ifdef HAVE_TERMIO
       struct termio sg;
@@ -255,7 +259,8 @@ init_baud_rate ()
       struct sgttyb sg;
       
       sg.sg_ospeed = B9600;
-      ioctl (0, TIOCGETP, &sg);
+      if (ioctl (0, TIOCGETP, &sg) < 0)
+       abort ();
       ospeed = sg.sg_ospeed;
 #endif /* not HAVE_TERMIO */
 #endif /* not HAVE_TERMIOS */
@@ -334,11 +339,20 @@ wait_for_termination (pid)
       else
        sigpause (SIGEMPTYMASK);
 #else /* not BSD, and not HPUX version >= 6 */
-#ifdef UNIPLUS
+#if defined (UNIPLUS)
       if (0 > kill (pid, 0))
        break;
       wait (0);
 #else /* neither BSD nor UNIPLUS: random sysV */
+#ifdef POSIX_SIGNALS   /* would this work for LINUX as well? */
+      sigblock (sigmask (SIGCHLD));
+      if (0 > kill (pid, 0))
+       {
+         sigunblock (sigmask (SIGCHLD));
+         break;
+       }
+      sigpause (SIGEMPTYMASK);
+#else /* not POSIX_SIGNALS */
 #ifdef HAVE_SYSV_SIGPAUSE
       sighold (SIGCHLD);
       if (0 > kill (pid, 0))
@@ -355,6 +369,7 @@ wait_for_termination (pid)
         we lose just one second.  */
       sleep (1);
 #endif /* not HAVE_SYSV_SIGPAUSE */
+#endif /* not POSIX_SIGNALS */
 #endif /* not UNIPLUS */
 #endif /* not BSD, and not HPUX version >= 6 */
 #endif /* not VMS */
@@ -426,7 +441,7 @@ child_setup_tty (out)
   s.main.c_oflag &= ~OLCUC;    /* Disable map of lower case to upper on
                                   output */
 #if 0
-  /* Said to be unnecesary:  */
+  /* Said to be unnecessary:  */
   s.main.c_cc[VMIN] = 1;       /* minimum number of characters to accept  */
   s.main.c_cc[VTIME] = 0;      /* wait forever for at least 1 character  */
 #endif
@@ -450,11 +465,22 @@ child_setup_tty (out)
      don't ignore break, but don't signal either, so it looks like NUL.  */
   s.main.c_iflag &= ~IGNBRK;
   s.main.c_iflag &= ~BRKINT;
+  /* QUIT and INTR work better as signals, so disable character forms */
+  s.main.c_cc[VINTR] = 0377;
+#ifdef SIGNALS_VIA_CHARACTERS
+  /* the QUIT and INTR character are used in process_send_signal
+     so set them here to something useful.  */
+  if (s.main.c_cc[VQUIT] == 0377)
+    s.main.c_cc[VQUIT] = '\\'&037;     /* Control-\ */
+  if (s.main.c_cc[VINTR] == 0377)
+    s.main.c_cc[VINTR] = 'C'&037;      /* Control-C */
+#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
   /* QUIT and INTR work better as signals, so disable character forms */
   s.main.c_cc[VQUIT] = 0377;
   s.main.c_cc[VINTR] = 0377;
-  s.main.c_cc[VEOL] = 0377;
   s.main.c_lflag &= ~ISIG;
+#endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
+  s.main.c_cc[VEOL] = 0377;
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
 #endif /* AIX */
 
@@ -545,7 +571,14 @@ sys_suspend ()
 #else
 #ifdef SIGTSTP
 
-  EMACS_KILLPG (getpgrp (0), SIGTSTP);
+  {
+#ifdef USG
+    int pgrp = getpgrp ();
+#else
+    int pgrp = getpgrp (0);
+#endif
+    EMACS_KILLPG (pgrp, SIGTSTP);
+  }
 
 #else /* No SIGTSTP */
 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
@@ -670,7 +703,7 @@ reset_sigio ()
   unrequest_sigio ();
 }
 
-#ifdef FASYNC          /* F_SETFL does not imply existance of FASYNC */
+#ifdef FASYNC          /* F_SETFL does not imply existence of FASYNC */
 
 request_sigio ()
 {
@@ -725,6 +758,54 @@ unrequest_sigio ()
 #endif /* FASYNC */
 #endif /* F_SETFL */
 \f
+/* Saving and restoring the process group of Emacs's terminal.  */
+
+#ifdef BSD
+
+/* The process group of which Emacs was a member when it initially
+   started.
+
+   If Emacs was in its own process group (i.e. inherited_pgroup ==
+   getpid ()), then we know we're running under a shell with job
+   control (Emacs would never be run as part of a pipeline).
+   Everything is fine.
+
+   If Emacs was not in its own process group, then we know we're
+   running under a shell (or a caller) that doesn't know how to
+   separate itself from Emacs (like sh).  Emacs must be in its own
+   process group in order to receive SIGIO correctly.  In this
+   situation, we put ourselves in our own pgroup, forcibly set the
+   tty's pgroup to our pgroup, and make sure to restore and reinstate
+   the tty's pgroup just like any other terminal setting.  If
+   inherited_group was not the tty's pgroup, then we'll get a
+   SIGTTmumble when we try to change the tty's pgroup, and a CONT if
+   it goes foreground in the future, which is what should happen.  */
+int inherited_pgroup;
+
+/* Split off the foreground process group to Emacs alone.
+   When we are in the foreground, but not started in our own process
+   group, redirect the TTY to point to our own process group.  We need
+   to be in our own process group to receive SIGIO properly.  */
+narrow_foreground_group ()
+{
+  int me = getpid ();
+
+  setpgrp (0, inherited_pgroup);
+  if (inherited_pgroup != me)
+    EMACS_SET_TTY_PGRP (0, &me);
+  setpgrp (0, me);
+}
+
+/* Set the tty to our original foreground group.  */
+widen_foreground_group ()
+{
+  if (inherited_pgroup != getpid ())
+    EMACS_SET_TTY_PGRP (0, &inherited_pgroup);
+  setpgrp (0, inherited_pgroup);
+}
+
+#endif
+\f
 /* Getting and setting emacs_tty structures.  */
 
 /* Set *TC to the parameters associated with the terminal FD.
@@ -765,13 +846,13 @@ emacs_get_tty (fd, settings)
 #endif
 
   /* Suivant - Do we have to get struct ltchars data?  */
-#ifdef TIOCGLTC
+#ifdef HAVE_LTCHARS
   if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
     return -1;
 #endif
 
   /* How about a struct tchars and a wordful of lmode bits?  */
-#ifdef TIOCGETC
+#ifdef HAVE_TCHARS
   if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
       || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
     return -1;
@@ -795,6 +876,7 @@ emacs_set_tty (fd, settings, waitp)
 {
   /* Set the primary parameters - baud rate, character size, etcetera.  */
 #ifdef HAVE_TCATTR
+  int i;
   /* We have those nifty POSIX tcmumbleattr functions.
      William J. Smith <wjs@wiis.wang.com> writes:
      "POSIX 1003.1 defines tcsetattr() to return success if it was
@@ -802,7 +884,8 @@ emacs_set_tty (fd, settings, waitp)
      of the requested actions could not be performed.
      We must read settings back to ensure tty setup properly.
      AIX requires this to keep tty from hanging occasionally."  */
-  for (;;)
+  /* This make sure that we don't loop indefinitely in here.  */
+  for (i = 0 ; i < 10 ; i++)
     if (tcsetattr (fd, waitp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
       {
        if (errno == EINTR)
@@ -816,10 +899,18 @@ emacs_set_tty (fd, settings, waitp)
 
        /* Get the current settings, and see if they're what we asked for.  */
        tcgetattr (fd, &new);
-       if (memcmp (&new, &settings->main, sizeof (new)))
-         continue;
-       else
+       /* We cannot use memcmp on the whole structure here because under
+        * aix386 the termios structure has some reserved field that may
+        * not be filled in.
+        */
+       if (   new.c_iflag == settings->main.c_iflag
+           && new.c_oflag == settings->main.c_oflag
+           && new.c_cflag == settings->main.c_cflag
+           && new.c_lflag == settings->main.c_lflag
+           && memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
          break;
+       else
+         continue;
       }
 
 #else
@@ -846,13 +937,13 @@ emacs_set_tty (fd, settings, waitp)
 #endif
 
   /* Suivant - Do we have to get struct ltchars data?  */
-#ifdef TIOCGLTC
+#ifdef HAVE_LTCHARS
   if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
     return -1;
 #endif
 
   /* How about a struct tchars and a wordful of lmode bits?  */
-#ifdef TIOCGETC
+#ifdef HAVE_TCHARS
   if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
       || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
     return -1;
@@ -888,10 +979,10 @@ unsigned char _sobuf[BUFSIZ+8];
 char _sobuf[BUFSIZ];
 #endif
  
-#ifdef TIOCGLTC
+#ifdef HAVE_LTCHARS
 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
 #endif
-#ifdef TIOCGETC
+#ifdef HAVE_TCHARS
   static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
 #endif 
 
@@ -941,6 +1032,11 @@ init_sys_modes ()
 #endif
 #endif /* not VMS */
 
+#ifdef BSD
+  if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+    narrow_foreground_group ();
+#endif
+
   EMACS_GET_TTY (input_fd, &old_tty);
 
   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
@@ -999,6 +1095,18 @@ init_sys_modes ()
 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP.  */
       tty.main.c_cc[VDSUSP] = CDISABLE;
 #endif /* VDSUSP */
+#ifdef VLNEXT
+      tty.main.c_cc[VLNEXT] = CDISABLE;
+#endif /* VLNEXT */
+#ifdef VREPRINT
+      tty.main.c_cc[VREPRINT] = CDISABLE;
+#endif /* VREPRINT */
+#ifdef VWERASE
+      tty.main.c_cc[VWERASE] = CDISABLE;
+#endif /* VWERASE */
+#ifdef VDISCARD
+      tty.main.c_cc[VDISCARD] = CDISABLE;
+#endif /* VDISCARD */
 #endif /* mips or HAVE_TCATTR */
 #ifdef AIX
 #ifndef IBMR2AIX
@@ -1042,7 +1150,7 @@ init_sys_modes ()
         control for user coming over network on 4.2; in this case,
         only t_stopc and t_startc really matter.  */
 #ifndef HAVE_TERMIO
-#ifdef TIOCGETC
+#ifdef HAVE_TCHARS
       /* Note: if not using CBREAK mode, it makes no difference how we
         set this */
       tty.tchars = new_tchars;
@@ -1063,17 +1171,22 @@ init_sys_modes ()
 #endif
 
       tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
+#ifdef ultrix
+      /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
+        anything, and leaving it in breaks the meta key.  Go figure.  */
+      tty.lmode &= ~LLITOUT;
+#endif
       
 #ifdef BSD4_1
       lmode = tty.lmode;
 #endif
 
-#endif /* TIOCGETC */
+#endif /* HAVE_TCHARS */
 #endif /* not HAVE_TERMIO */
 
-#ifdef TIOCGLTC
+#ifdef HAVE_LTCHARS
       tty.ltchars = new_ltchars;
-#endif /* TIOCGLTC */
+#endif /* HAVE_LTCHARS */
 
       EMACS_SET_TTY (input_fd, &tty, 0);
 
@@ -1113,7 +1226,7 @@ init_sys_modes ()
     }
 
 #ifdef F_SETFL
-#ifdef F_GETOWN                /* F_SETFL does not imply existance of F_GETOWN */
+#ifdef F_GETOWN                /* F_SETFL does not imply existence of F_GETOWN */
   if (interrupt_input)
     {
       old_fcntl_owner = fcntl (0, F_GETOWN, 0);
@@ -1262,7 +1375,7 @@ reset_sys_modes ()
 #endif
 
 #ifdef F_SETFL
-#ifdef F_SETOWN                /* F_SETFL does not imply existance of F_SETOWN */
+#ifdef F_SETOWN                /* F_SETFL does not imply existence of F_SETOWN */
   if (interrupt_input)
     {
       reset_sigio ();
@@ -1281,6 +1394,10 @@ reset_sys_modes ()
 #ifdef AIX
   hft_reset ();
 #endif
+
+#ifdef BSD
+  widen_foreground_group ();
+#endif
 }
 \f
 #ifdef HAVE_PTYS
@@ -1712,6 +1829,17 @@ static struct utsname get_system_name_name;
 #endif /* not HAVE_GETHOSTNAME */
 #endif /* USG */
 
+#ifndef BSD4_1
+#ifndef USG
+#ifndef VMS
+#ifdef HAVE_SOCKETS
+#include <sys/socket.h>
+#include <netdb.h>
+#endif /* HAVE_SOCKETS */
+#endif /* not VMS */
+#endif /* not USG */
+#endif /* not BSD4_1 */
+
 char *
 get_system_name ()
 {
@@ -1742,6 +1870,20 @@ get_system_name ()
   strcpy (system_name_saved, sp);
 #else /* not VMS */
   gethostname (system_name_saved, sizeof (system_name_saved));
+#ifdef HAVE_SOCKETS
+  /* Turn the hostname into the official, fully-qualified hostname.
+     Don't do this if we're going to dump; this can confuse system
+     libraries on some machines and make the dumped emacs core dump. */
+#ifndef CANNOT_DUMP
+  if (initialized)
+#endif /* not CANNOT_DUMP */
+    {
+      struct hostent *hp;
+      hp = gethostbyname (system_name_saved);
+      if (hp && strlen (hp->h_name) < sizeof(system_name_saved))
+       strcpy (system_name_saved, hp->h_name);
+    }
+#endif /* HAVE_SOCKETS */
 #endif /* not VMS */
   return system_name_saved;
 #endif /* not USG, not 4.1 */
@@ -2088,7 +2230,7 @@ sys_signal (int signal_number, signal_handler_t action)
 #else
   sigemptyset (&new_action.sa_mask);
   new_action.sa_handler = action;
-  new_action.sa_flags = NULL;
+  new_action.sa_flags = 0;
   sigaction (signal_number, &new_action, &old_action);
   return (old_action.sa_handler);
 #endif /* DGUX */
@@ -2321,7 +2463,7 @@ sys_abort ()
 #ifdef VMS
 #ifdef LINK_CRTL_SHARE
 #ifdef SHAREABLE_LIB_BUG
-/* Variables declared noshare and initialized in shareable libraries
+/* Variables declared noshare and initialized in sharable libraries
    cannot be shared.  The VMS linker incorrectly forces you to use a private
    version which is uninitialized... If not for this "feature", we
    could use the C library definition of sys_nerr and sys_errlist. */
@@ -2442,7 +2584,7 @@ sys_write (fildes, buf, nbyte)
  *     to names for our own functions in sysdep.c that do the system call
  *     with retries.  Actually, for portability reasons, it is good
  *     programming practice, as this example shows, to limit all actual
- *     system calls to a single occurance in the source.  Sure, this
+ *     system calls to a single occurrence in the source.  Sure, this
  *     adds an extra level of function call overhead but it is almost
  *     always negligible.   Fred Fish, Unisoft Systems Inc.
  */
@@ -2508,7 +2650,7 @@ char *sys_siglist[NSIG + 1] =
 #endif /* not AIX */
   0
   };
-#endif HAVE_SYS_SIGLIST
+#endif /* HAVE_SYS_SIGLIST */
 
 /*
  *     Warning, this function may not duplicate 4.2 action properly
@@ -2679,7 +2821,8 @@ gettimeofday (tp, tzp)
 
   tp->tv_sec = time ((long *)0);    
   tp->tv_usec = 0;
-  tzp->tz_minuteswest = -1;
+  if (tzp != 0)
+    tzp->tz_minuteswest = -1;
 }
  
 #endif
@@ -2727,7 +2870,7 @@ char *sys_siglist[NSIG + 1] =
   "power-fail restart",                         /* 19 SIGPWR    */
   "window size changed",                /* 20 SIGWINCH  */
   "undefined",                          /* 21           */
-  "pollable event occured",             /* 22 SIGPOLL   */
+  "pollable event occurred",            /* 22 SIGPOLL   */
   "sendable stop signal not from tty",  /* 23 SIGSTOP   */
   "stop signal from tty",               /* 24 SIGSTP    */
   "continue a stopped process",                 /* 25 SIGCONT   */
@@ -2781,16 +2924,22 @@ char *sys_siglist[NSIG + 1] =
 
 #include <dirent.h>
 
-#ifndef AIX
+#ifndef HAVE_CLOSEDIR
 int
 closedir (dirp)
      register DIR *dirp;              /* stream from opendir */
 {
   sys_close (dirp->dd_fd);
-  xfree ((char *) dirp->dd_buf);       /* directory block defined in <dirent.h> */
+
+  /* Some systems (like Solaris) allocate the buffer and the DIR all
+     in one block.  Why in the world are we freeing this ourselves
+     anyway?  */
+#if ! (defined (sun) && defined (USG5_4))
+  xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
+#endif
   xfree ((char *) dirp);
 }
-#endif /* not AIX */
+#endif /* not HAVE_CLOSEDIR */
 #endif /* SYSV_SYSTEM_DIR */
 
 #ifdef NONSYSTEM_DIR_LIBRARY
@@ -3499,7 +3648,7 @@ creat_copy_attrs (old, new)
 sys_creat (va_alist)
      va_dcl
 {
-  va_list list_incrementor;
+  va_list list_incrementer;
   char *name;
   int mode;
   int rfd;                     /* related file descriptor */
@@ -3513,12 +3662,12 @@ sys_creat (va_alist)
   extern int vms_stmlf_recfm;
 
   va_count (count);
-  va_start (list_incrementor);
-  name = va_arg (list_incrementor, char *);
-  mode = va_arg (list_incrementor, int);
+  va_start (list_incrementer);
+  name = va_arg (list_incrementer, char *);
+  mode = va_arg (list_incrementer, int);
   if (count > 2)
-    rfd = va_arg (list_incrementor, int);
-  va_end (list_incrementor);
+    rfd = va_arg (list_incrementer, int);
+  va_end (list_incrementer);
   if (count > 2)
     {
       /* Use information from the related file descriptor to set record
@@ -4027,7 +4176,7 @@ rename (from, to)
    are renaming.
 
    We could use the chmod function, but Eunichs uses 3 bits per user category
-   to describe the protection, and VMS uses 4 (write and delete are seperate
+   to describe the protection, and VMS uses 4 (write and delete are separate
    bits).  To maintain portability, the VMS implementation of `chmod' wires
    the W and D bits together.  */