(child_setup_tty): Use CDISABLE for setting VERASE, VKILL.
[bpt/emacs.git] / src / sysdep.c
index 95398fa..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 
@@ -97,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
@@ -150,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
@@ -179,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.  */
 
@@ -197,6 +225,7 @@ change_input_fd (fd)
 
 discard_tty_input ()
 {
+#ifndef WINDOWSNT
   struct emacs_tty buf;
 
   if (noninteractive)
@@ -219,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
@@ -238,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);
@@ -254,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;
 
@@ -296,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;
 }
@@ -330,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 ()
@@ -361,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;
@@ -376,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))
        {
@@ -394,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 */
@@ -457,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);
@@ -486,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 */
@@ -545,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
@@ -663,11 +694,10 @@ sys_subshell ()
      which somehow wedges the hp compiler.  So instead...  */
 
   dir = intern ("default-directory");
-  /* Can't use NILP */
-  if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil))
+  if (NILP (Fboundp (dir)))
     goto xyzzy;
   dir = Fsymbol_value (dir);
-  if (XTYPE (dir) != Lisp_String)
+  if (!STRINGP (dir))
     goto xyzzy;
 
   dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
@@ -678,15 +708,19 @@ sys_subshell ()
   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");
@@ -710,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 */
     }
 
@@ -754,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 ()
@@ -771,6 +818,9 @@ reset_sigio ()
 
 request_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
 #ifdef SIGWINCH
   sigunblock (sigmask (SIGWINCH));
 #endif
@@ -781,6 +831,9 @@ request_sigio ()
 
 unrequest_sigio ()
 {
+  if (read_socket_hook)
+    return;
+
 #ifdef SIGWINCH
   sigblock (sigmask (SIGWINCH));
 #endif
@@ -794,6 +847,10 @@ unrequest_sigio ()
 request_sigio ()
 {
   int on = 1;
+
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &on);
   interrupts_deferred = 0;
 }
@@ -802,6 +859,9 @@ unrequest_sigio ()
 {
   int off = 0;
 
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &off);
   interrupts_deferred = 1;
 }
@@ -817,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);
@@ -828,6 +891,9 @@ unrequest_sigio ()
 {
   int off = 0;
 
+  if (read_socket_hook)
+    return;
+
   ioctl (input_fd, FIOASYNC, &off);
   interrupts_deferred = 1;
 }
@@ -836,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");
 }
  
@@ -928,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
@@ -1020,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
@@ -1133,10 +1205,14 @@ 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)
@@ -1214,9 +1290,14 @@ init_sys_modes ()
       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
@@ -1243,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 */
 
@@ -1287,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
 
@@ -1305,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
       {
@@ -1317,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.
@@ -1336,7 +1422,7 @@ init_sys_modes ()
     {
       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 */
@@ -1344,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.  */
@@ -1497,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. */
@@ -1549,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
 
@@ -1690,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)
@@ -1823,7 +1925,8 @@ sys_sleep (timeval)
     SYS$WAITFR (timer_ef);       /* Wait for timer expiry only */
 }
 
-init_sigio ()
+init_sigio (fd)
+     int fd;
 {
   request_sigio ();
 }
@@ -2131,6 +2234,7 @@ select_alarm ()
     longjmp (read_alarm_throw, 1);
 }
 
+#ifndef WINDOWSNT
 /* Only rfds are checked.  */
 int
 select (nfds, rfds, wfds, efds, timeout)
@@ -2261,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.  */
@@ -2306,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++)
        {
@@ -2321,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.  */
@@ -2354,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 ()
@@ -2750,6 +2856,7 @@ char *sys_errlist[] =
 #endif /* VMS */
 
 #ifndef HAVE_STRERROR
+#ifndef WINDOWSNT
 char *
 strerror (errnum)
      int errnum;
@@ -2761,7 +2868,7 @@ strerror (errnum)
     return sys_errlist[errnum];
   return (char *) "Unknown error";
 }
-
+#endif /* not WINDOWSNT */
 #endif /* ! HAVE_STRERROR */
 \f
 #ifdef INTERRUPTIBLE_OPEN
@@ -2842,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
@@ -3364,12 +3471,6 @@ set_file_times (filename, atime, mtime)
   tv[1] = mtime;
   return utimes (filename, tv);
 #else /* not HAVE_UTIMES */
-#ifndef HAVE_STRUCT_UTIMBUF
-  struct utimbuf {
-    long actime;
-    long modtime;
-  };
-#endif
   struct utimbuf utb;
   utb.actime = EMACS_SECS (atime);
   utb.modtime = EMACS_SECS (mtime);
@@ -3617,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;
@@ -3651,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);
@@ -4762,7 +4863,7 @@ srandom (seed)
 }
 #endif /* VMS */
 \f
-#ifdef AIX
+#ifdef AIXHFT
 
 /* Called from init_sys_modes.  */
 hft_init ()
@@ -4854,7 +4955,7 @@ hft_reset ()
   hftctl (0, HFSKBD, &buf);
 }
 
-#endif /* AIX */
+#endif /* AIXHFT */
 
 #ifdef USE_DL_STUBS