summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c581
-rw-r--r--lib-src/pty.c20
-rw-r--r--lib-src/pty.h224
3 files changed, 817 insertions, 8 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index aafc531ac5b..2f0f45e1f59 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -41,6 +41,54 @@ Boston, MA 02111-1307, USA. */
# include <pwd.h>
#endif /* not VMS */
+
+/****************************************/
+
+#include <errno.h>
+#include <signal.h>
+
+#ifndef INCLUDED_FCNTL
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_TERMIOS
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif
+#include <termios.h>
+#endif /* not HAVE_TERMIOS */
+
+#ifdef __GNU_LIBRARY__
+#include <sys/ioctl.h>
+#include <termios.h>
+#endif
+
+#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+
+
+/* Try to establish the correct character to disable terminal functions
+ in a system-independent manner. Note that USG (at least) define
+ _POSIX_VDISABLE as 0! */
+
+#ifdef _POSIX_VDISABLE
+#define CDISABLE _POSIX_VDISABLE
+#else /* not _POSIX_VDISABLE */
+#ifdef CDEL
+#undef CDISABLE
+#define CDISABLE CDEL
+#else /* not CDEL */
+#define CDISABLE 255
+#endif /* not CDEL */
+#endif /* not _POSIX_VDISABLE */
+
+
+
+/****************************************/
+
char *getenv (), *getwd ();
char *getcwd ();
@@ -63,6 +111,9 @@ int eval = 0;
/* The display on which Emacs should work. --display. */
char *display = NULL;
+/* Nonzero means open a new Emacs frame on the current terminal. */
+int here = 0;
+
/* If non-NULL, the name of an editor to fallback to if the server
is not running. --alternate-editor. */
const char * alternate_editor = NULL;
@@ -78,6 +129,7 @@ struct option longopts[] =
{ "eval", no_argument, NULL, 'e' },
{ "help", no_argument, NULL, 'H' },
{ "version", no_argument, NULL, 'V' },
+ { "here", no_argument, NULL, 'h' },
{ "alternate-editor", required_argument, NULL, 'a' },
{ "socket-name", required_argument, NULL, 's' },
{ "display", required_argument, NULL, 'd' },
@@ -95,7 +147,7 @@ decode_options (argc, argv)
while (1)
{
int opt = getopt_long (argc, argv,
- "VHnea:s:d:", longopts, 0);
+ "VHnea:s:d:h", longopts, 0);
if (opt == EOF)
break;
@@ -134,6 +186,10 @@ decode_options (argc, argv)
exit (0);
break;
+ case 'h':
+ here = 1;
+ break;
+
case 'H':
print_help_and_exit ();
break;
@@ -144,6 +200,12 @@ decode_options (argc, argv)
break;
}
}
+
+ if (here) {
+ nowait = 0;
+ display = 0;
+ }
+
}
void
@@ -157,6 +219,7 @@ Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
The following OPTIONS are accepted:\n\
-V, --version Just print a version info and return\n\
-H, --help Print this usage information message\n\
+-h, --here Open a new Emacs frame on the current terminal\n\
-n, --no-wait Don't wait for the server to return\n\
-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
-d, --display=DISPLAY Visit the file in the given display\n\
@@ -247,6 +310,455 @@ fail (argc, argv)
}
}
+
+#ifdef HAVE_TERMIOS
+
+/* Adapted from emacs_get_tty() in sysdep.c. */
+int
+ec_get_tty (int fd, struct termios *settings)
+{
+ bzero (settings, sizeof (struct termios));
+ if (tcgetattr (fd, settings) < 0)
+ return -1;
+ return 0;
+}
+
+/* Adapted from emacs_set_tty() in sysdep.c. */
+int
+ec_set_tty (int fd, struct termios *settings, int flushp)
+{
+ /* Set the primary parameters - baud rate, character size, etcetera. */
+
+ 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
+ able to perform any of the requested actions, even if some
+ 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." */
+ /* This make sure that we don't loop indefinitely in here. */
+ for (i = 0 ; i < 10 ; i++)
+ if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ else
+ return -1;
+ }
+ else
+ {
+ struct termios new;
+
+ bzero (&new, sizeof (new));
+ /* Get the current settings, and see if they're what we asked for. */
+ tcgetattr (fd, &new);
+ /* 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->c_iflag
+ && new.c_oflag == settings->c_oflag
+ && new.c_cflag == settings->c_cflag
+ && new.c_lflag == settings->c_lflag
+ && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
+ break;
+ else
+ continue;
+ }
+ return 0;
+}
+
+int master;
+char *pty_name;
+
+struct termios old_tty;
+struct termios tty;
+int old_tty_valid;
+
+int tty_erase_char;
+int flow_control = 0;
+int meta_key = 0;
+char _sobuf[BUFSIZ];
+
+/* Adapted from init_sys_modes() in sysdep.c. */
+int
+init_tty ()
+{
+ if (! isatty (0))
+ {
+ fprintf (stderr, "%s: Input is not a terminal", "init_tty");
+ return 0;
+ }
+
+ ec_get_tty (0, &old_tty);
+ old_tty_valid = 1;
+ tty = old_tty;
+
+ tty_erase_char = old_tty.c_cc[VERASE];
+
+ tty.c_iflag |= (IGNBRK); /* Ignore break condition */
+ tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
+#ifdef INLCR
+ tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
+#endif
+#ifdef ISTRIP
+ tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
+#endif
+ tty.c_lflag &= ~ECHO; /* Disable echo */
+ tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
+#ifdef IEXTEN
+ tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
+#endif
+ tty.c_lflag |= ISIG; /* Enable signals */
+ if (flow_control)
+ {
+ tty.c_iflag |= IXON; /* Enable start/stop output control */
+#ifdef IXANY
+ tty.c_iflag &= ~IXANY;
+#endif /* IXANY */
+ }
+ else
+ tty.c_iflag &= ~IXON; /* Disable start/stop output control */
+ tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
+ on output */
+ tty.c_oflag &= ~TAB3; /* Disable tab expansion */
+#ifdef CS8
+ if (meta_key)
+ {
+ tty.c_cflag |= CS8; /* allow 8th bit on input */
+ tty.c_cflag &= ~PARENB; /* Don't check parity */
+ }
+#endif
+ tty.c_cc[VINTR] = CDISABLE;
+ tty.c_cc[VQUIT] = CDISABLE;
+ tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
+ tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
+#ifdef VSWTCH
+ tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
+#endif
+
+#ifdef VSUSP
+ tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
+#endif /* VSUSP */
+#ifdef V_DSUSP
+ tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
+#endif /* V_DSUSP */
+#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
+ tty.c_cc[VDSUSP] = CDISABLE;
+#endif /* VDSUSP */
+#ifdef VLNEXT
+ tty.c_cc[VLNEXT] = CDISABLE;
+#endif /* VLNEXT */
+#ifdef VREPRINT
+ tty.c_cc[VREPRINT] = CDISABLE;
+#endif /* VREPRINT */
+#ifdef VWERASE
+ tty.c_cc[VWERASE] = CDISABLE;
+#endif /* VWERASE */
+#ifdef VDISCARD
+ tty.c_cc[VDISCARD] = CDISABLE;
+#endif /* VDISCARD */
+
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
+ else
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = CDISABLE;
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = CDISABLE;
+#endif /* VSTOP */
+ }
+
+#ifdef SET_LINE_DISCIPLINE
+ /* Need to explicitly request TERMIODISC line discipline or
+ Ultrix's termios does not work correctly. */
+ tty.c_line = SET_LINE_DISCIPLINE;
+#endif
+
+#ifdef AIX
+#ifndef IBMR2AIX
+ /* AIX enhanced edit loses NULs, so disable it. */
+ tty.c_line = 0;
+ tty.c_iflag &= ~ASCEDIT;
+#else
+ tty.c_cc[VSTRT] = 255;
+ tty.c_cc[VSTOP] = 255;
+ tty.c_cc[VSUSP] = 255;
+ tty.c_cc[VDSUSP] = 255;
+#endif /* IBMR2AIX */
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
+ /* Also, PTY overloads NUL and BREAK.
+ don't ignore break, but don't signal either, so it looks like NUL.
+ This really serves a purpose only if running in an XTERM window
+ or via TELNET or the like, but does no harm elsewhere. */
+ tty.c_iflag &= ~IGNBRK;
+ tty.c_iflag &= ~BRKINT;
+#endif /* AIX */
+
+ ec_set_tty (0, &tty, 0);
+
+ /* This code added to insure that, if flow-control is not to be used,
+ we have an unlocked terminal at the start. */
+
+#ifdef TCXONC
+ if (!flow_control) ioctl (0, TCXONC, 1);
+#endif
+#ifndef APOLLO
+#ifdef TIOCSTART
+ if (!flow_control) ioctl (0, TIOCSTART, 0);
+#endif
+#endif
+
+#if defined (HAVE_TERMIOS) || defined (HPUX9)
+#ifdef TCOON
+ if (!flow_control) tcflow (0, TCOON);
+#endif
+#endif
+
+#ifdef _IOFBF
+ /* This symbol is defined on recent USG systems.
+ Someone says without this call USG won't really buffer the file
+ even with a call to setbuf. */
+ setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
+#else
+ setbuf (stdout, (char *) _sobuf);
+#endif
+
+ return 1;
+}
+
+void
+window_change ()
+{
+ int width, height;
+
+#ifdef TIOCGWINSZ
+ {
+ /* BSD-style. */
+ struct winsize size;
+
+ if (ioctl (0, TIOCGWINSZ, &size) == -1)
+ width = height = 0;
+ else
+ {
+ width = size.ws_col;
+ height = size.ws_row;
+ }
+ }
+#else
+#ifdef TIOCGSIZE
+ {
+ /* SunOS - style. */
+ struct ttysize size;
+
+ if (ioctl (0, TIOCGSIZE, &size) == -1)
+ width = height = 0;
+ else
+ {
+ width = size.ts_cols;
+ height = size.ts_lines;
+ }
+ }
+#endif /* not SunOS-style */
+#endif /* not BSD-style */
+
+#ifdef TIOCSWINSZ
+ {
+ /* BSD-style. */
+ struct winsize size;
+ size.ws_row = height;
+ size.ws_col = width;
+
+ ioctl (master, TIOCSWINSZ, &size);
+ }
+#else
+#ifdef TIOCSSIZE
+ {
+ /* SunOS - style. */
+ struct ttysize size;
+ size.ts_lines = height;
+ size.ts_cols = width;
+
+ ioctl (master, TIOCGSIZE, &size);
+ }
+#endif /* not SunOS-style */
+#endif /* not BSD-style */
+}
+
+int in_conversation = 0;
+int quit_conversation = 0;
+
+SIGTYPE
+hang_up_signal (int signalnum)
+{
+ int old_errno = errno;
+
+ if (! in_conversation)
+ return;
+
+ quit_conversation = 1;
+
+ errno = old_errno;
+}
+
+SIGTYPE
+window_change_signal (int signalnum)
+{
+ int old_errno = errno;
+
+ if (! in_conversation)
+ goto end;
+
+ window_change();
+
+ end:
+ signal (SIGWINCH, window_change_signal);
+ errno = old_errno;
+}
+
+int
+init_signals ()
+{
+ /* Set up signal handlers. */
+ signal (SIGWINCH, window_change_signal);
+ signal (SIGHUP, hang_up_signal);
+
+ return 1;
+}
+
+
+
+/* Adapted from reset_sys_modes in sysdep.c. */
+int
+reset_tty ()
+{
+ fflush (stdout);
+#ifdef BSD_SYSTEM
+#ifndef BSD4_1
+ /* Avoid possible loss of output when changing terminal modes. */
+ fsync (fileno (stdout));
+#endif
+#endif
+
+#ifdef F_SETFL
+#ifdef O_NDELAY
+ fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
+#endif
+#endif /* F_SETFL */
+
+ if (old_tty_valid)
+ while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
+ ;
+
+ return 1;
+}
+
+
+int
+init_pty ()
+{
+ master = getpt ();
+ if (master < 0)
+ return 0;
+
+ if (grantpt (master) < 0 || unlockpt (master) < 0)
+ goto close_master;
+ pty_name = strdup (ptsname (master));
+ if (! pty_name)
+ goto close_master;
+
+ /* Propagate window size. */
+ window_change ();
+
+ return 1;
+
+ close_master:
+ close (master);
+ return 0;
+}
+
+int
+copy_from_to (int in, int out)
+{
+ static char buf[BUFSIZ];
+ int nread = read (in, &buf, BUFSIZ);
+ if (nread == 0)
+ return 1; /* EOF */
+ else if (nread < 0 && errno != EAGAIN)
+ return 0; /* Error */
+ else if (nread > 0)
+ {
+ int r = 0;
+ int written = 0;
+
+ do {
+ r = write (out, &buf, nread);
+ } while ((r < 0 && errno == EAGAIN)
+ || (r > 0 && (written += r) && written != nread));
+
+ if (r < 0)
+ return 0; /* Error */
+ }
+ return 1;
+}
+
+int
+pty_conversation ()
+{
+ fd_set set;
+
+ in_conversation = 1;
+
+ while (! quit_conversation) {
+ int res;
+
+ FD_ZERO (&set);
+ FD_SET (master, &set);
+ FD_SET (1, &set);
+ res = select (FD_SETSIZE, &set, NULL, NULL, NULL);
+ if (res < 0)
+ {
+ if (errno != EINTR)
+ return 0;
+ }
+ else if (res > 0)
+ {
+ if (FD_ISSET (master, &set))
+ {
+ /* Copy Emacs output to stdout. */
+ if (! copy_from_to (master, 0))
+ return 1;
+ }
+ if (FD_ISSET (1, &set))
+ {
+ /* Forward user input to Emacs. */
+ if (! copy_from_to (1, master))
+ return 1;
+ }
+ }
+ }
+ return 1;
+}
+
+#endif /* HAVE_TERMIOS */
#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
@@ -312,7 +824,7 @@ main (argc, argv)
/* Process options. */
decode_options (argc, argv);
- if ((argc - optind < 1) && !eval)
+ if ((argc - optind < 1) && !eval && !here)
{
fprintf (stderr, "%s: file name or argument required\n", progname);
fprintf (stderr, "Try `%s --help' for more information\n", progname);
@@ -484,6 +996,38 @@ To start the server in Emacs, type \"M-x server-start\".\n",
fprintf (out, " ");
}
+ if (here)
+ {
+ if (! init_signals ())
+ {
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ if (! init_tty ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ if (! init_pty ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ fprintf (out, "-pty ");
+ quote_file_name (pty_name, out);
+ fprintf (out, " ");
+ quote_file_name (getenv("TERM"), out);
+ fprintf (out, " ");
+ }
+
if ((argc - optind > 0))
{
for (i = optind; i < argc; i++)
@@ -512,11 +1056,14 @@ To start the server in Emacs, type \"M-x server-start\".\n",
}
else
{
- while ((str = fgets (string, BUFSIZ, stdin)))
- {
- quote_file_name (str, out);
- }
- fprintf (out, " ");
+ if (!here)
+ {
+ while ((str = fgets (string, BUFSIZ, stdin)))
+ {
+ quote_file_name (str, out);
+ }
+ fprintf (out, " ");
+ }
}
fprintf (out, "\n");
@@ -524,8 +1071,25 @@ To start the server in Emacs, type \"M-x server-start\".\n",
/* Maybe wait for an answer. */
if (nowait)
- return 0;
+ {
+ reset_tty ();
+ return 0;
+ }
+ if (here)
+ {
+ if (! pty_conversation ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+ close (master);
+ reset_tty ();
+ return 0;
+ }
+
if (!eval)
{
printf ("Waiting for Emacs...");
@@ -546,6 +1110,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
printf ("\n");
fflush (stdout);
+ reset_tty ();
return 0;
}
diff --git a/lib-src/pty.c b/lib-src/pty.c
new file mode 100644
index 00000000000..05c54c63ff5
--- /dev/null
+++ b/lib-src/pty.c
@@ -0,0 +1,20 @@
+/* Terminal initialization for emacsclient.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
diff --git a/lib-src/pty.h b/lib-src/pty.h
new file mode 100644
index 00000000000..d8f6318176a
--- /dev/null
+++ b/lib-src/pty.h
@@ -0,0 +1,224 @@
+/* Terminal initialization for emacsclient.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Adapted from systty.h */
+
+
+#ifdef HAVE_TERMIOS
+#define HAVE_TCATTR
+#endif
+
+
+/* Include the proper files. */
+#ifdef HAVE_TERMIO
+#ifdef __DGUX
+#include <sys/ioctl.h>
+#endif
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif /* not NO_TERMIO */
+#ifndef INCLUDED_FCNTL
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#endif
+#else /* not HAVE_TERMIO */
+#ifdef HAVE_TERMIOS
+#if defined(_AIX) && defined(_I386)
+#include <termios.h> /* termios.h needs to be before termio.h */
+#include <termio.h>
+#else /* not (_AIX && _I386) */
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif
+#include <termios.h>
+#endif /* not (_AIX && _I386) */
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#else /* neither HAVE_TERMIO nor HAVE_TERMIOS */
+#ifndef VMS
+#ifndef DOS_NT
+#include <sgtty.h>
+#endif /* not DOS_NT */
+#else /* VMS */
+#include <descrip.h>
+static struct iosb
+{
+ short status;
+ short offset;
+ short termlen;
+ short term;
+} input_iosb;
+
+extern int waiting_for_ast;
+extern int stop_input;
+extern int input_ef;
+extern int timer_ef;
+extern int process_ef;
+extern int input_eflist;
+extern int timer_eflist;
+
+static $DESCRIPTOR (input_dsc, "TT");
+static int terminator_mask[2] = { 0, 0 };
+
+static struct sensemode {
+ short status;
+ unsigned char xmit_baud;
+ unsigned char rcv_baud;
+ unsigned char crfill;
+ unsigned char lffill;
+ unsigned char parity;
+ unsigned char unused;
+ char class;
+ char type;
+ short scr_wid;
+ unsigned long tt_char : 24, scr_len : 8;
+ unsigned long tt2_char;
+} sensemode_iosb;
+#endif /* VMS */
+#endif /* not HAVE_TERMIOS */
+#endif /* not HAVE_TERMIO */
+
+#ifdef __GNU_LIBRARY__
+#include <sys/ioctl.h>
+#include <termios.h>
+#endif
+
+#ifdef AIXHFT
+/* Get files for keyboard remapping */
+#define HFNKEYS 2
+#include <sys/hft.h>
+#include <sys/devinfo.h>
+#endif
+
+/* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
+#ifdef BSD4_1
+#undef LLITOUT
+#define LLITOUT 0
+#endif /* 4.1 */
+
+#ifdef NEED_BSDTTY
+#include <sys/bsdtty.h>
+#endif
+
+#if defined (HPUX) && defined (HAVE_PTYS)
+#include <sys/ptyio.h>
+#endif
+
+#ifdef AIX
+#include <sys/pty.h>
+#endif /* AIX */
+
+#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#ifdef SYSV_PTYS
+#include <sys/types.h>
+#include <sys/tty.h>
+#ifdef titan
+#include <sys/ttyhw.h>
+#include <sys/stream.h>
+#endif
+#ifndef NO_PTY_H
+#include <sys/pty.h>
+#endif
+#endif
+
+/* saka@pfu.fujitsu.co.JP writes:
+ FASYNC defined in this file. But, FASYNC don't working.
+ so no problem, because unrequest_sigio only need. */
+#if defined (pfa)
+#include <sys/file.h>
+#endif
+
+
+/* Special cases - inhibiting the use of certain features. */
+
+#ifdef APOLLO
+#undef TIOCSTART
+#endif
+
+#ifdef XENIX
+#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
+#endif
+
+#ifdef BROKEN_TIOCGETC
+#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
+#endif
+
+/* UNIPLUS systems may have FIONREAD. */
+#ifdef UNIPLUS
+#include <sys.ioctl.h>
+#endif
+
+/* Allow m- file to inhibit use of FIONREAD. */
+#ifdef BROKEN_FIONREAD
+#undef FIONREAD
+#undef ASYNC
+#endif
+
+/* Interrupt input is not used if there is no FIONREAD. */
+#ifndef FIONREAD
+#undef SIGIO
+#endif
+
+/* On TERMIOS systems, the tcmumbleattr calls take care of these
+ parameters, and it's a bad idea to use them (on AIX, it makes the
+ tty hang for a long time). */
+#if defined (TIOCGLTC) && !defined (HAVE_TERMIOS)
+#define HAVE_LTCHARS
+#endif
+
+#if defined (TIOCGETC) && !defined (HAVE_TERMIOS)
+#define HAVE_TCHARS
+#endif
+
+
+/* Try to establish the correct character to disable terminal functions
+ in a system-independent manner. Note that USG (at least) define
+ _POSIX_VDISABLE as 0! */
+
+#ifdef _POSIX_VDISABLE
+#define CDISABLE _POSIX_VDISABLE
+#else /* not _POSIX_VDISABLE */
+#ifdef CDEL
+#undef CDISABLE
+#define CDISABLE CDEL
+#else /* not CDEL */
+#define CDISABLE 255
+#endif /* not CDEL */
+#endif /* not _POSIX_VDISABLE */
+
+/* Get the number of characters queued for output. */
+
+/* EMACS_OUTQSIZE(FD, int *SIZE) stores the number of characters
+ queued for output to the terminal FD in *SIZE, if FD is a tty.
+ Returns -1 if there was an error (i.e. FD is not a tty), 0
+ otherwise. */
+#ifdef TIOCOUTQ
+#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TIOCOUTQ, (size)))
+#endif
+
+#ifdef HAVE_TERMIO
+#ifdef TCOUTQ
+#undef EMACS_OUTQSIZE
+#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TCOUTQ, (size)))
+#endif
+#endif