Fix compilation when MULE is disabled, due to a missing ifdef.
[sxemacs] / src / sysdep.c
1 /* Interfaces to system-dependent kernel and library entries.
2    Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Tinker Systems.
4    Copyright (C) 2007 Sebastian Freundt
5
6 This file is part of SXEmacs
7
8 SXEmacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 SXEmacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
20
21
22 /* Synched up with: FSF 19.30 except for some Windows-NT crap. */
23
24 /* Substantially cleaned up by Ben Wing, Dec. 1994 / Jan. 1995. */
25
26 /* In this file, open, read and write refer to the system calls,
27    not our sugared interfaces sys_open, sys_read and sys_write.
28  */
29
30 #define DONT_ENCAPSULATE
31
32 #include <config.h>
33
34 #include "lisp.h"
35
36 /* ------------------------------- */
37 /*          basic includes         */
38 /* ------------------------------- */
39
40 #ifdef HAVE_TTY
41 #include "ui/TTY/console-tty.h" /* for stuff in stuff_char and
42                                    others. Seriously in need of
43                                    refactoring... */
44 #else
45 #include "syssignal.h"
46 #include "ui/systty.h"
47 #endif                          /* HAVE_TTY */
48
49 #include "ui/console-stream.h"
50
51 #include "buffer.h"
52 #include "events/events.h"
53 #include "ui/frame.h"
54 #include "ui/redisplay.h"
55 #include "process.h"
56 #include "sysdep.h"
57 #include "ui/window.h"
58
59 #include <setjmp.h>
60 #ifdef HAVE_LIBGEN_H            /* Must come before sysfile.h */
61 #include <libgen.h>
62 #endif
63 #include "sysfile.h"
64 #include "syswait.h"
65 #include "sysdir.h"
66 #include "systime.h"
67
68 #include "sysproc.h"
69
70 #include <sys/times.h>
71
72 /* ------------------------------- */
73 /*         TTY definitions         */
74 /* ------------------------------- */
75
76 #ifdef USG
77 #include <sys/utsname.h>
78 #if defined (TIOCGWINSZ) || defined (ISC4_0)
79 #ifdef NEED_SIOCTL
80 #include <sys/sioctl.h>
81 #endif
82 #ifdef NEED_PTEM_H
83 #include <sys/stream.h>
84 #include <sys/ptem.h>
85 #endif
86 #endif                          /* TIOCGWINSZ or ISC4_0 */
87 #endif                          /* USG */
88
89 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
90 #ifndef LPASS8
91 #define LPASS8 0
92 #endif
93
94 #ifndef HAVE_H_ERRNO
95 int h_errno;
96 #endif
97
98 #ifdef HAVE_TTY
99
100 static int baud_convert[] =
101 #ifdef BAUD_CONVERT
102     BAUD_CONVERT;
103 #else
104 {
105         0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
106         1800, 2400, 4800, 9600, 19200, 38400
107 };
108 #endif
109
110 #endif
111
112 #ifdef AIXHFT
113 static void hft_init(struct console *c);
114 static void hft_reset(struct console *c);
115 #include <sys/termio.h>
116 #endif
117 \f
118 /************************************************************************/
119 /*                         subprocess control                           */
120 /************************************************************************/
121
122 #ifdef HAVE_TTY
123
124 #ifdef SIGTSTP
125
126 /* Arrange for character C to be read as the next input from
127    the terminal.  */
128 void stuff_char(struct console *con, int c)
129 {
130         int input_fd;
131
132         assert(CONSOLE_TTY_P(con));
133         input_fd = CONSOLE_TTY_DATA(con)->infd;
134 /* Should perhaps error if in batch mode */
135 #ifdef TIOCSTI
136         ioctl(input_fd, TIOCSTI, &c);
137 #else                           /* no TIOCSTI */
138         error
139             ("Cannot stuff terminal input characters in this version of Unix.");
140 #endif                          /* no TIOCSTI */
141 }
142
143 #endif                          /* SIGTSTP */
144
145 #endif                          /* HAVE_TTY */
146
147 void set_exclusive_use(int fd)
148 {
149 #ifdef FIOCLEX
150         ioctl(fd, FIOCLEX, 0);
151 #endif
152         /* Ok to do nothing if this feature does not exist */
153 }
154
155 void set_descriptor_non_blocking(int fd)
156 {
157 /* Stride people say it's a mystery why this is needed
158    as well as the O_NDELAY, but that it fails without this.  */
159         /* For AIX: Apparently need this for non-blocking reads on sockets.
160            It seems that O_NONBLOCK applies only to FIFOs?  From
161            lowry@watson.ibm.com (Andy Lowry). */
162         /* #### Should this be conditionalized on FIONBIO? */
163 #if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS)) || defined (AIX)
164         {
165                 int one = 1;
166                 ioctl(fd, FIONBIO, &one);
167         }
168 #endif
169
170 #ifdef F_SETFL
171         fcntl(fd, F_SETFL, O_NONBLOCK);
172 #endif
173 }
174
175 #if defined (NO_SUBPROCESSES)
176
177 #ifdef BSD
178 void wait_without_blocking(void)
179 {
180         wait3(0, WNOHANG | WUNTRACED, 0);
181         synch_process_alive = 0;
182 }
183 #endif                          /* BSD */
184
185 #endif                          /* NO_SUBPROCESSES */
186
187 void wait_for_termination(int pid)
188 {
189         /* #### With the new improved SIGCHLD handling stuff, there is much
190            less danger of race conditions and some of the comments below
191            don't apply.  This should be updated. */
192
193 #if defined (NO_SUBPROCESSES)
194         while (1) {
195                 /* No need to be tricky like below; we can just call wait(). */
196                 /* #### should figure out how to write a wait_allowing_quit().
197                    Since hardly any systems don't have subprocess support,
198                    however, there doesn't seem to be much point. */
199                 if (wait(0) == pid)
200                         return;
201         }
202 #elif defined (HAVE_WAITPID)
203         /* Note that, whenever any subprocess terminates (asynch. or synch.),
204            the SIGCHLD handler will be called and it will call wait().  Thus
205            we cannot just call wait() ourselves, and we can't block SIGCHLD
206            and then call wait(), because then if an asynch.  process dies
207            while we're waiting for our synch. process, Emacs will never
208            notice that the asynch. process died.
209
210            So, the general approach we take is to repeatedly block until a
211            signal arrives, and then check if our process died using kill
212            (pid, 0).  (We could also check the value of `synch_process_alive',
213            since the SIGCHLD handler will reset that and we know that we're
214            only being called on synchronous processes, but this approach is
215            safer.  I don't trust the proper delivery of SIGCHLD.
216
217            Note also that we cannot use any form of waitpid().  A loop with
218            WNOHANG will chew up CPU time; better to use sleep().  A loop
219            without WNOWAIT will screw up the SIGCHLD handler (actually this
220            is not true, if you duplicate the exit-status-reaping code; see
221            below).  A loop with WNOWAIT will result in a race condition if
222            the process terminates between the process-status check and the
223            call to waitpid(). */
224
225         /* Formerly, immediate_quit was set around this function call, but
226            that could lead to problems if the QUIT happened when SIGCHLD was
227            blocked -- it would remain blocked.  Yet another reason why
228            immediate_quit is a bad idea.  In any case, there is no reason to
229            resort to this because either the SIGIO or the SIGALRM will stop
230            the block in EMACS_WAIT_FOR_SIGNAL(). */
231
232         /* Apparently there are bugs on some systems with the second method
233            used below (the EMACS_BLOCK_SIGNAL method), whereby zombie
234            processes get left around.  It appears in those cases that the
235            SIGCHLD handler is never getting invoked.  It's not clear whether
236            this is an Emacs bug or a kernel bug or both: on HPUX this
237            problem is observed only with XEmacs, but under Solaris 2.4 all
238            sorts of different programs have problems with zombies.  The
239            method we use here does not require a working SIGCHLD (but will
240            not break if it is working), and should be safe. */
241         /*
242            We use waitpid(), contrary to the remarks above.  There is no
243            race condition, because the three situations when sigchld_handler
244            is invoked should be handled OK:
245
246            - handler invoked before waitpid(): In this case, subprocess
247            status will be set by sigchld_handler.  waitpid() here will
248            return -1 with errno set to ECHILD, which is a valid exit
249            condition.
250
251            - handler invoked during waitpid(): as above, except that errno
252            here will be set to EINTR.  This will cause waitpid() to be
253            called again, and this time it will exit with ECHILD.
254
255            - handler invoked after waitpid(): The following code will reap
256            the subprocess. In the handler, wait() will return -1 because
257            there is no child to reap, and the handler will exit without
258            modifying child subprocess status.  */
259         int ret, status;
260
261         /* Because the SIGCHLD handler can potentially reap the synchronous
262            subprocess, we should take care of that.  */
263
264         /* Will stay in the do loop as long as:
265            1. Process is alive
266            2. Ctrl-G is not pressed */
267         do {
268                 QUIT;
269                 ret = waitpid(pid, &status, 0);
270                 /* waitpid returns 0 if the process is still alive. */
271         }
272         while (ret == 0 || (ret == -1 && errno == EINTR));
273
274         if (ret == pid)
275         {                       /* Success */
276                 /* Set synch process globals.  This is can also happen
277                    in sigchld_handler, and that code is duplicated. */
278                 synch_process_alive = 0;
279                 if (WIFEXITED(status))
280                         synch_process_retcode = WEXITSTATUS(status);
281                 else if (WIFSIGNALED(status))
282                         synch_process_death = signal_name(WTERMSIG(status));
283         }
284         /* On exiting the loop, ret will be -1, with errno set to ECHILD if
285            the child has already been reaped, e.g. in the signal handler.  */
286
287         /* Otherwise, we've had some error condition here.
288            Per POSIX, the only other possibilities are:
289            - EFAULT (bus error accessing arg 2) or
290            - EINVAL (incorrect arguments),
291            which are both program bugs.
292
293            Since implementations may add their own error indicators on top,
294            we ignore it by default.  */
295 #elif defined (EMACS_BLOCK_SIGNAL) && !defined (BROKEN_WAIT_FOR_SIGNAL) && defined (SIGCHLD)
296         while (1) {
297                 static int wait_debugging = 0;  /* Set nonzero to make following
298                                                    function work under dbx (at least for bsd).  */
299                 QUIT;
300                 if (wait_debugging)
301                         return;
302
303                 EMACS_BLOCK_SIGNAL(SIGCHLD);
304                 /* Block SIGCHLD from happening during this check,
305                    to avoid race conditions. */
306                 if (kill(pid, 0) < 0) {
307                         EMACS_UNBLOCK_SIGNAL(SIGCHLD);
308                         return;
309                 } else
310                         /* WARNING: Whatever this macro does *must* not allow SIGCHLD
311                            to happen between the time that it's reenabled and when we
312                            begin to block.  Otherwise we may end up blocking for a
313                            signal that has already arrived and isn't coming again.
314                            Can you say "race condition"?
315
316                            I assume that the system calls sigpause() or sigsuspend()
317                            to provide this atomicness.  If you're getting hangs in
318                            sigpause()/sigsuspend(), then your OS doesn't implement
319                            this properly (this applies under hpux9, for example).
320                            Try defining BROKEN_WAIT_FOR_SIGNAL. */
321                         EMACS_WAIT_FOR_SIGNAL(SIGCHLD);
322         }
323 #else                           /* not HAVE_WAITPID and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */
324         /* This approach is kind of cheesy but is guaranteed(?!) to work
325            for all systems. */
326         while (1) {
327                 QUIT;
328                 if (kill(pid, 0) < 0)
329                         return;
330                 emacs_sleep(1);
331         }
332 #endif                          /* OS features */
333 }
334
335 #if !defined (NO_SUBPROCESSES)
336
337 /*
338  *      flush any pending output
339  *      (may flush input as well; it does not matter the way we use it)
340  */
341
342 void flush_pending_output(int channel)
343 {
344 #ifdef HAVE_TERMIOS
345         /* If we try this, we get hit with SIGTTIN, because
346            the child's tty belongs to the child's pgrp. */
347 #elif defined (TCFLSH)
348         ioctl(channel, TCFLSH, 1);
349 #elif defined (TIOCFLUSH)
350         int zero = 0;
351         /* 3rd arg should be ignored
352            but some 4.2 kernels actually want the address of an int
353            and nonzero means something different.  */
354         ioctl(channel, TIOCFLUSH, &zero);
355 #endif
356 }
357
358 /*  Set up the terminal at the other end of a pseudo-terminal that
359     we will be controlling an inferior through.
360     It should not echo or do line-editing, since that is done
361     in Emacs.  No padding needed for insertion into an Emacs buffer.  */
362
363 void child_setup_tty(int out)
364 {
365         struct emacs_tty s;
366         emacs_get_tty(out, &s);
367
368 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
369         assert(isatty(out));
370         s.main.c_oflag |= OPOST;        /* Enable output postprocessing */
371         s.main.c_oflag &= ~ONLCR;       /* Disable map of NL to CR-NL on output */
372 #ifdef NLDLY
373         s.main.c_oflag &= ~(NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
374         /* No output delays */
375 #endif
376         s.main.c_lflag &= ~ECHO;        /* Disable echo */
377         s.main.c_lflag |= ISIG; /* Enable signals */
378 #ifdef IUCLC
379         s.main.c_iflag &= ~IUCLC;       /* Disable downcasing on input.  */
380 #endif
381 #ifdef OLCUC
382         s.main.c_oflag &= ~OLCUC;       /* Disable upcasing on output.  */
383 #endif
384         s.main.c_oflag &= ~TAB3;        /* Disable tab expansion */
385 #if defined (CSIZE) && defined (CS8)
386         s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8;       /* Don't strip 8th bit */
387 #endif
388 #ifdef ISTRIP
389         s.main.c_iflag &= ~ISTRIP;      /* Don't strip 8th bit on input */
390 #endif
391 #if 0
392         /* Unnecessary as long as ICANON is set */
393         s.main.c_cc[VMIN] = 1;  /* minimum number of characters to accept  */
394         s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character  */
395 #endif                          /* 0 */
396
397         s.main.c_lflag |= ICANON;       /* Enable erase/kill and eof processing */
398         s.main.c_cc[VEOF] = 04; /* ensure that EOF is Control-D */
399         s.main.c_cc[VERASE] = _POSIX_VDISABLE;  /* disable erase processing */
400         s.main.c_cc[VKILL] = _POSIX_VDISABLE;   /* disable kill processing */
401
402 #ifdef HPUX
403         s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;     /* baud rate sanity */
404 #endif                          /* HPUX */
405
406 #ifdef AIX
407 #ifndef IBMR2AIX
408         /* AIX enhanced edit loses NULs, so disable it. */
409         s.main.c_line = 0;
410         s.main.c_iflag &= ~ASCEDIT;
411 #endif                          /* IBMR2AIX */
412         /* Also, PTY overloads NUL and BREAK.
413            don't ignore break, but don't signal either, so it looks like NUL.
414            This really serves a purpose only if running in an XTERM window
415            or via TELNET or the like, but does no harm elsewhere.  */
416         s.main.c_iflag &= ~IGNBRK;
417         s.main.c_iflag &= ~BRKINT;
418 #endif                          /* AIX */
419 #ifdef SIGNALS_VIA_CHARACTERS
420         /* TTY `special characters' are used in process_send_signal
421            so set them here to something useful.  */
422         s.main.c_cc[VQUIT] = '\\' & 037;        /* Control-\ */
423         s.main.c_cc[VINTR] = 'C' & 037; /* Control-C */
424         s.main.c_cc[VSUSP] = 'Z' & 037; /* Control-Z */
425 #else                           /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
426         /* TTY `special characters' work better as signals, so disable
427            character forms */
428         s.main.c_cc[VQUIT] = _POSIX_VDISABLE;
429         s.main.c_cc[VINTR] = _POSIX_VDISABLE;
430         s.main.c_cc[VSUSP] = _POSIX_VDISABLE;
431         s.main.c_lflag &= ~ISIG;
432 #endif                          /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
433         s.main.c_cc[VEOL] = _POSIX_VDISABLE;
434 #if defined (CBAUD)
435         /* <mdiers> #### This is not portable. ###
436            POSIX does not specify CBAUD, and 4.4BSD does not have it.
437            Instead, POSIX suggests to use cfset{i,o}speed().
438            [cf. D. Lewine, POSIX Programmer's Guide, Chapter 8: Terminal
439            I/O, O'Reilly 1991] */
440         s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;     /* baud rate sanity */
441 #else
442         /* <mdiers> What to do upon failure? Just ignoring rc is probably
443            not acceptable, is it? */
444         if (cfsetispeed(&s.main, B9600) == -1)  /* ignore */
445                 ;
446         if (cfsetospeed(&s.main, B9600) == -1)  /* ignore */
447                 ;
448 #endif                          /* defined (CBAUD) */
449
450 #else                           /* not HAVE_TERMIO */
451
452         s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
453                              | CBREAK | TANDEM);
454         s.main.sg_flags |= LPASS8;
455         s.main.sg_erase = 0377;
456         s.main.sg_kill = 0377;
457         s.lmode = LLITOUT | s.lmode;    /* Don't strip 8th bit */
458
459 #endif                          /* not HAVE_TERMIO */
460         emacs_set_tty(out, &s, 0);
461
462 #ifdef RTU
463         {
464                 int zero = 0;
465                 ioctl(out, FIOASYNC, &zero);
466         }
467 #endif                          /* RTU */
468 }
469 #endif                          /* not NO_SUBPROCESSES */
470 \f
471 #if !defined (SIGTSTP) && !defined (USG_JOBCTRL)
472
473 #if defined(__STDC__) || defined(_MSC_VER)
474 #define SIG_PARAM_TYPE int
475 #else
476 #define SIG_PARAM_TYPE
477 #endif
478
479 /* Record a signal code and the handler for it.  */
480 struct save_signal {
481         int code;
482          SIGTYPE(*handler) (SIG_PARAM_TYPE);
483 };
484
485 static void save_signal_handlers(struct save_signal *saved_handlers)
486 {
487         while (saved_handlers->code) {
488                 saved_handlers->handler
489                     =
490                     (SIGTYPE(*)(SIG_PARAM_TYPE)) signal(saved_handlers->code,
491                                                         SIG_IGN);
492                 saved_handlers++;
493         }
494 }
495
496 static void restore_signal_handlers(struct save_signal *saved_handlers)
497 {
498         while (saved_handlers->code) {
499                 signal(saved_handlers->code, saved_handlers->handler);
500                 saved_handlers++;
501         }
502 }
503
504 /* Fork a subshell.  */
505 static void sys_subshell(void)
506 {
507         int pid;
508         struct save_signal saved_handlers[5];
509         Lisp_Object dir;
510         unsigned char *str = 0;
511         int len;
512         struct gcpro gcpro1;
513
514         saved_handlers[0].code = SIGINT;
515         saved_handlers[1].code = SIGQUIT;
516         saved_handlers[2].code = SIGTERM;
517 #ifdef SIGIO
518         saved_handlers[3].code = SIGIO;
519         saved_handlers[4].code = 0;
520 #else
521         saved_handlers[3].code = 0;
522 #endif
523
524         /* Mentioning current_buffer->buffer would mean including buffer.h,
525            which somehow wedges the hp compiler.  So instead...  */
526
527         if (NILP(Fboundp(Qdefault_directory)))
528                 goto xyzzy;
529         dir = Fsymbol_value(Qdefault_directory);
530         if (!STRINGP(dir))
531                 goto xyzzy;
532
533         GCPRO1(dir);
534         dir = Funhandled_file_name_directory(dir);
535         dir = expand_and_dir_to_file(dir, Qnil);
536         UNGCPRO;
537         str = (unsigned char *)alloca(XSTRING_LENGTH(dir) + 2);
538         len = XSTRING_LENGTH(dir);
539         memcpy(str, XSTRING_DATA(dir), len);
540         if (!IS_ANY_SEP(str[len - 1]))
541                 str[len++] = DIRECTORY_SEP;
542         str[len] = 0;
543       xyzzy:
544
545         pid = fork();
546
547         if (pid == -1)
548                 error("Can't spawn subshell");
549         if (pid == 0)
550         {
551                 char *sh = 0;
552
553                 if (sh == 0)
554                         sh = (char *)egetenv("SHELL");
555                 if (sh == 0)
556                         sh = "sh";
557
558                 /* Use our buffer's default directory for the subshell.  */
559                 if (str)
560                         sys_chdir(str);
561
562 #if !defined (NO_SUBPROCESSES)
563                 close_process_descs();  /* Close Emacs's pipes/ptys */
564 #endif
565
566 #ifdef SET_EMACS_PRIORITY
567                 if (emacs_priority != 0)
568                         nice(-emacs_priority);  /* Give the new shell the default priority */
569 #endif
570
571                 execlp(sh, sh, 0);
572                 write(1, "Can't execute subshell", 22);
573                 _exit(1);
574         }
575
576         save_signal_handlers(saved_handlers);
577         synch_process_alive = 1;
578         wait_for_termination(pid);
579         restore_signal_handlers(saved_handlers);
580 }
581 #endif                          /* !defined (SIGTSTP) && !defined (USG_JOBCTRL) */
582 \f
583 /* Suspend the Emacs process; give terminal to its superior.  */
584 void sys_suspend(void)
585 {
586 #if defined (SIGTSTP)
587         {
588                 int pgrp = EMACS_GET_PROCESS_GROUP();
589                 EMACS_KILLPG(pgrp, SIGTSTP);
590         }
591
592 #elif defined (USG_JOBCTRL)
593         /* If you don't know what this is don't mess with it */
594         ptrace(0, 0, 0, 0);     /* set for ptrace - caught by csh */
595         kill(getpid(), SIGQUIT);
596
597 #else                           /* No SIGTSTP or USG_JOBCTRL */
598
599         /* On a system where suspending is not implemented,
600            instead fork a subshell and let it talk directly to the terminal
601            while we wait.  */
602         sys_subshell();
603
604 #endif
605 }
606
607 /* Suspend a process if possible; give terminal to its superior.  */
608 void sys_suspend_process(int process)
609 {
610         /* I don't doubt that it is possible to suspend processes on
611          * VMS machines or thost that use USG_JOBCTRL,
612          * but I don't know how to do it, so...
613          */
614 #if defined (SIGTSTP)
615         kill(process, SIGTSTP);
616 #endif
617 }
618 \f
619 /* Given FD, obtain pty buffer size. When no luck, a good guess is made,
620    so that the function works even when fd is not a pty. */
621
622 int get_pty_max_bytes(int fd)
623 {
624         /* DEC OSF 4.0 fpathconf returns 255, but xemacs hangs on long shell
625            input lines if we return 253.  252 is OK!.  So let's leave a bit
626            of slack for the newline that xemacs will insert, and for those
627            inevitable vendor off-by-one-or-two-or-three bugs. */
628 #define MAX_CANON_SLACK 10
629 #define SAFE_MAX_CANON (127 - MAX_CANON_SLACK)
630 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
631         {
632                 int max_canon = fpathconf(fd, _PC_MAX_CANON);
633 #ifdef __hpux__
634                 /* HP-UX 10.20 fpathconf returns 768, but this results in
635                    truncated input lines, while 255 works. */
636                 if (max_canon > 255)
637                         max_canon = 255;
638 #endif
639                 return (max_canon < 0 ? SAFE_MAX_CANON :
640                         max_canon >
641                         SAFE_MAX_CANON ? max_canon -
642                         MAX_CANON_SLACK : max_canon);
643         }
644 #elif defined (_POSIX_MAX_CANON)
645         return (_POSIX_MAX_CANON > SAFE_MAX_CANON ?
646                 _POSIX_MAX_CANON - MAX_CANON_SLACK : _POSIX_MAX_CANON);
647 #else
648         return SAFE_MAX_CANON;
649 #endif
650 }
651
652 /* Figure out the eof character for the FD. */
653
654 Bufbyte get_eof_char(int fd)
655 {
656         const Bufbyte ctrl_d = (Bufbyte) '\004';
657
658         if (!isatty(fd))
659                 return ctrl_d;
660 #ifdef HAVE_TERMIOS
661         {
662                 struct termios t;
663                 tcgetattr(fd, &t);
664 #if 0
665                 /* What is the following line designed to do??? -mrb */
666                 if (strlen((const char *)t.c_cc) < (unsigned int)(VEOF + 1))
667                         return ctrl_d;
668                 else
669                         return (Bufbyte) t.c_cc[VEOF];
670 #endif
671                 return t.c_cc[VEOF] ==
672                     _POSIX_VDISABLE ? ctrl_d : (Bufbyte) t.c_cc[VEOF];
673         }
674 #else                           /* ! HAVE_TERMIOS */
675         /* On Berkeley descendants, the following IOCTL's retrieve the
676            current control characters.  */
677 #if defined (TIOCGETC)
678         {
679                 struct tchars c;
680                 ioctl(fd, TIOCGETC, &c);
681                 return (Bufbyte) c.t_eofc;
682         }
683 #else                           /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
684         /* On SYSV descendants, the TCGETA ioctl retrieves the current control
685            characters.  */
686 #ifdef TCGETA
687         {
688                 struct termio t;
689                 ioctl(fd, TCGETA, &t);
690                 if (strlen((const char *)t.c_cc) < (unsigned int)(VINTR + 1))
691                         return ctrl_d;
692                 else
693                         return (Bufbyte) t.c_cc[VINTR];
694         }
695 #else                           /* ! defined (TCGETA) */
696         /* Rather than complain, we'll just guess ^D, which is what
697          * earlier emacsen always used. */
698         return ctrl_d;
699 #endif                          /* ! defined (TCGETA) */
700 #endif                          /* ! defined (TIOCGETC) */
701 #endif                          /* ! defined (HAVE_TERMIOS) */
702 }
703
704 /* Set the logical window size associated with descriptor FD
705    to HEIGHT and WIDTH.  This is used mainly with ptys.  */
706
707 int set_window_size(int fd, int height, int width)
708 {
709 #ifdef TIOCSWINSZ
710
711         /* BSD-style.  */
712         struct winsize size;
713         size.ws_row = height;
714         size.ws_col = width;
715
716         if (ioctl(fd, TIOCSWINSZ, &size) == -1)
717                 return 0;       /* error */
718         else
719                 return 1;
720
721 #elif defined (TIOCSSIZE)
722
723         /* SunOS - style.  */
724         struct ttysize size;
725         size.ts_lines = height;
726         size.ts_cols = width;
727
728         if (ioctl(fd, TIOCGSIZE, &size) == -1)
729                 return 0;
730         else
731                 return 1;
732 #else
733         return -1;
734 #endif
735 }
736
737 #ifdef HAVE_PTYS
738
739 /* Set up the proper status flags for use of a pty.  */
740
741 void setup_pty(int fd)
742 {
743         /* I'm told that TIOCREMOTE does not mean control chars
744            "can't be sent" but rather that they don't have
745            input-editing or signaling effects.
746            That should be good, because we have other ways
747            to do those things in Emacs.
748            However, telnet mode seems not to work on 4.2.
749            So TIOCREMOTE is turned off now. */
750
751         /* Under hp-ux, if TIOCREMOTE is turned on, some calls
752            will hang.  In particular, the "timeout" feature (which
753            causes a read to return if there is no data available)
754            does this.  Also it is known that telnet mode will hang
755            in such a way that Emacs must be stopped (perhaps this
756            is the same problem).
757
758            If TIOCREMOTE is turned off, then there is a bug in
759            hp-ux which sometimes loses data.  Apparently the
760            code which blocks the master process when the internal
761            buffer fills up does not work.  Other than this,
762            though, everything else seems to work fine.
763
764            Since the latter lossage is more benign, we may as well
765            lose that way.  -- cph */
766 #if defined (FIONBIO) && defined (SYSV_PTYS)
767         {
768                 int on = 1;
769                 ioctl(fd, FIONBIO, &on);
770         }
771 #endif
772 #ifdef IBMRTAIX
773         /* On AIX, the parent gets SIGHUP when a pty attached child dies.  So, we */
774         /* ignore SIGHUP once we've started a child on a pty.  Note that this may */
775         /* cause EMACS not to die when it should, i.e., when its own controlling  */
776         /* tty goes away.  I've complained to the AIX developers, and they may    */
777         /* change this behavior, but I'm not going to hold my breath.             */
778         signal(SIGHUP, SIG_IGN);
779 #endif
780 #ifdef TIOCPKT
781         /* In some systems (Linux through 2.0.0, at least), packet mode doesn't
782            get cleared when a pty is closed, so we need to clear it here.
783            Linux pre2.0.13 contained an attempted fix for this (from Ted Ts'o,
784            tytso@mit.edu), but apparently it messed up rlogind and telnetd, so he
785            removed the fix in pre2.0.14.     - dkindred@cs.cmu.edu
786          */
787         {
788                 int off = 0;
789                 ioctl(fd, TIOCPKT, (char *)&off);
790         }
791 #endif
792 }
793 #endif                          /* HAVE_PTYS */
794 \f
795 /************************************************************************/
796 /*                            TTY control                               */
797 /************************************************************************/
798
799 /* ------------------------------------------------------ */
800 /*                     get baud rate                      */
801 /* ------------------------------------------------------ */
802
803 /* It really makes more sense for the baud-rate to be console-specific
804    and not device-specific, but it's (at least potentially) used for output
805    decisions. */
806
807 void init_baud_rate(struct device *d)
808 {
809         struct console *con = XCONSOLE(DEVICE_CONSOLE(d));
810         if (DEVICE_WIN_P(d) || DEVICE_STREAM_P(d)) {
811                 DEVICE_BAUD_RATE(d) = 38400;
812                 return;
813         }
814 #ifdef HAVE_TTY
815         assert(DEVICE_TTY_P(d));
816         {
817                 int input_fd = CONSOLE_TTY_DATA(con)->infd;
818 #if defined (HAVE_TERMIOS)
819                 struct termios sg;
820
821                 sg.c_cflag = B9600;
822                 tcgetattr(input_fd, &sg);
823                 DEVICE_TTY_DATA(d)->ospeed = cfgetospeed(&sg);
824 # if defined (USE_GETOBAUD) && defined (getobaud)
825                 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
826                 if (DEVICE_TTY_DATA(d)->ospeed == 0)
827                         DEVICE_TTY_DATA(d)->ospeed = getobaud(sg.c_cflag);
828 # endif
829 #elif defined (HAVE_TERMIO)
830                 struct termio sg;
831
832                 sg.c_cflag = B9600;
833 # ifdef HAVE_TCATTR
834                 tcgetattr(input_fd, &sg);
835 # else
836                 ioctl(input_fd, TCGETA, &sg);
837 # endif
838                 DEVICE_TTY_DATA(d)->ospeed = sg.c_cflag & CBAUD;
839 #else                           /* neither TERMIOS nor TERMIO */
840                 struct sgttyb sg;
841
842                 sg.sg_ospeed = B9600;
843                 if (ioctl(input_fd, TIOCGETP, &sg) < 0)
844                         abort();
845                 DEVICE_TTY_DATA(d)->ospeed = sg.sg_ospeed;
846 #endif
847         }
848
849         DEVICE_BAUD_RATE(d) =
850             (DEVICE_TTY_DATA(d)->ospeed < countof(baud_convert)
851              ? baud_convert[DEVICE_TTY_DATA(d)->ospeed]
852              : 9600);
853
854         if (DEVICE_BAUD_RATE(d) == 0)
855                 DEVICE_BAUD_RATE(d) = 1200;
856 #endif                          /* HAVE_TTY */
857 }
858 \f
859 /* ------------------------------------------------------ */
860 /*                       SIGIO control                    */
861 /* ------------------------------------------------------ */
862
863 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
864
865 static void init_sigio_on_device(struct device *d)
866 {
867         int filedesc = DEVICE_INFD(d);
868
869 #if defined (FIOSSAIOOWN)
870         {                       /* HPUX stuff */
871                 int owner = getpid();
872                 int ioctl_status;
873                 if (DEVICE_TTY_P(d)) {
874                         ioctl_status = ioctl(filedesc, FIOGSAIOOWN,
875                                              &DEVICE_OLD_FCNTL_OWNER(d));
876                         ioctl_status = ioctl(filedesc, FIOSSAIOOWN, &owner);
877                 }
878 #ifdef HAVE_WINDOW_SYSTEM
879                 else if (!DEVICE_STREAM_P(d)) {
880                         ioctl_status = ioctl(filedesc, SIOCGPGRP,
881                                              &DEVICE_OLD_FCNTL_OWNER(d));
882                         ioctl_status = ioctl(filedesc, SIOCSPGRP, &owner);
883                 }
884 #endif
885         }
886 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG)
887         DEVICE_OLD_FCNTL_OWNER(d) = fcntl(filedesc, F_GETOWN, 0);
888 # ifdef F_SETOWN_SOCK_NEG
889         /* stdin is a socket here */
890         fcntl(filedesc, F_SETOWN, -getpid());
891 # else
892         fcntl(filedesc, F_SETOWN, getpid());
893 # endif
894 #endif
895 }
896
897 static void reset_sigio_on_device(struct device *d)
898 {
899         int filedesc = DEVICE_INFD(d);
900
901 #if defined (FIOSSAIOOWN)
902         {                       /* HPUX stuff */
903                 int ioctl_status;
904                 if (DEVICE_TTY_P(d)) {
905                         ioctl_status = ioctl(filedesc, FIOSSAIOOWN,
906                                              &DEVICE_OLD_FCNTL_OWNER(d));
907                 }
908 #ifdef HAVE_WINDOW_SYSTEM
909                 else if (!DEVICE_STREAM_P(d)) {
910                         ioctl_status = ioctl(filedesc, SIOCSPGRP,
911                                              &DEVICE_OLD_FCNTL_OWNER(d));
912                 }
913 #endif
914         }
915 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG)
916         fcntl(filedesc, F_SETOWN, DEVICE_OLD_FCNTL_OWNER(d));
917 #endif
918 }
919
920 static void request_sigio_on_device(struct device *d)
921 {
922         int filedesc = DEVICE_INFD(d);
923
924 #if defined (I_SETSIG) && !defined(HPUX10) && !defined(LINUX)
925         {
926                 int events = 0;
927                 ioctl(filedesc, I_GETSIG, &events);
928                 ioctl(filedesc, I_SETSIG, events | S_INPUT);
929         }
930 #elif defined (FASYNC)
931         fcntl(filedesc, F_SETFL, fcntl(filedesc, F_GETFL, 0) | FASYNC);
932 #elif defined (FIOSSAIOSTAT)
933         {
934                 /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for
935                    sockets and other devices for some bizarre reason. We guess
936                    that an X device is a socket, and tty devices aren't. We then
937                    use the following crud to do the appropriate thing. */
938                 int on = 1;
939                 int ioctl_status;       /* ####DG: check if IOCTL succeeds here. */
940
941                 if (DEVICE_TTY_P(d)) {
942                         ioctl_status = ioctl(filedesc, FIOSSAIOSTAT, &on);
943                 }
944 #ifdef HAVE_WINDOW_SYSTEM
945                 else if (!DEVICE_STREAM_P(d)) {
946                         ioctl_status = ioctl(filedesc, FIOASYNC, &on);
947                 }
948 #endif
949         }
950 #elif defined (FIOASYNC)
951         {
952                 int on = 1;
953                 ioctl(filedesc, FIOASYNC, &on);
954         }
955 #endif
956
957 #if defined (_CX_UX)            /* #### Is this crap necessary? */
958         EMACS_UNBLOCK_SIGNAL(SIGIO);
959 #endif
960 }
961
962 static void unrequest_sigio_on_device(struct device *d)
963 {
964         int filedesc = DEVICE_INFD(d);
965
966 #if defined (I_SETSIG) && !defined(HPUX10)
967         {
968                 int events = 0;
969                 ioctl(filedesc, I_GETSIG, &events);
970                 ioctl(filedesc, I_SETSIG, events & ~S_INPUT);
971         }
972 #elif defined (FASYNC)
973         fcntl(filedesc, F_SETFL, fcntl(filedesc, F_GETFL, 0) & ~FASYNC);
974 #elif defined (FIOSSAIOSTAT)
975         {
976                 /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for
977                    sockets and other devices for some bizarre reason. We guess
978                    that an X device is a socket, and tty devices aren't. We then
979                    use the following crud to do the appropriate thing. */
980
981                 int off = 0;
982                 int ioctl_status;
983
984                 /* See comment for request_sigio_on_device */
985
986                 if (DEVICE_TTY_P(d)) {
987                         ioctl_status = ioctl(filedesc, FIOSSAIOSTAT, &off);
988                 } else {
989                         ioctl_status = ioctl(filedesc, FIOASYNC, &off);
990                 }
991         }
992 #elif defined (FIOASYNC)
993         {
994                 int off = 0;
995                 ioctl(filedesc, FIOASYNC, &off);
996         }
997 #endif
998 }
999
1000 void request_sigio(void)
1001 {
1002         Lisp_Object devcons, concons;
1003
1004         DEVICE_LOOP_NO_BREAK(devcons, concons) {
1005                 struct device *d;
1006
1007                 d = XDEVICE(XCAR(devcons));
1008
1009                 if (!DEVICE_STREAM_P(d))
1010                         request_sigio_on_device(d);
1011         }
1012 }
1013
1014 void unrequest_sigio(void)
1015 {
1016         Lisp_Object devcons, concons;
1017
1018         DEVICE_LOOP_NO_BREAK(devcons, concons) {
1019                 struct device *d;
1020
1021                 d = XDEVICE(XCAR(devcons));
1022
1023                 if (!DEVICE_STREAM_P(d))
1024                         unrequest_sigio_on_device(d);
1025         }
1026 }
1027
1028 #endif                          /* SIGIO */
1029 \f
1030 /* ------------------------------------------------------ */
1031 /*             Changing Emacs's process group             */
1032 /* ------------------------------------------------------ */
1033
1034 /* Saving and restoring the process group of Emacs's terminal.  */
1035
1036 /* On some systems, apparently (?!) Emacs must be in its own process
1037    group in order to receive SIGIO correctly.  On other systems
1038    (e.g. Solaris), it's not required and doing it makes things
1039    get fucked up.  So, we only do it when
1040    SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP is defined.  Basically,
1041    this is only required for BSD 4.2 systems. (Actually, I bet
1042    we don't have to do this at all -- those systems also
1043    required interrupt input, which we don't support.)
1044
1045    If Emacs was in its own process group (i.e. inherited_pgroup ==
1046    getpid ()), then we know we're running under a shell with job
1047    control (Emacs would never be run as part of a pipeline).
1048    Everything is fine.
1049
1050    If Emacs was not in its own process group, then we know we're
1051    running under a shell (or a caller) that doesn't know how to
1052    separate itself from Emacs (like sh).  Emacs must be in its own
1053    process group in order to receive SIGIO correctly.  In this
1054    situation, we put ourselves in our own pgroup, forcibly set the
1055    tty's pgroup to our pgroup, and make sure to restore and reinstate
1056    the tty's pgroup just like any other terminal setting.  If
1057    inherited_group was not the tty's pgroup, then we'll get a
1058    SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1059    it goes foreground in the future, which is what should happen.  */
1060
1061 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1062
1063 static pid_t inherited_pgroup;
1064 static pid_t inherited_tty_pgroup;
1065
1066 #endif
1067
1068 void munge_tty_process_group(void)
1069 {
1070 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1071         if (noninteractive)
1072                 return;
1073
1074         /* Only do this munging if we have a device on the controlling
1075            terminal.  See the large comment below. */
1076
1077         if (CONSOLEP(Vcontrolling_terminal) &&
1078             CONSOLE_LIVE_P(XCONSOLE(Vcontrolling_terminal))) {
1079                 int fd = open("/dev/tty", O_RDWR, 0);
1080                 pid_t me = getpid();
1081                 EMACS_BLOCK_SIGNAL(SIGTTOU);
1082                 EMACS_SET_TTY_PROCESS_GROUP(fd, &me);
1083                 EMACS_UNBLOCK_SIGNAL(SIGTTOU);
1084                 close(fd);
1085         }
1086 #endif
1087 }
1088
1089 /* Split off the foreground process group to Emacs alone.
1090    When we are in the foreground, but not started in our own process
1091    group, redirect the TTY to point to our own process group.  We need
1092    to be in our own process group to receive SIGIO properly.  */
1093 static void munge_process_groups(void)
1094 {
1095 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1096         if (noninteractive)
1097                 return;
1098
1099         EMACS_SEPARATE_PROCESS_GROUP();
1100
1101         munge_tty_process_group();
1102 #endif
1103 }
1104
1105 void unmunge_tty_process_group(void)
1106 {
1107 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1108         {
1109                 int fd = open("/dev/tty", O_RDWR, 0);
1110                 EMACS_BLOCK_SIGNAL(SIGTTOU);
1111                 EMACS_SET_TTY_PROCESS_GROUP(fd, &inherited_tty_pgroup);
1112                 EMACS_UNBLOCK_SIGNAL(SIGTTOU);
1113                 close(fd);
1114         }
1115 #endif
1116 }
1117
1118 /* Set the tty to our original foreground group.
1119    Also restore the original process group (put us back into sh's
1120    process group), so that ^Z will suspend both us and sh. */
1121 static void unmunge_process_groups(void)
1122 {
1123 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1124         if (noninteractive)
1125                 return;
1126
1127         unmunge_tty_process_group();
1128
1129         EMACS_SET_PROCESS_GROUP(inherited_pgroup);
1130 #endif
1131 }
1132
1133 /* According to some old wisdom, we need to be in a separate process
1134    group for SIGIO to work correctly (at least on some systems ...).
1135    So go ahead and put ourselves into our own process group.  This
1136    will fail if we're already in our own process group, but who cares.
1137    Also record whether we were in our own process group. (In general,
1138    we will already be in our own process group if we were started from
1139    a job-control shell like csh, but not if we were started from sh).
1140
1141    If we succeeded in changing our process group, then we will no
1142    longer be in the foreground process group of our controlling
1143    terminal.  Therefore, if we have a console open onto this terminal,
1144    we have to change the controlling terminal's foreground process
1145    group (otherwise we will get stopped with a SIGTTIN signal when
1146    attempting to read from the terminal).  It's important,
1147    however, that we do this *only* when we have a console open onto
1148    the terminal.  It's a decidedly bad idea to do so otherwise,
1149    especially if XEmacs was started from the background. */
1150
1151 void init_process_group(void)
1152 {
1153 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1154         if (!noninteractive) {
1155                 int fd = open("/dev/tty", O_RDWR, 0);
1156                 inherited_pgroup = EMACS_GET_PROCESS_GROUP();
1157                 EMACS_GET_TTY_PROCESS_GROUP(fd, &inherited_tty_pgroup);
1158                 close(fd);
1159                 EMACS_SEPARATE_PROCESS_GROUP();
1160         }
1161 #endif
1162 }
1163
1164 void disconnect_controlling_terminal(void)
1165 {
1166 #  ifdef HAVE_SETSID
1167         /* Controlling terminals are attached to a session.
1168            Create a new session for us; it will have no controlling
1169            terminal.  This also, of course, puts us in our own
1170            process group. */
1171         setsid();
1172 #  else
1173         /* Put us in our own process group. */
1174         EMACS_SEPARATE_PROCESS_GROUP();
1175 #    if defined (TIOCNOTTY)
1176         /* This is the older way of disconnecting the controlling
1177            terminal, on 4.3 BSD.  We must open /dev/tty; using
1178            filedesc 0 is not sufficient because it could be
1179            something else (e.g. our stdin was redirected to
1180            another terminal).
1181          */
1182         {
1183                 int j = open("/dev/tty", O_RDWR, 0);
1184                 ioctl(j, TIOCNOTTY, 0);
1185                 close(j);
1186         }
1187 #    endif                      /* TIOCNOTTY */
1188         /*
1189            On systems without TIOCNOTTY and without
1190            setsid(), we don't need to do anything more to
1191            disconnect our controlling terminal.  Here is
1192            what the man page for termio(7) from a SYSV 3.2
1193            system says:
1194
1195            "The first terminal file opened by the process group leader
1196            of a terminal file not already associated with a process
1197            group becomes the control terminal for that process group.
1198            The control terminal plays a special role in handling quit
1199            and interrupt signals, as discussed below.  The control
1200            terminal is inherited by a child process during a fork(2).
1201            A process can break this association by changing its process
1202            group using setpgrp(2)."
1203
1204          */
1205 #  endif                        /* not HAVE_SETSID */
1206 }
1207 \f
1208 /* ------------------------------------------------------ */
1209 /*        Getting and setting emacs_tty structures        */
1210 /* ------------------------------------------------------ */
1211
1212 /* It's wrong to encase these into #ifdef HAVE_TTY because we need
1213    them for child TTY processes.  */
1214 /* However, this does break NT support while we don't do child TTY processes */
1215
1216 /* Set *TC to the parameters associated with the terminal FD.
1217    Return zero if all's well, or -1 if we ran into an error we
1218    couldn't deal with.  */
1219 int emacs_get_tty(int fd, struct emacs_tty *settings)
1220 {
1221         /* Retrieve the primary parameters - baud rate, character size, etcetera.  */
1222 #ifdef HAVE_TCATTR
1223         /* We have those nifty POSIX tcmumbleattr functions.  */
1224         if (tcgetattr(fd, &settings->main) < 0)
1225                 return -1;
1226
1227 #elif defined HAVE_TERMIO
1228         /* The SYSV-style interface?  */
1229         if (ioctl(fd, TCGETA, &settings->main) < 0)
1230                 return -1;
1231
1232 #else
1233         /* I give up - I hope you have the BSD ioctls.  */
1234         if (ioctl(fd, TIOCGETP, &settings->main) < 0)
1235                 return -1;
1236 #endif                          /* HAVE_TCATTR */
1237
1238         /* Suivant - Do we have to get struct ltchars data?  */
1239 #ifdef HAVE_LTCHARS
1240         if (ioctl(fd, TIOCGLTC, &settings->ltchars) < 0)
1241                 return -1;
1242 #endif
1243
1244         /* How about a struct tchars and a wordful of lmode bits?  */
1245 #ifdef HAVE_TCHARS
1246         if (ioctl(fd, TIOCGETC, &settings->tchars) < 0
1247             || ioctl(fd, TIOCLGET, &settings->lmode) < 0)
1248                 return -1;
1249 #endif
1250
1251         /* We have survived the tempest.  */
1252         return 0;
1253 }
1254
1255 /* Set the parameters of the tty on FD according to the contents of
1256    *SETTINGS.  If FLUSHP is non-zero, we discard input.
1257    Return 0 if all went well, and -1 if anything failed.
1258    #### All current callers use FLUSHP == 0. */
1259
1260 int emacs_set_tty(int fd, struct emacs_tty *settings, int flushp)
1261 {
1262         /* Set the primary parameters - baud rate, character size, etcetera.  */
1263 #ifdef HAVE_TCATTR
1264         int i;
1265         /* We have those nifty POSIX tcmumbleattr functions.
1266            William J. Smith <wjs@wiis.wang.com> writes:
1267            "POSIX 1003.1 defines tcsetattr() to return success if it was
1268            able to perform any of the requested actions, even if some
1269            of the requested actions could not be performed.
1270            We must read settings back to ensure tty setup properly.
1271            AIX requires this to keep tty from hanging occasionally."  */
1272         /* This makes sure that we don't loop indefinitely in here.  */
1273         for (i = 0; i < 10; i++)
1274                 if (tcsetattr
1275                     (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0) {
1276                         if (errno == EINTR)
1277                                 continue;
1278                         else
1279                                 return -1;
1280                 } else {
1281                         struct termios new;
1282
1283                         /* Get the current settings, and see if they're what we asked for.  */
1284                         tcgetattr(fd, &new);
1285                         /* We cannot use memcmp on the whole structure here because under
1286                          * aix386 the termios structure has some reserved field that may
1287                          * not be filled in.
1288                          */
1289                         if (new.c_iflag == settings->main.c_iflag
1290                             && new.c_oflag == settings->main.c_oflag
1291                             && new.c_cflag == settings->main.c_cflag
1292                             && new.c_lflag == settings->main.c_lflag
1293                             && memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
1294                                 break;
1295                         else
1296                                 continue;
1297                 }
1298 #elif defined HAVE_TERMIO
1299         /* The SYSV-style interface?  */
1300         if (ioctl(fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1301                 return -1;
1302
1303 #else
1304         /* I give up - I hope you have the BSD ioctls.  */
1305         if (ioctl(fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1306                 return -1;
1307 #endif                          /* HAVE_TCATTR */
1308
1309         /* Suivant - Do we have to get struct ltchars data?  */
1310 #ifdef HAVE_LTCHARS
1311         if (ioctl(fd, TIOCSLTC, &settings->ltchars) < 0)
1312                 return -1;
1313 #endif
1314
1315         /* How about a struct tchars and a wordful of lmode bits?  */
1316 #ifdef HAVE_TCHARS
1317         if (ioctl(fd, TIOCSETC, &settings->tchars) < 0
1318             || ioctl(fd, TIOCLSET, &settings->lmode) < 0)
1319                 return -1;
1320 #endif
1321
1322         /* We have survived the tempest.  */
1323         return 0;
1324 }
1325
1326 \f
1327 /* ------------------------------------------------------ */
1328 /*                 Initializing a device                  */
1329 /* ------------------------------------------------------ */
1330
1331 #ifdef HAVE_TTY
1332
1333 /* This may also be defined in stdio,
1334    but if so, this does no harm,
1335    and using the same name avoids wasting the other one's space.  */
1336
1337 #if ((defined(USG) || defined(DGUX)) && !defined(__STDC__))
1338 char _sobuf[BUFSIZ + 8];
1339 #elif (defined(USG) && !defined(LINUX) && !defined(_SCO_DS)) || defined(IRIX5)
1340 extern unsigned char _sobuf[BUFSIZ + 8];
1341 #else
1342 char _sobuf[BUFSIZ];
1343 #endif
1344
1345 #if defined (TIOCGLTC) && defined (HAVE_LTCHARS)        /* HAVE_LTCHARS */
1346 static struct ltchars new_ltchars = { -1, -1, -1, -1, -1, -1 };
1347 #endif
1348 #ifdef TIOCGETC                 /* HAVE_TCHARS */
1349 #ifdef HAVE_TCHARS
1350 static struct tchars new_tchars = { -1, -1, -1, -1, -1, -1 };
1351 #endif
1352 #endif
1353
1354 static void tty_init_sys_modes_on_device(struct device *d)
1355 {
1356         struct emacs_tty tty;
1357         int input_fd, output_fd;
1358         struct console *con = XCONSOLE(DEVICE_CONSOLE(d));
1359
1360         input_fd = CONSOLE_TTY_DATA(con)->infd;
1361         output_fd = CONSOLE_TTY_DATA(con)->outfd;
1362
1363         emacs_get_tty(input_fd, &CONSOLE_TTY_DATA(con)->old_tty);
1364         tty = CONSOLE_TTY_DATA(con)->old_tty;
1365
1366         con->tty_erase_char = Qnil;
1367
1368 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1369         /* after all those years... */
1370         con->tty_erase_char = make_char(tty.main.c_cc[VERASE]);
1371 #ifdef DGUX
1372         /* This allows meta to be sent on 8th bit.  */
1373         tty.main.c_iflag &= ~INPCK;     /* don't check input for parity */
1374 #endif
1375         tty.main.c_iflag |= (IGNBRK);   /* Ignore break condition */
1376         tty.main.c_iflag &= ~ICRNL;     /* Disable map of CR to NL on input */
1377 #ifdef ISTRIP
1378         tty.main.c_iflag &= ~ISTRIP;    /* don't strip 8th bit on input */
1379 #endif
1380         tty.main.c_lflag &= ~ECHO;      /* Disable echo */
1381         tty.main.c_lflag &= ~ICANON;    /* Disable erase/kill processing */
1382 #ifdef IEXTEN
1383         tty.main.c_lflag &= ~IEXTEN;    /* Disable other editing characters.  */
1384 #endif
1385         tty.main.c_lflag |= ISIG;       /* Enable signals */
1386         if (TTY_FLAGS(con).flow_control) {
1387                 tty.main.c_iflag |= IXON;       /* Enable start/stop output control */
1388 #ifdef IXANY
1389                 tty.main.c_iflag &= ~IXANY;
1390 #endif                          /* IXANY */
1391         } else
1392                 tty.main.c_iflag &= ~IXON;      /* Disable start/stop output control */
1393         tty.main.c_oflag &= ~ONLCR;     /* Disable map of NL to CR-NL
1394                                            on output */
1395         tty.main.c_oflag &= ~TAB3;      /* Disable tab expansion */
1396 #ifdef CS8
1397         if (TTY_FLAGS(con).meta_key) {
1398                 tty.main.c_cflag |= CS8;        /* allow 8th bit on input */
1399                 tty.main.c_cflag &= ~PARENB;    /* Don't check parity */
1400         }
1401 #endif
1402         if (CONSOLE_TTY_DATA(con)->controlling_terminal) {
1403                 tty.main.c_cc[VINTR] = CONSOLE_QUIT_CHAR(con);  /* C-g (usually) gives SIGINT */
1404                 /* Set up C-g for both SIGQUIT and SIGINT.
1405                    We don't know which we will get, but we handle both alike
1406                    so which one it really gives us does not matter.  */
1407                 tty.main.c_cc[VQUIT] = CONSOLE_QUIT_CHAR(con);
1408         } else {
1409                 tty.main.c_cc[VINTR] = _POSIX_VDISABLE;
1410                 tty.main.c_cc[VQUIT] = _POSIX_VDISABLE;
1411         }
1412         tty.main.c_cc[VMIN] = 1;        /* Input should wait for at
1413                                            least 1 char */
1414         tty.main.c_cc[VTIME] = 0;       /* no matter how long that takes.  */
1415 #ifdef VSWTCH
1416         tty.main.c_cc[VSWTCH] = _POSIX_VDISABLE;        /* Turn off shell layering use
1417                                                            of C-z */
1418 #endif                          /* VSWTCH */
1419         /* There was some conditionalizing here on (mips or TCATTR), but
1420            I think that's wrong.  There was one report of C-y (DSUSP) not being
1421            disabled on HP9000s700 systems, and this might fix it. */
1422 #ifdef VSUSP
1423         tty.main.c_cc[VSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-z. */
1424 #endif                          /* VSUSP */
1425 #ifdef V_DSUSP
1426         tty.main.c_cc[V_DSUSP] = _POSIX_VDISABLE;       /* Turn off mips handling of C-y. */
1427 #endif                          /* V_DSUSP */
1428 #ifdef VDSUSP                   /* Some systems have VDSUSP, some have V_DSUSP.  */
1429         tty.main.c_cc[VDSUSP] = _POSIX_VDISABLE;
1430 #endif                          /* VDSUSP */
1431 #ifdef VLNEXT
1432         tty.main.c_cc[VLNEXT] = _POSIX_VDISABLE;
1433 #endif                          /* VLNEXT */
1434 #ifdef VREPRINT
1435         tty.main.c_cc[VREPRINT] = _POSIX_VDISABLE;
1436 #endif                          /* VREPRINT */
1437 #ifdef VWERASE
1438         tty.main.c_cc[VWERASE] = _POSIX_VDISABLE;
1439 #endif                          /* VWERASE */
1440 #ifdef VDISCARD
1441         tty.main.c_cc[VDISCARD] = _POSIX_VDISABLE;
1442 #endif                          /* VDISCARD */
1443 #ifdef VSTART
1444         tty.main.c_cc[VSTART] = _POSIX_VDISABLE;
1445 #endif                          /* VSTART */
1446 #ifdef VSTRT
1447         tty.main.c_cc[VSTRT] = _POSIX_VDISABLE; /* called VSTRT on some systems */
1448 #endif                          /* VSTART */
1449 #ifdef VSTOP
1450         tty.main.c_cc[VSTOP] = _POSIX_VDISABLE;
1451 #endif                          /* VSTOP */
1452 #ifdef SET_LINE_DISCIPLINE
1453         /* Need to explicitly request TERMIODISC line discipline or
1454            Ultrix's termios does not work correctly.  */
1455         tty.main.c_line = SET_LINE_DISCIPLINE;
1456 #endif
1457
1458 #ifdef AIX
1459 #ifndef IBMR2AIX
1460         /* AIX enhanced edit loses NULs, so disable it. */
1461         tty.main.c_line = 0;
1462         tty.main.c_iflag &= ~ASCEDIT;
1463 #else
1464         tty.main.c_cc[VSTRT] = 255;
1465         tty.main.c_cc[VSTOP] = 255;
1466         tty.main.c_cc[VSUSP] = 255;
1467         tty.main.c_cc[VDSUSP] = 255;
1468 #endif                          /* IBMR2AIX */
1469         /* Also, PTY overloads NUL and BREAK.
1470            don't ignore break, but don't signal either, so it looks like NUL.
1471            This really serves a purpose only if running in an XTERM window
1472            or via TELNET or the like, but does no harm elsewhere.  */
1473         tty.main.c_iflag &= ~IGNBRK;
1474         tty.main.c_iflag &= ~BRKINT;
1475 #endif                          /* AIX */
1476 #else                           /* if not HAVE_TERMIO */
1477         con->tty_erase_char = make_char(tty.main.sg_erase);
1478         tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1479         if (TTY_FLAGS(con).meta_key)
1480                 tty.main.sg_flags |= ANYP;
1481         /* #### should we be using RAW mode here? */
1482         tty.main.sg_flags |= /* interrupt_input ? RAW : */ CBREAK;
1483 #endif                          /* not HAVE_TERMIO */
1484
1485         /* If going to use CBREAK mode, we must request C-g to interrupt
1486            and turn off start and stop chars, etc.  If not going to use
1487            CBREAK mode, do this anyway so as to turn off local flow
1488            control for user coming over network on 4.2; in this case,
1489            only t_stopc and t_startc really matter.  */
1490 #ifndef HAVE_TERMIO
1491 #ifdef HAVE_TCHARS
1492         /* Note: if not using CBREAK mode, it makes no difference how we
1493            set this */
1494         tty.tchars = new_tchars;
1495         tty.tchars.t_intrc = CONSOLE_QUIT_CHAR(con);
1496         if (TTY_FLAGS(con).flow_control) {
1497                 tty.tchars.t_startc = '\021';
1498             &nb