(child_setup_tty): Use CDISABLE for setting VERASE, VKILL.
[bpt/emacs.git] / src / sysdep.c
index cbf928e..7c8a072 100644 (file)
@@ -40,6 +40,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #undef read
 #undef write
 
+#ifdef WINDOWSNT
+#define read _read
+#define write _write
+#include <windows.h>
+extern int errno;
+#endif /* not WINDOWSNT */
+
 #ifndef close
 #define sys_close close
 #else 
@@ -59,6 +66,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>
@@ -93,7 +104,7 @@ extern int errno;
 #ifndef RAB$C_BID
 #include <rab.h>
 #endif
-#define        MAXIOSIZE ( 32 * PAGESIZE )     /* Don't I/O more than 32 blocks at a time */
+#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
 #endif /* VMS */
 
 #ifndef BSD4_1
@@ -108,15 +119,6 @@ extern int errno;
 #endif
 #endif /* not 4.1 bsd */
 
-#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
-
 #ifndef MSDOS
 #include <sys/ioctl.h>
 #endif
@@ -125,6 +127,7 @@ extern int errno;
 
 #ifdef BROKEN_TIOCGWINSZ
 #undef TIOCGWINSZ
+#undef TIOCSWINSZ
 #endif
 
 #ifdef USG
@@ -154,12 +157,34 @@ extern int quit_char;
 #include "dispextern.h"
 #include "process.h"
 
+#ifdef WINDOWSNT
+#include <direct.h>
+/* In process.h which conflicts with the local copy.  */
+#define _P_WAIT 0
+int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
+int _CRTAPI1 _getpid (void);
+#endif
+
 #ifdef NONSYSTEM_DIR_LIBRARY
 #include "ndir.h"
 #endif /* NONSYSTEM_DIR_LIBRARY */
 
 #include "syssignal.h"
 #include "systime.h"
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifndef HAVE_UTIMES
+#ifndef HAVE_STRUCT_UTIMBUF
+/* We want to use utime rather than utimes, but we couldn't find the
+   structure declaration.  We'll use the traditional one.  */
+struct utimbuf {
+  long actime;
+  long modtime;
+};
+#endif
+#endif
 
 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
 #ifndef LPASS8
@@ -183,10 +208,9 @@ static int baud_convert[] =
 extern short ospeed;
 
 /* The file descriptor for Emacs's input terminal.
-   Under Unix, this is normaly zero except when using X;
-   under VMS, we place the input channel number here.
-   This allows us to write more code that works for both VMS and Unix.  */
-static int input_fd;
+   Under Unix, this is normally zero except when using X;
+   under VMS, we place the input channel number here.  */
+int input_fd;
 \f
 /* Specify a different file descriptor for further input operations.  */
 
@@ -201,6 +225,7 @@ change_input_fd (fd)
 
 discard_tty_input ()
 {
+#ifndef WINDOWSNT
   struct emacs_tty buf;
 
   if (noninteractive)
@@ -223,15 +248,16 @@ discard_tty_input ()
     ioctl (input_fd, TIOCFLUSH, &zero);
   }
 #else /* not Apollo */
-#ifdef MSDOS   /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
+#ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
   while (dos_keyread () != -1)
-       ;
+    ;
 #else /* not MSDOS */
   EMACS_GET_TTY (input_fd, &buf);
   EMACS_SET_TTY (input_fd, &buf, 0);
 #endif /* not MSDOS */
 #endif /* not Apollo */
 #endif /* not VMS */
+#endif /* not WINDOWSNT */
 }
 
 #ifdef SIGTSTP
@@ -242,6 +268,9 @@ discard_tty_input ()
 stuff_char (c)
      char c;
 {
+  if (read_socket_hook)
+    return;
+
 /* Should perhaps error if in batch mode */
 #ifdef TIOCSTI
   ioctl (input_fd, TIOCSTI, &c);
@@ -258,9 +287,9 @@ init_baud_rate ()
     ospeed = 0;
   else
     {
-#ifdef MSDOS
+#ifdef DOS_NT
     ospeed = 15;
-#else
+#else  /* not DOS_NT */
 #ifdef VMS
       struct sensemode sg;
 
@@ -274,6 +303,11 @@ init_baud_rate ()
       sg.c_cflag = B9600;
       tcgetattr (input_fd, &sg);
       ospeed = cfgetospeed (&sg);
+#if defined (USE_GETOBAUD) && defined (getobaud)
+      /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
+      if (ospeed == 0)
+        ospeed = getobaud (sg.c_cflag);
+#endif
 #else /* neither VMS nor TERMIOS */
 #ifdef HAVE_TERMIO
       struct termio sg;
@@ -295,11 +329,11 @@ init_baud_rate ()
 #endif /* not HAVE_TERMIO */
 #endif /* not HAVE_TERMIOS */
 #endif /* not VMS */
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
     }
    
   baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0]
-              ? baud_convert[ospeed] : 9600);
+              ? baud_convert[ospeed] : 9600);
   if (baud_rate == 0)
     baud_rate = 1200;
 }
@@ -329,7 +363,7 @@ wait_without_blocking ()
 #endif /* not subprocesses */
 
 int wait_debugging;   /* Set nonzero to make following function work under dbx
-                        (at least for bsd).  */
+                        (at least for bsd).  */
 
 SIGTYPE
 wait_for_termination_signal ()
@@ -360,7 +394,7 @@ wait_for_termination (pid)
         if that causes the problem to go away or get worse.  */
       sigsetmask (sigmask (SIGCHLD));
       if (0 > kill (pid, 0))
-        {
+       {
          sigsetmask (SIGEMPTYMASK);
          kill (getpid (), SIGCHLD);
          break;
@@ -375,7 +409,7 @@ wait_for_termination (pid)
        break;
       wait (0);
 #else /* neither BSD nor UNIPLUS: random sysV */
-#ifdef POSIX_SIGNALS   /* would this work for LINUX as well? */
+#ifdef POSIX_SIGNALS    /* would this work for LINUX as well? */
       sigblock (sigmask (SIGCHLD));
       if (0 > kill (pid, 0))
        {
@@ -393,12 +427,17 @@ wait_for_termination (pid)
        }
       sigpause (SIGCHLD);
 #else /* not HAVE_SYSV_SIGPAUSE */
+#ifdef WINDOWSNT
+      wait (0);
+      break;
+#else /* not WINDOWSNT */
       if (0 > kill (pid, 0))
        break;
       /* Using sleep instead of pause avoids timing error.
         If the inferior dies just before the sleep,
         we lose just one second.  */
       sleep (1);
+#endif /* not WINDOWSNT */
 #endif /* not HAVE_SYSV_SIGPAUSE */
 #endif /* not POSIX_SIGNALS */
 #endif /* not UNIPLUS */
@@ -456,7 +495,7 @@ flush_pending_output (channel)
 child_setup_tty (out)
      int out;
 {
-#ifndef MSDOS
+#ifndef DOS_NT
   struct emacs_tty s;
 
   EMACS_GET_TTY (out, &s);
@@ -485,8 +524,8 @@ child_setup_tty (out)
 
   s.main.c_lflag |= ICANON;    /* Enable erase/kill and eof processing */
   s.main.c_cc[VEOF] = 04;      /* insure that EOF is Control-D */
-  s.main.c_cc[VERASE] = 0377;  /* disable erase processing */
-  s.main.c_cc[VKILL] = 0377;   /* disable kill processing */
+  s.main.c_cc[VERASE] = CDISABLE;      /* disable erase processing */
+  s.main.c_cc[VKILL] = CDISABLE;       /* disable kill processing */
 
 #ifdef HPUX
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
@@ -544,18 +583,11 @@ child_setup_tty (out)
     ioctl (out, FIOASYNC, &zero);
   }
 #endif /* RTU */
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
 }
 #endif /* not VMS */
 
 #endif /* subprocesses */
-
-/*ARGSUSED*/
-setpgrp_of_tty (pid)
-     int pid;
-{
-  EMACS_SET_TTY_PGRP (input_fd, &pid);
-}
 \f
 /* Record a signal code and the handler for it.  */
 struct save_signal
@@ -642,8 +674,11 @@ sys_subshell ()
   int st;
   char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
 #endif
-  int pid = fork ();
+  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;
@@ -655,13 +690,37 @@ sys_subshell ()
   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");
+  if (NILP (Fboundp (dir)))
+    goto xyzzy;
+  dir = Fsymbol_value (dir);
+  if (!STRINGP (dir))
+    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:
+
+#ifdef WINDOWSNT
+  pid = -1;
+#else /* not WINDOWSNT */
+  pid = vfork ();
+
   if (pid == -1)
     error ("Can't spawn subshell");
   if (pid == 0)
+#endif /* not WINDOWSNT */
     {
       char *sh;
 
-#ifdef MSDOS   /* MW, Aug 1993 */
+#ifdef MSDOS    /* MW, Aug 1993 */
       getwd (oldwd);
 #endif
       sh = (char *) egetenv ("SHELL");
@@ -669,30 +728,9 @@ sys_subshell ()
        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
@@ -706,15 +744,26 @@ sys_subshell ()
       }
 #endif
 
-#ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida */
+#ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
       st = system (sh);
       chdir (oldwd);
       if (st)
-        report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
+       report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
 #else /* not MSDOS */
+#ifdef  WINDOWSNT
+      restore_console ();
+
+      /* Waits for process completion */
+      pid = _spawnlp (_P_WAIT, sh, sh, NULL);
+      if (pid == -1)
+       write (1, "Can't execute subshell", 22);
+
+      take_console ();
+#else   /* not WINDOWSNT */
       execlp (sh, sh, 0);
       write (1, "Can't execute subshell", 22);
       _exit (1);
+#endif  /* not WINDOWSNT */
 #endif /* not MSDOS */
     }
 
@@ -750,12 +799,14 @@ restore_signal_handlers (saved_handlers)
 
 int old_fcntl_flags;
 
-init_sigio ()
+init_sigio (fd)
+     int fd;
 {
 #ifdef FASYNC
-  old_fcntl_flags = fcntl (input_fd, F_GETFL, 0) & ~FASYNC;
+  old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
+  fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
 #endif
-  request_sigio ();
+  interrupts_deferred = 0;
 }
 
 reset_sigio ()
@@ -767,6 +818,9 @@ reset_sigio ()
 
 request_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
 #ifdef SIGWINCH
   sigunblock (sigmask (SIGWINCH));
 #endif
@@ -777,6 +831,9 @@ request_sigio ()
 
 unrequest_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
 #ifdef SIGWINCH
   sigblock (sigmask (SIGWINCH));
 #endif
@@ -790,6 +847,10 @@ unrequest_sigio ()
 request_sigio ()
 {
   int on = 1;
+
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &on);
   interrupts_deferred = 0;
 }
@@ -798,6 +859,9 @@ unrequest_sigio ()
 {
   int off = 0;
 
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &off);
   interrupts_deferred = 1;
 }
@@ -813,6 +877,9 @@ request_sigio ()
   int on = 1;
   sigset_t st;
 
+  if (read_socket_hook)
+    return;
+
   sigemptyset(&st);
   sigaddset(&st, SIGIO);
   ioctl (input_fd, FIOASYNC, &on);
@@ -824,6 +891,9 @@ unrequest_sigio ()
 {
   int off = 0;
 
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &off);
   interrupts_deferred = 1;
 }
@@ -832,11 +902,17 @@ unrequest_sigio ()
 
 request_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
   croak ("request_sigio");
 }
  
 unrequest_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
   croak ("unrequest_sigio");
 }
  
@@ -924,11 +1000,11 @@ emacs_get_tty (fd, settings)
     return -1;
 
 #else
-#ifndef MSDOS
+#ifndef DOS_NT
   /* I give up - I hope you have the BSD ioctls.  */
   if (ioctl (fd, TIOCGETP, &settings->main) < 0)
     return -1;
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
 #endif
 #endif
 #endif
@@ -1016,11 +1092,11 @@ emacs_set_tty (fd, settings, waitp)
     return -1;
 
 #else
-#ifndef MSDOS
+#ifndef DOS_NT
   /* I give up - I hope you have the BSD ioctls.  */
   if (ioctl (fd, (waitp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
     return -1;
-#endif /* not MSDOS */
+#endif /* not DOS_NT */
 
 #endif
 #endif
@@ -1129,13 +1205,21 @@ init_sys_modes ()
     narrow_foreground_group ();
 #endif
 
-  EMACS_GET_TTY (input_fd, &old_tty);
-
+#ifdef HAVE_X_WINDOWS
+  /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
+     needs the initialization code below.  */
   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
+#endif
     {
+      EMACS_GET_TTY (input_fd, &old_tty);
+
       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
@@ -1199,10 +1283,21 @@ 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 SET_LINE_DISCIPLINE
+      /* Need to explicitely request TERMIODISC line discipline or
+         Ultrix's termios does not work correctly.  */
+      tty.main.c_line = SET_LINE_DISCIPLINE;
+#endif
 #ifdef AIX
 #ifndef IBMR2AIX
-      /* AIX enhanced edit loses NULs, so disable it */
+      /* AIX enhanced edit loses NULs, so disable it */
       tty.main.c_line = 0;
       tty.main.c_iflag &= ~ASCEDIT;
 #else
@@ -1229,12 +1324,12 @@ init_sys_modes ()
        tty.main.tt_char &= ~TT$M_TTSYNC;
       tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
 #else /* not VMS (BSD, that is) */
-#ifndef MSDOS
+#ifndef DOS_NT
       tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
       if (meta_key)
        tty.main.sg_flags |= ANYP;
       tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
-#endif
+#endif /* not DOS_NT */
 #endif /* not VMS (BSD, that is) */
 #endif /* not HAVE_TERMIO */
 
@@ -1273,7 +1368,8 @@ init_sys_modes ()
       tty.ltchars = new_ltchars;
 #endif /* HAVE_LTCHARS */
 #ifdef MSDOS   /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
-      internal_terminal_init ();
+      if (!term_initted)
+       internal_terminal_init ();
       dos_ttraw ();
 #endif
 
@@ -1291,7 +1387,11 @@ init_sys_modes ()
 #endif
 #endif
 
-#ifdef AIX
+#if defined (HAVE_TERMIOS) || defined (HPUX9)
+      if (!flow_control) tcflow (input_fd, TCOON);
+#endif
+
+#ifdef AIXHFT
       hft_init ();
 #ifdef IBMR2AIX
       {
@@ -1303,7 +1403,7 @@ init_sys_modes ()
          write (1, "\033[20l", 5);
       }
 #endif
-#endif
+#endif /* AIXHFT */
 
 #ifdef VMS
 /*  Appears to do nothing when in PASTHRU mode.
@@ -1317,11 +1417,12 @@ 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 ());
-      init_sigio ();
+      init_sigio (input_fd);
     }
 #endif /* F_GETOWN */
 #endif /* F_SETOWN_BUG */
@@ -1329,7 +1430,7 @@ init_sys_modes ()
 
 #ifdef BSD4_1
   if (interrupt_input)
-    init_sigio ();
+    init_sigio (input_fd);
 #endif
 
 #ifdef VMS  /* VMS sometimes has this symbol but lacks setvbuf.  */
@@ -1343,7 +1444,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)
@@ -1480,13 +1583,26 @@ reset_sys_modes ()
     }
   if (!term_initted)
     return;
+#ifdef HAVE_X_WINDOWS
+  /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
+     needs the clean-up code below.  */
   if (read_socket_hook || !EQ (Vwindow_system, Qnil))
     return;
+#endif
   cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
+#ifdef MSDOS
+  if (!EQ (Vwindow_system, Qnil))
+    {
+      /* Change to grey on white.  */
+      putchar ('\e');
+      putchar ('A');
+      putchar (7);
+    }
+#endif
   clear_end_of_line (FRAME_WIDTH (selected_frame));
   /* clear_end_of_line may move the cursor */
   cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
-#ifdef IBMR2AIX
+#if defined (IBMR2AIX) && defined (AIXHFT)
   {
     /* HFT devices normally use ^J as a LF/CR.  We forced it to 
        do the LF only.  Now, we need to reset it. */
@@ -1532,7 +1648,14 @@ reset_sys_modes ()
   dos_ttcooked ();
 #endif
 
-#ifdef AIX
+#ifdef SET_LINE_DISCIPLINE
+  /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
+     A different old line discipline is therefore not restored, yet.
+     Restore the old line discipline by hand.  */
+  ioctl (0, TIOCSETD, &old_tty.main.c_line);
+#endif
+
+#ifdef AIXHFT
   hft_reset ();
 #endif
 
@@ -1673,12 +1796,8 @@ kbd_input_ast ()
     {
       struct input_event e;
       e.kind = ascii_keystroke;
-      XSET (e.code, Lisp_Int, c);
-#ifdef MULTI_FRAME
-      XSET(e.frame_or_window, Lisp_Frame, selected_frame);
-#else
-      e.frame_or_window = Qnil;
-#endif
+      XSETINT (e.code, c);
+      XSETFRAME (e.frame_or_window, selected_frame);
       kbd_buffer_store_event (&e);
     }
   if (input_available_clear_time)
@@ -1806,7 +1925,8 @@ sys_sleep (timeval)
     SYS$WAITFR (timer_ef);       /* Wait for timer expiry only */
 }
 
-init_sigio ()
+init_sigio (fd)
+     int fd;
 {
   request_sigio ();
 }
@@ -1849,7 +1969,7 @@ unrequest_sigio ()
  *
  */
 
-#if !defined (CANNOT_UNEXEC) && !defined (HAVE_TEXT_START)
+#ifndef HAVE_TEXT_START
 char *
 start_of_text ()
 {
@@ -1865,7 +1985,7 @@ start_of_text ()
 #endif /* GOULD */
 #endif /* TEXT_START */
 }
-#endif /* not CANNOT_UNEXEC and not HAVE_TEXT_START */
+#endif /* not HAVE_TEXT_START */
 
 /*
  *     Return the address of the start of the data segment prior to
@@ -1954,17 +2074,14 @@ 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.  */
-static char *get_system_name_cache;
-static int get_system_name_predump_p;
+extern Lisp_Object Vsystem_name;
 
 #ifndef BSD4_1
 #ifndef VMS
@@ -1975,116 +2092,108 @@ static int get_system_name_predump_p;
 #endif /* not VMS */
 #endif /* not BSD4_1 */
 
-char *
-get_system_name ()
+void
+init_system_name ()
 {
 #ifdef BSD4_1
-  return sysname;
+  Vsystem_name = build_string (sysname);
 #else
-#ifndef CANNOT_DUMP
-  /* If the cached value is from before the dump, and we've dumped
-     since then, then the cached value is no good. */
-  if (get_system_name_predump_p && initialized && get_system_name_cache)
-    {
-      xfree (get_system_name_cache);
-      get_system_name_cache = 0;
-    }
-#endif
-  if (!get_system_name_cache)
-    {
-      /* No cached value, so get the name from the system.  */
 #ifdef VMS
-      char *sp;
-      if ((sp = egetenv ("SYS$NODE")) == 0)
-       sp = "vax-vms";
-      else
-       {
-         char *end;
-
-         if ((end = index (sp, ':')) != 0)
-           *end = '\0';
-       }
-      get_system_name_cache = (char *) xmalloc (strlen (sp) + 1);
-      strcpy (get_system_name_cache, sp);
+  char *sp, *end;
+  if ((sp = egetenv ("SYS$NODE")) == 0)
+    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);
-      get_system_name_cache = (char *) xmalloc (strlen (uts.nodename) + 1);
-      strcpy (get_system_name_cache, uts.nodename);
+  struct utsname uts;
+  uname (&uts);
+  Vsystem_name = build_string (uts.nodename);
 #else /* HAVE_GETHOSTNAME */
-      {
-       int hostname_size = 256;
-       char *hostname = (char *) xmalloc (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 (;;)
-         {
-           gethostname (hostname, hostname_size - 1);
-           hostname[hostname_size - 1] = '\0';
+  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 (;;)
+    {
+      gethostname (hostname, hostname_size - 1);
+      hostname[hostname_size - 1] = '\0';
 
-           /* Was the buffer large enough for the '\0'?  */
-           if (strlen (hostname) < hostname_size - 1)
-             break;
+      /* Was the buffer large enough for the '\0'?  */
+      if (strlen (hostname) < hostname_size - 1)
+       break;
 
-           hostname_size <<= 1;
-           hostname = (char *) xrealloc (hostname, hostname_size);
-         }
-       get_system_name_cache = hostname;
+      hostname_size <<= 1;
+      hostname = (char *) alloca (hostname_size);
+    }
 #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. */
+  /* 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)
+  if (initialized)
 #endif /* not CANNOT_DUMP */
-         {
-           struct hostent *hp = gethostbyname (hostname);
-           if (hp)
-             {
-               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 = (char *) xrealloc (hostname, strlen (fqdn) + 1);
-               strcpy (hostname, fqdn);
+    {
+      struct hostent *hp;
+      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)
+       {
+         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++;
-                 }
+         /* 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 */
-       get_system_name_cache = hostname;
-      }
+  Vsystem_name = build_string (hostname);
 #endif /* HAVE_GETHOSTNAME */
 #endif /* VMS */
-#ifndef CANNOT_DUMP
-      get_system_name_predump_p = !initialized;
-#endif
-    }
-  return (get_system_name_cache);
 #endif /* BSD4_1 */
+  {
+    unsigned char *p;
+    for (p = XSTRING (Vsystem_name)->data; *p; p++)
+      if (*p == ' ' || *p == '\t')
+       *p = '-';
+  }
 }
 \f
 #ifndef VMS
@@ -2125,6 +2234,7 @@ select_alarm ()
     longjmp (read_alarm_throw, 1);
 }
 
+#ifndef WINDOWSNT
 /* Only rfds are checked.  */
 int
 select (nfds, rfds, wfds, efds, timeout)
@@ -2255,6 +2365,7 @@ select (nfds, rfds, wfds, efds, timeout)
     }
   return ravail;
 }
+#endif /* not WINDOWSNT */
 
 /* Read keyboard input into the standard buffer,
    waiting for at least one character.  */
@@ -2300,7 +2411,7 @@ read_input_waiting ()
 
       /* Scan the chars for C-g and store them in kbd_buffer.  */
       e.kind = ascii_keystroke;
-      e.frame_or_window = selected_frame;
+      XSETFRAME (e.frame_or_window, selected_frame);
       e.modifiers = 0;
       for (i = 0; i < nread; i++)
        {
@@ -2315,7 +2426,7 @@ read_input_waiting ()
                buf[i] &= ~0x80;
            }
 
-         XSET (e.code, Lisp_Int, buf[i]);
+         XSETINT (e.code, buf[i]);
          kbd_buffer_store_event (&e);
          /* Don't look at input that follows a C-g too closely.
             This reduces lossage due to autorepeat on C-g.  */
@@ -2348,12 +2459,13 @@ sys_open (path, oflag, mode)
     return open (path, oflag);
 }
 
-init_sigio ()
+init_sigio (fd)
+     int fd;
 {
   if (noninteractive)
     return;
   lmode = LINTRUP | lmode;
-  ioctl (0, TIOCLSET, &lmode);
+  ioctl (fd, TIOCLSET, &lmode);
 }
 
 reset_sigio ()
@@ -2587,7 +2699,8 @@ bcmp (b1, b2, length)     /* This could be a macro! */
 #endif /* not BSTRING */
 \f
 #ifndef HAVE_RANDOM
-#ifdef USG
+#ifndef random 
+
 /*
  *     The BSD random returns numbers in the range of
  *     0 to 2e31 - 1.  The USG rand returns numbers in the
@@ -2598,32 +2711,33 @@ bcmp (b1, b2, length)   /* This could be a macro! */
 long
 random ()
 {
-  /* Arrange to return a range centered on zero.  */
-  return (rand () << 15) + rand () - (1 << 29);
+#ifdef HAVE_LRAND48
+  return lrand48 ();
+#else
+/* The BSD rand returns numbers in the range of 0 to 2e31 - 1,
+   with unusable least significant bits.  The USG rand returns
+   numbers in the range of 0 to 2e15 - 1, all usable.  Let us
+   build a usable 30 bit number from either.  */
+#ifdef USG
+  return (rand () << 15) + rand ();
+#else
+  return (rand () & 0x3fff8000) + (rand () >> 16);
+#endif
+#endif
 }
 
 srandom (arg)
      int arg;
 {
+#ifdef HAVE_LRAND48
+  srand48 (arg);
+#else
   srand (arg);
+#endif
 }
 
-#endif /* USG */
-
-#ifdef BSD4_1
-long random ()
-{
-  /* Arrange to return a range centered on zero.  */
-  return (rand () << 15) + rand () - (1 << 29);
-}
-
-srandom (arg)
-     int arg;
-{
-  srand (arg);
-}
-#endif /* BSD4_1 */
-#endif
+#endif /* no random */
+#endif /* not HAVE_RANDOM */
 \f
 #ifdef WRONG_NAME_INSQUE
 
@@ -2742,6 +2856,7 @@ char *sys_errlist[] =
 #endif /* VMS */
 
 #ifndef HAVE_STRERROR
+#ifndef WINDOWSNT
 char *
 strerror (errnum)
      int errnum;
@@ -2753,7 +2868,7 @@ strerror (errnum)
     return sys_errlist[errnum];
   return (char *) "Unknown error";
 }
-
+#endif /* not WINDOWSNT */
 #endif /* ! HAVE_STRERROR */
 \f
 #ifdef INTERRUPTIBLE_OPEN
@@ -2834,16 +2949,16 @@ sys_write (fildes, buf, nbyte)
 #endif /* INTERRUPTIBLE_IO */
 \f
 #ifndef HAVE_VFORK
-
+#ifndef WINDOWSNT
 /*
- *     Substitute fork for vfork on USG flavors.
+ *      Substitute fork for vfork on USG flavors.
  */
 
 vfork ()
 {
   return (fork ());
 }
-
+#endif /* not WINDOWSNT */
 #endif /* not HAVE_VFORK */
 \f
 #ifdef USG
@@ -3006,37 +3121,6 @@ rename (from, to)
 
 #endif
 
-#ifdef MISSING_UTIMES
-
-/* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes.  */
-
-utimes ()
-{
-}
-#endif
-
-#ifdef IRIS_UTIME
-
-/* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
-   utimbuf structure defined anywhere but in the man page. */
-
-struct utimbuf
- {
-   long actime;
-   long modtime;
- };
-
-utimes (name, tvp)
-     char *name;
-     struct timeval tvp[];
-{
-  struct utimbuf utb;
-  utb.actime  = tvp[0].tv_sec;
-  utb.modtime = tvp[1].tv_sec;
-  utime (name, &utb);
-}
-#endif /* IRIS_UTIME */
-
 
 #ifdef HPUX
 #ifndef HAVE_PERROR
@@ -3376,6 +3460,24 @@ readdirver (dirp)
 #endif /* NONSYSTEM_DIR_LIBRARY */
 
 \f
+int
+set_file_times (filename, atime, mtime)
+     char *filename;
+     EMACS_TIME atime, mtime;
+{
+#ifdef HAVE_UTIMES
+  struct timeval tv[2];
+  tv[0] = atime;
+  tv[1] = mtime;
+  return utimes (filename, tv);
+#else /* not HAVE_UTIMES */
+  struct utimbuf utb;
+  utb.actime = EMACS_SECS (atime);
+  utb.modtime = EMACS_SECS (mtime);
+  return utime (filename, &utb);
+#endif /* not HAVE_UTIMES */
+}
+\f
 /* mkdir and rmdir functions, for systems which don't have them.  */
 
 #ifndef HAVE_MKDIR
@@ -3616,8 +3718,8 @@ sys_access (path, mode)
 #else /* not VMS4_4 */
 
 #include <prvdef.h>
-#define        ACE$M_WRITE     2
-#define        ACE$C_KEYID     1
+#define ACE$M_WRITE     2
+#define ACE$C_KEYID     1
 
 static unsigned short memid, grpid;
 static unsigned int uic;
@@ -3650,13 +3752,13 @@ sys_access (filename, type)
       grpid = uic >> 16;
     }
 
-  if (type != 2)               /* not checking write access */
+  if (type != 2)                /* not checking write access */
     return access (filename, type);
 
   /* Check write protection. */
     
-#define        CHECKPRIV(bit)    (prvmask.bit)
-#define        WRITEABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
+#define CHECKPRIV(bit)    (prvmask.bit)
+#define WRITEABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
 
   /* Find privilege bits */
   status = SYS$SETPRV (0, 0, 0, prvmask);
@@ -4761,7 +4863,7 @@ srandom (seed)
 }
 #endif /* VMS */
 \f
-#ifdef AIX
+#ifdef AIXHFT
 
 /* Called from init_sys_modes.  */
 hft_init ()
@@ -4853,4 +4955,31 @@ hft_reset ()
   hftctl (0, HFSKBD, &buf);
 }
 
-#endif /* AIX */
+#endif /* AIXHFT */
+
+#ifdef USE_DL_STUBS
+
+/* These are included on Sunos 4.1 when we do not use shared libraries.
+   X11 libraries may refer to these functions but (we hope) do not
+   actually call them.  */
+
+void *
+dlopen ()
+{
+  return 0;
+}
+
+void *
+dlsym ()
+{
+  return 0;
+}
+
+int
+dlclose ()
+{
+  return -1;
+}
+
+#endif /* USE_DL_STUBS */
+