]> code.delx.au - gnu-emacs/blobdiff - src/sysdep.c
(BSD_PGRPS): Defined.
[gnu-emacs] / src / sysdep.c
index 23376cb9bce3f7a4bf2f86c192bf537a6736c938..828ec00f619bdfe0785657b80b7bfcfaa4da20f6 100644 (file)
@@ -59,6 +59,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #undef fwrite
 #endif
 
+#ifndef HAVE_H_ERRNO
+extern int h_errno;
+#endif
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -125,6 +129,7 @@ extern int errno;
 
 #ifdef BROKEN_TIOCGWINSZ
 #undef TIOCGWINSZ
+#undef TIOCSWINSZ
 #endif
 
 #ifdef USG
@@ -133,7 +138,7 @@ extern int errno;
 #ifndef MEMORY_IN_STRING_H
 #include <memory.h>
 #endif
-#ifdef TIOCGWINSZ
+#if defined (TIOCGWINSZ) || defined (ISC4_0)
 #ifdef NEED_SIOCTL
 #include <sys/sioctl.h>
 #endif
@@ -141,7 +146,7 @@ extern int errno;
 #include <sys/stream.h>
 #include <sys/ptem.h>
 #endif
-#endif /* TIOCGWINSZ */
+#endif /* TIOCGWINSZ or ISC4_0 */
 #endif /* USG */
 
 extern int quit_char;
@@ -464,14 +469,18 @@ child_setup_tty (out)
 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
   s.main.c_oflag |= OPOST;     /* Enable output postprocessing */
   s.main.c_oflag &= ~ONLCR;    /* Disable map of NL to CR-NL on output */
+#ifdef NLDLY
   s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
                                /* No output delays */
+#endif
   s.main.c_lflag &= ~ECHO;     /* Disable echo */
   s.main.c_lflag |= ISIG;      /* Enable signals */
-  s.main.c_iflag &= ~IUCLC;    /* Disable map of upper case to lower on
-                                  input */
-  s.main.c_oflag &= ~OLCUC;    /* Disable map of lower case to upper on
-                                  output */
+#ifdef IUCLC
+  s.main.c_iflag &= ~IUCLC;    /* Disable downcasing on input.  */
+#endif
+#ifdef OLCUC
+  s.main.c_oflag &= ~OLCUC;    /* Disable upcasing on output.  */
+#endif
   s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
 #if 0
   /* Said to be unnecessary:  */
@@ -564,10 +573,6 @@ struct save_signal
 
 sys_suspend ()
 {
-#ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida */
-  int st;
-  char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
-#endif
 #ifdef VMS
   /* "Foster" parentage allows emacs to return to a subprocess that attached
      to the current emacs as a cheaper than starting a whole new process.  This
@@ -626,8 +631,27 @@ sys_suspend ()
 /* On a system where suspending is not implemented,
    instead fork a subshell and let it talk directly to the terminal
    while we wait.  */
-  int pid = fork ();
+  sys_subshell ();
+
+#endif /* no USG_JOBCTRL */
+#endif /* no SIGTSTP */
+#endif /* not VMS */
+}
+
+/* Fork a subshell.  */
+
+sys_subshell ()
+{
+#ifndef VMS
+#ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida */
+  int st;
+  char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
+#endif
+  int pid;
   struct save_signal saved_handlers[5];
+  Lisp_Object dir;
+  unsigned char *str = 0;
+  int len;
 
   saved_handlers[0].code = SIGINT;
   saved_handlers[1].code = SIGQUIT;
@@ -639,6 +663,27 @@ sys_suspend ()
   saved_handlers[3].code = 0;
 #endif
 
+  /* Mentioning current_buffer->buffer would mean including buffer.h,
+     which somehow wedges the hp compiler.  So instead...  */
+
+  dir = intern ("default-directory");
+  /* Can't use NILP */
+  if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil))
+    goto xyzzy;
+  dir = Fsymbol_value (dir);
+  if (XTYPE (dir) != Lisp_String)
+    goto xyzzy;
+
+  dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
+  str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
+  len = XSTRING (dir)->size;
+  bcopy (XSTRING (dir)->data, str, len);
+  if (str[len - 1] != '/') str[len++] = '/';
+  str[len] = 0;
+ xyzzy:
+
+  pid = vfork ();
+
   if (pid == -1)
     error ("Can't spawn subshell");
   if (pid == 0)
@@ -653,39 +698,18 @@ sys_suspend ()
        sh = "sh";
 
       /* Use our buffer's default directory for the subshell.  */
-      {
-       Lisp_Object dir;
-       unsigned char *str;
-       int len;
-
-       /* mentioning current_buffer->buffer would mean including buffer.h,
-          which somehow wedges the hp compiler.  So instead... */
-
-       dir = intern ("default-directory");
-       /* Can't use NILP */
-       if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil))
-         goto xyzzy;
-       dir = Fsymbol_value (dir);
-       if (XTYPE (dir) != Lisp_String)
-         goto xyzzy;
-
-       str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
-       len = XSTRING (dir)->size;
-       bcopy (XSTRING (dir)->data, str, len);
-       if (str[len - 1] != '/') str[len++] = '/';
-       str[len] = 0;
+      if (str)
        chdir (str);
-      }
-    xyzzy:
+
 #ifdef subprocesses
       close_process_descs ();  /* Close Emacs's pipes/ptys */
 #endif
 
-#ifdef PRIO_PROCESS
+#ifdef SET_EMACS_PRIORITY
       {
        extern int emacs_priority;
 
-       if (emacs_priority)
+       if (emacs_priority < 0)
          nice (-emacs_priority);
       }
 #endif
@@ -706,10 +730,7 @@ sys_suspend ()
   synch_process_alive = 1;
   wait_for_termination (pid);
   restore_signal_handlers (saved_handlers);
-
-#endif /* no USG_JOBCTRL */
-#endif /* no SIGTSTP */
-#endif /* not VMS */
+#endif /* !VMS */
 }
 
 save_signal_handlers (saved_handlers)
@@ -791,6 +812,32 @@ unrequest_sigio ()
 
 #else /* not FASYNC, not STRIDE */
  
+#ifdef _CX_UX
+
+#include <termios.h>
+
+request_sigio ()
+{
+  int on = 1;
+  sigset_t st;
+
+  sigemptyset(&st);
+  sigaddset(&st, SIGIO);
+  ioctl (input_fd, FIOASYNC, &on);
+  interrupts_deferred = 0;
+  sigprocmask(SIG_UNBLOCK, &st, (sigset_t *)0);
+}
+
+unrequest_sigio ()
+{
+  int off = 0;
+
+  ioctl (input_fd, FIOASYNC, &off);
+  interrupts_deferred = 1;
+}
+
+#else /* ! _CX_UX */
+
 request_sigio ()
 {
   croak ("request_sigio");
@@ -801,13 +848,14 @@ unrequest_sigio ()
   croak ("unrequest_sigio");
 }
  
+#endif /* _CX_UX */
 #endif /* STRIDE */
 #endif /* FASYNC */
 #endif /* F_SETFL */
 \f
 /* Saving and restoring the process group of Emacs's terminal.  */
 
-#ifdef BSD
+#ifdef BSD_PGRPS
 
 /* The process group of which Emacs was a member when it initially
    started.
@@ -851,7 +899,7 @@ widen_foreground_group ()
   setpgrp (0, inherited_pgroup);
 }
 
-#endif
+#endif /* BSD_PGRPS */
 \f
 /* Getting and setting emacs_tty structures.  */
 
@@ -1084,7 +1132,7 @@ init_sys_modes ()
 #endif
 #endif /* not VMS */
 
-#ifdef BSD
+#ifdef BSD_PGRPS
   if (! read_socket_hook && EQ (Vwindow_system, Qnil))
     narrow_foreground_group ();
 #endif
@@ -1096,6 +1144,10 @@ init_sys_modes ()
       tty = old_tty;
 
 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
+#ifdef DGUX
+      /* This allows meta to be sent on 8th bit.  */
+      tty.main.c_iflag &= ~INPCK;      /* don't check input for parity */
+#endif
       tty.main.c_iflag |= (IGNBRK);    /* Ignore break condition */
       tty.main.c_iflag &= ~ICRNL;      /* Disable map of CR to NL on input */
 #ifdef ISTRIP
@@ -1104,7 +1156,7 @@ init_sys_modes ()
       tty.main.c_lflag &= ~ECHO;       /* Disable echo */
       tty.main.c_lflag &= ~ICANON;     /* Disable erase/kill processing */
 #ifdef IEXTEN
-      tty.main.c_iflag &= ~IEXTEN;     /* Disable other editing characters.  */
+      tty.main.c_lflag &= ~IEXTEN;     /* Disable other editing characters.  */
 #endif
       tty.main.c_lflag |= ISIG;        /* Enable signals */
       if (flow_control)
@@ -1159,6 +1211,12 @@ init_sys_modes ()
 #ifdef VDISCARD
       tty.main.c_cc[VDISCARD] = CDISABLE;
 #endif /* VDISCARD */
+#ifdef VSTART
+      tty.main.c_cc[VSTART] = CDISABLE;
+#endif /* VSTART */
+#ifdef VSTOP
+      tty.main.c_cc[VSTOP] = CDISABLE;
+#endif /* VSTOP */
 #endif /* mips or HAVE_TCATTR */
 #ifdef AIX
 #ifndef IBMR2AIX
@@ -1277,7 +1335,8 @@ init_sys_modes ()
 #ifdef F_SETFL
 #ifndef F_SETOWN_BUG
 #ifdef F_GETOWN                /* F_SETFL does not imply existence of F_GETOWN */
-  if (interrupt_input)
+  if (interrupt_input
+      && ! read_socket_hook && EQ (Vwindow_system, Qnil))
     {
       old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
       fcntl (input_fd, F_SETOWN, getpid ());
@@ -1303,7 +1362,9 @@ init_sys_modes ()
 #else
   setbuf (stdout, _sobuf);
 #endif
-  set_terminal_modes ();
+  if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+    set_terminal_modes ();
+
   if (term_initted && no_redraw_on_reenter)
     {
       if (display_completed)
@@ -1331,10 +1392,10 @@ tabs_safe_p ()
   EMACS_GET_TTY (input_fd, &tty);
   return EMACS_TTY_TABS_OK (&tty);
 }
-
+\f
 /* Get terminal size from system.
-   Store number of lines into *heightp and width into *widthp.
-   If zero or a negative number is stored, the value is not valid.  */
+   Store number of lines into *HEIGHTP and width into *WIDTHP.
+   We store 0 if there's no valid information.  */
 
 get_frame_size (widthp, heightp)
      int *widthp, *heightp;
@@ -1391,6 +1452,43 @@ get_frame_size (widthp, heightp)
 #endif /* not BSD-style */
 }
 
+/* Set the logical window size associated with descriptor FD
+   to HEIGHT and WIDTH.  This is used mainly with ptys.  */
+
+int
+set_window_size (fd, height, width)
+     int fd, height, width;
+{
+#ifdef TIOCSWINSZ
+
+  /* BSD-style.  */
+  struct winsize size;
+  size.ws_row = height;
+  size.ws_col = width;
+
+  if (ioctl (fd, TIOCSWINSZ, &size) == -1)
+    return 0; /* error */
+  else
+    return 1;
+
+#else
+#ifdef TIOCSSIZE
+
+  /* SunOS - style.  */
+  struct ttysize size;  
+  size.ts_lines = height;
+  size.ts_cols = width;
+
+  if (ioctl (fd, TIOCGSIZE, &size) == -1)
+    return 0;
+  else
+    return 1;
+#else
+  return -1;
+#endif /* not SunOS-style */
+#endif /* not BSD-style */
+}
+
 \f
 /* Prepare the terminal for exiting Emacs; move the cursor to the
    bottom of the frame, turn off interrupt-driven I/O, etc.  */
@@ -1439,6 +1537,9 @@ reset_sys_modes ()
     }
 #endif /* F_SETOWN */
 #endif /* F_SETOWN_BUG */
+#ifdef O_NDELAY
+  fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
+#endif
 #endif /* F_SETFL */
 #ifdef BSD4_1
   if (interrupt_input)
@@ -1456,7 +1557,7 @@ reset_sys_modes ()
   hft_reset ();
 #endif
 
-#ifdef BSD
+#ifdef BSD_PGRPS
   widen_foreground_group ();
 #endif
 }
@@ -1769,7 +1870,7 @@ unrequest_sigio ()
  *
  */
 
-#ifndef CANNOT_UNEXEC
+#if !defined (CANNOT_UNEXEC) && !defined (HAVE_TEXT_START)
 char *
 start_of_text ()
 {
@@ -1785,7 +1886,7 @@ start_of_text ()
 #endif /* GOULD */
 #endif /* TEXT_START */
 }
-#endif /* not CANNOT_UNEXEC */
+#endif /* not CANNOT_UNEXEC and not HAVE_TEXT_START */
 
 /*
  *     Return the address of the start of the data segment prior to
@@ -1874,64 +1975,63 @@ end_of_data ()
 
 #endif /* not CANNOT_DUMP */
 \f
-/* Get_system_name returns as its value
a string for the Lisp function system-name to return. */
+/* init_system_name sets up the string for the Lisp function
  system-name to return. */
 
 #ifdef BSD4_1
 #include <whoami.h>
 #endif
 
-/* Can't have this within the function since `static' is #defined to 
-   nothing for some USG systems.  */
-#ifdef USG
-#ifdef HAVE_GETHOSTNAME
-static char get_system_name_name[256];
-#else /* not HAVE_GETHOSTNAME */
-static struct utsname get_system_name_name;
-#endif /* not HAVE_GETHOSTNAME */
-#endif /* USG */
+extern Lisp_Object Vsystem_name;
 
 #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 ()
+void
+init_system_name ()
 {
-#ifdef USG
-#ifdef HAVE_GETHOSTNAME
-  gethostname (get_system_name_name, sizeof (get_system_name_name));
-  return get_system_name_name;
-#else /* not HAVE_GETHOSTNAME */
-  uname (&get_system_name_name);
-  return (get_system_name_name.nodename);
-#endif /* not HAVE_GETHOSTNAME */
-#else /* Not USG */
 #ifdef BSD4_1
-  return sysname;
-#else /* not USG, not 4.1 */
-  static char system_name_saved[32];
+  Vsystem_name = build_string (sysname);
+#else
 #ifdef VMS
-  char *sp;
+  char *sp, *end;
   if ((sp = egetenv ("SYS$NODE")) == 0)
-    sp = "vax-vms";
+    Vsystem_name = build_string ("vax-vms");
+  else if ((end = index (sp, ':')) == 0)
+    Vsystem_name = build_string (sp);
   else
+    Vsystem_name = make_string (sp, end - sp);
+#else
+#ifndef HAVE_GETHOSTNAME
+  struct utsname uts;
+  uname (&uts);
+  Vsystem_name = build_string (uts.nodename);
+#else /* HAVE_GETHOSTNAME */
+  int hostname_size = 256;
+  char *hostname = (char *) alloca (hostname_size);
+
+  /* Try to get the host name; if the buffer is too short, try
+     again.  Apparently, the only indication gethostname gives of
+     whether the buffer was large enough is the presence or absence
+     of a '\0' in the string.  Eech.  */
+  for (;;)
     {
-      char *end;
+      gethostname (hostname, hostname_size - 1);
+      hostname[hostname_size - 1] = '\0';
 
-      if ((end = index (sp, ':')) != 0)
-       *end = '\0';
+      /* Was the buffer large enough for the '\0'?  */
+      if (strlen (hostname) < hostname_size - 1)
+       break;
+
+      hostname_size <<= 1;
+      hostname = (char *) alloca (hostname_size);
     }
-  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
@@ -1941,45 +2041,61 @@ get_system_name ()
 #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);
-      if (hp && !index (system_name_saved, '.'))
+      int count;
+      for (count = 0; count < 10; count++)
+       {
+#ifdef TRY_AGAIN
+         h_errno = 0;
+#endif
+         hp = gethostbyname (hostname);
+#ifdef TRY_AGAIN
+         if (! (hp == 0 && h_errno == TRY_AGAIN))
+#endif
+           break;
+         Fsleep_for (make_number (1), Qnil);
+       }
+      if (hp)
        {
-         /* We still don't have a fully qualified domain name.
-            Try to find one in the list of alternate names */
-         char **alias = hp->h_aliases;
-         while (*alias && !index (*alias, '.'))
-           alias++;
-         if (*alias && strlen (*alias) < sizeof (system_name_saved))
-           strcpy (system_name_saved, *alias);
+         char *fqdn = hp->h_name;
+         char *p;
+
+         if (!index (fqdn, '.'))
+           {
+             /* We still don't have a fully qualified domain name.
+                Try to find one in the list of alternate names */
+             char **alias = hp->h_aliases;
+             while (*alias && !index (*alias, '.'))
+               alias++;
+             if (*alias)
+               fqdn = *alias;
+           }
+         hostname = fqdn;
+#if 0
+         /* Convert the host name to lower case.  */
+         /* Using ctype.h here would introduce a possible locale
+            dependence that is probably wrong for hostnames.  */
+         p = hostname;
+         while (*p)
+           {
+             if (*p >= 'A' && *p <= 'Z')
+               *p += 'a' - 'A';
+             p++;
+           }
+#endif
        }
     }
 #endif /* HAVE_SOCKETS */
-#endif /* not VMS */
-  return system_name_saved;
-#endif /* not USG, not 4.1 */
-#endif /* not USG */
-}
-
-#ifdef VMS
-#ifndef HAVE_GETHOSTNAME
-void gethostname(buf, len)
-    char *buf;
-    int len;
-{
-    char *s;
-    s = getenv ("SYS$NODE");
-    if (s == NULL)
-        buf[0] = '\0';
-    else {
-        strncpy (buf, s, len - 2);
-        buf[len - 1] = '\0';
-    } /* else */
-} /* static void gethostname */
-#endif /* ! HAVE_GETHOSTNAME */
+  Vsystem_name = build_string (hostname);
+#endif /* HAVE_GETHOSTNAME */
 #endif /* VMS */
-
+#endif /* BSD4_1 */
+  {
+    unsigned char *p;
+    for (p = XSTRING (Vsystem_name)->data; *p; p++)
+      if (*p == ' ' || *p == '\t')
+       *p = '-';
+  }
+}
 \f
 #ifndef VMS
 #ifndef HAVE_SELECT
@@ -2337,7 +2453,14 @@ sys_signal (int signal_number, signal_handler_t action)
 #else
   sigemptyset (&new_action.sa_mask);
   new_action.sa_handler = action;
+#ifdef SA_RESTART
+  /* Emacs mostly works better with restartable system services. If this
+   * flag exists, we probably want to turn it on here.
+   */
+  new_action.sa_flags = SA_RESTART;
+#else
   new_action.sa_flags = 0;
+#endif
   sigaction (signal_number, &new_action, &old_action);
   return (old_action.sa_handler);
 #endif /* DGUX */
@@ -2708,7 +2831,7 @@ sys_write (fildes, buf, nbyte)
          if (errno == EINTR)
            continue;
          else
-           return (-1);
+           return (bytes_written ? bytes_written : -1);
        }
 
       buf += rtnval;
@@ -2822,8 +2945,12 @@ char *sys_siglist[NSIG + 1] =
   "exceeded file size limit",              /* 31 SIGXFSZ */
   "process's lwps are blocked",            /*  32 SIGWAITING */
   "special signal used by thread library", /* 33 SIGLWP */
+#ifdef SIGFREEZE
   "Special Signal Used By CPR",            /* 34 SIGFREEZE */
+#endif
+#ifdef SIGTHAW
   "Special Signal Used By CPR",            /* 35 SIGTHAW */
+#endif
 #endif /* sun */
 #endif /* not AIX */
   0
@@ -3280,10 +3407,14 @@ readdirver (dirp)
 /*
  * Make a directory.
  */
+#ifdef MKDIR_PROTOTYPE
+MKDIR_PROTOTYPE
+#else
 int
 mkdir (dpath, dmode)
      char *dpath;
      int dmode;
+#endif
 {
   int cpid, status, fd;
   struct stat statbuf;