📄 sysdep.c
字号:
if (ioctl (1, HFTGETID, &tty) != -1) write (1, "\033[20h", 5); }#endif reset_terminal_modes (); fflush (stdout);#ifdef BSD#ifndef BSD4_1 /* Avoid possible loss of output when changing terminal modes. */ fsync (fileno (stdout));#endif#endif#ifdef TIOCGLTC ioctl (0, TIOCSLTC, &old_ltchars);#endif /* TIOCGLTC */#ifndef HAVE_TERMIO#ifdef TIOCGETC ioctl (0, TIOCSETC, &old_tchars); ioctl (0, TIOCLSET, &old_lmode);#endif /* TIOCGETC */#endif /* not HAVE_TERMIO */#ifdef F_SETFL#ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */ if (interrupt_input) { reset_sigio (); fcntl (0, F_SETOWN, old_fcntl_owner); }#endif /* F_SETOWN */#endif /* F_SETFL */#ifdef BSD4_1 if (interrupt_input) reset_sigio ();#endif /* BSD4_1 */#ifdef VMS end_kbd_input (); SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0, &old_gtty.class, 12, 0, 0, 0, 0);#else /* not VMS */ while (ioctl (0, TCSETAW, &old_gtty) < 0 && errno == EINTR);#endif /* not VMS */#ifdef AIX hft_reset ();#endif}#ifdef HAVE_PTYS/* Set up the proper status flags for use of a pty. */setup_pty (fd) int fd;{ /* I'm told that TOICREMOTE does not mean control chars "can't be sent" but rather that they don't have input-editing or signaling effects. That should be good, because we have other ways to do those things in Emacs. However, telnet mode seems not to work on 4.2. So TIOCREMOTE is turned off now. */ /* Under hp-ux, if TIOCREMOTE is turned on, some calls will hang. In particular, the "timeout" feature (which causes a read to return if there is no data available) does this. Also it is known that telnet mode will hang in such a way that Emacs must be stopped (perhaps this is the same problem). If TIOCREMOTE is turned off, then there is a bug in hp-ux which sometimes loses data. Apparently the code which blocks the master process when the internal buffer fills up does not work. Other than this, though, everything else seems to work fine. Since the latter lossage is more benign, we may as well lose that way. -- cph */#ifdef FIONBIO#ifdef SYSV_PTYS { int on = 1; ioctl (fd, FIONBIO, &on); }#endif#endif#ifdef IBMRTAIX /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */ /* ignore SIGHUP once we've started a child on a pty. Note that this may */ /* cause EMACS not to die when it should, i.e., when its own controlling */ /* tty goes away. I've complained to the AIX developers, and they may */ /* change this behavior, but I'm not going to hold my breath. */ signal (SIGHUP, SIG_IGN);#endif}#endif /* HAVE_PTYS */#ifdef VMS/* Assigning an input channel is done at the start of Emacs execution. This is called each time Emacs is resumed, also, but does nothing because input_chain is no longer zero. */init_vms_input(){ int status; if (input_chan == 0) { status = SYS$ASSIGN (&input_dsc, &input_chan, 0, 0); if (! (status & 1)) LIB$STOP (status); }}/* Deassigning the input channel is done before exiting. */stop_vms_input (){ return SYS$DASSGN (input_chan);}short input_buffer;/* Request reading one character into the keyboard buffer. This is done as soon as the buffer becomes empty. */queue_kbd_input (){ int status; waiting_for_ast = 0; stop_input = 0; status = SYS$QIO (0, input_chan, IO$_READVBLK, &input_iosb, kbd_input_ast, 1, &input_buffer, 1, 0, terminator_mask, 0, 0);}int input_count;/* Ast routine that is called when keyboard input comes in in accord with the SYS$QIO above. */kbd_input_ast (){ register int c = -1; int old_errno = errno; if (waiting_for_ast) SYS$SETEF (input_ef); waiting_for_ast = 0; input_count++;#ifdef ASTDEBUG if (input_count == 25) exit (1); printf ("Ast # %d,", input_count); printf (" iosb = %x, %x, %x, %x", input_iosb.offset, input_iosb.status, input_iosb.termlen, input_iosb.term);#endif if (input_iosb.offset) { c = input_buffer;#ifdef ASTDEBUG printf (", char = 0%o", c);#endif }#ifdef ASTDEBUG printf ("\n"); fflush (stdout); sleep (1);#endif if (! stop_input) queue_kbd_input (); if (c >= 0) kbd_buffer_store_char (c); errno = old_errno;}/* Wait until there is something in kbd_buffer. */wait_for_kbd_input (){ extern int have_process_input, process_exited; /* If already something, avoid doing system calls. */ if (detect_input_pending ()) { return; } /* Clear a flag, and tell ast routine above to set it. */ SYS$CLREF (input_ef); waiting_for_ast = 1; /* Check for timing error: ast happened while we were doing that. */ if (!detect_input_pending ()) { /* No timing error: wait for flag to be set. */ set_waiting_for_input (0); SYS$WFLOR (input_ef, input_eflist); clear_waiting_for_input (0); if (!detect_input_pending ()) /* Check for subprocess input availability */ { int dsp = have_process_input || process_exited; sys$clref (process_ef); if (have_process_input) process_command_input (); if (process_exited) process_exit (); if (dsp) { update_mode_lines++; redisplay_preserve_echo_area (); } } } waiting_for_ast = 0;}/* Get rid of any pending QIO, when we are about to suspend or when we want to throw away pending input. We wait for a positive sign that the AST routine has run and therefore there is no I/O request queued when we return. SYS$SETAST is used to avoid a timing error. */end_kbd_input(){#ifdef ASTDEBUG printf ("At end_kbd_input.\n"); fflush (stdout); sleep (1);#endif if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_char! */ { SYS$CANCEL (input_chan); return; } SYS$SETAST (0); /* Clear a flag, and tell ast routine above to set it. */ SYS$CLREF (input_ef); waiting_for_ast = 1; stop_input = 1; SYS$CANCEL (input_chan); SYS$SETAST (1); SYS$WAITFR (input_ef); waiting_for_ast = 0;}/* Wait for either input available or time interval expiry. */input_wait_timeout (timeval) int timeval; /* Time to wait, in seconds */{ int time [2]; LIB$EMUL (&timeval, &-10000000, &0, time); /* Convert to VMS format */ /* If already something, avoid doing system calls. */ if (detect_input_pending ()) { return; } /* Clear a flag, and tell ast routine above to set it. */ SYS$CLREF (input_ef); waiting_for_ast = 1; /* Check for timing error: ast happened while we were doing that. */ if (!detect_input_pending ()) { /* No timing error: wait for flag to be set. */ SYS$CANTIM (1, 0); if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */ SYS$WFLOR (timer_ef, timer_eflist); /* Wait for timer expiry or input */ } waiting_for_ast = 0;}/* The standard `sleep' routine works some other way and it stops working if you have ever quit out of it. This one continues to work. */sys_sleep (timeval) int timeval;{ int time [2]; LIB$EMUL (&timeval, &-10000000, &0, time); /* Convert to VMS format */ SYS$CANTIM (1, 0); if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */ SYS$WAITFR (timer_ef); /* Wait for timer expiry only */}init_sigio (){ request_sigio ();}reset_sigio (){ unrequest_sigio ();}request_sigio (){ croak ("request sigio");}unrequest_sigio (){ croak ("unrequest sigio");}#endif /* VMS *//* Note that VMS compiler won't accept defined (CANNOT_DUMP). */#ifndef CANNOT_DUMP#define NEED_STARTS#endif#ifndef SYSTEM_MALLOC#ifndef NEED_STARTS#define NEED_STARTS#endif#endif#ifdef NEED_STARTS/* Some systems that cannot dump also cannot implement these. *//* * Return the address of the start of the text segment prior to * doing an unexec(). After unexec() the return value is undefined. * See crt0.c for further explanation and _start(). * */#ifndef CANNOT_UNEXECchar *start_of_text (){#ifdef TEXT_START return ((char *) TEXT_START);#else#ifdef GOULD extern csrt(); return ((char *) csrt);#else /* not GOULD */ extern int _start (); return ((char *) _start);#endif /* GOULD */#endif /* TEXT_START */}#endif /* not CANNOT_UNEXEC *//* * Return the address of the start of the data segment prior to * doing an unexec(). After unexec() the return value is undefined. * See crt0.c for further information and definition of data_start. * * Apparently, on BSD systems this is etext at startup. On * USG systems (swapping) this is highly mmu dependent and * is also dependent on whether or not the program is running * with shared text. Generally there is a (possibly large) * gap between end of text and start of data with shared text. * * On Uniplus+ systems with shared text, data starts at a * fixed address. Each port (from a given oem) is generally * different, and the specific value of the start of data can * be obtained via the UniPlus+ specific "uvar(2)" system call, * however the method outlined in crt0.c seems to be more portable. * * Probably what will have to happen when a USG unexec is available, * at least on UniPlus, is temacs will have to be made unshared so * that text and data are contiguous. Then once loadup is complete, * unexec will produce a shared executable where the data can be * at the normal shared text boundry and the startofdata variable * will be patched by unexec to the correct value. * */ char *start_of_data (){#ifdef DATA_START return ((char *) DATA_START);#else extern int data_start; return ((char *) &data_start);#endif}#endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */#ifndef CANNOT_DUMP/* Some systems that cannot dump also cannot implement these. *//* * Return the address of the end of the text segment prior to * doing an unexec(). After unexec() the return value is undefined. */ char *end_of_text (){#ifdef TEXT_END return ((char *) TEXT_END);#else extern int etext; return ((char *) &etext);#endif} /* * Return the address of the end of the data segment prior to * doing an unexec(). After unexec() the return value is undefined. */char *end_of_data (){#ifdef DATA_END return ((char *) DATA_END);#else extern int edata; return ((char *) &edata);#endif}#endif /* not CANNOT_DUMP *//* Get_system_name returns as its value a string for the Lisp function system-name to return. */#ifdef BSD4_1#include <whoami.h>#endif#ifdef USG/* Can't have this within the function since `static' is #defined to nothing */static struct utsname get_system_name_name;#endifchar *get_system_name (){#ifdef USG uname (&get_system_name_name); return (get_system_name_name.nodename);#else /* Not USG */#ifdef BSD4_1 return sysname;#else /* not USG, not 4.1 */ static char system_name_saved[32];#ifdef VMS char *sp; if ((sp = egetenv("SYS$NODE")) == 0) sp = "vax-vms"; else { char *end; if ((end = index (sp, ':')) != 0) *end = '\0'; } strcpy (system_name_saved, sp);#else /* not VMS */ gethostname (system_name_saved, sizeof (system_name_saved));#endif /* not VMS */ return system_name_saved;#endif /* not USG, not 4.1 */#endif /* not USG */}#ifndef HAVE_SELECT/* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs * Only checks read descriptors. *//* How long to wait between checking fds in select */#define SELECT_PAUSE 1int select_alarmed;/* For longjmp'ing back to read_input_waiting. */jmp_buf read_alarm_throw;/* Nonzero if the alarm signal should throw back to read_input_waiting. The read_socket_hook function sets this to 1 while it is waiting. */int read_alarm_should_throw;select_alarm (){ select_alarmed = 1;#ifdef BSD4_1 sigrelse (SIGALRM);#else /* not BSD4_1 */ signal (SIGALRM, SIG_IGN);#endif /* not BSD4_1 */ if (read_alarm_should_throw) longjmp (read_alarm_throw, 1);}/* Only rfds are checked. */intselect (nfds, rfds, wfds, efds, timeout) int nfds; int *rfds, *wfds, *efds, *timeout;{ int ravail = 0, orfds = 0, old_alarm; int timeoutval = timeout ? *timeout : 100000; int *local_timeout = &timeoutval; extern int kbd_count; extern int proc_buffered_char[];#ifndef subprocesses int process_tick = 0, update_tick = 0;#else extern int process_tick, update_tick;#endif int (*old_trap) (); char buf; if (rfds) { orfds = *rfds; *rfds = 0; } if (wfds) *wfds = 0; if (efds) *efds = 0; /* If we are looking only for the terminal, with no timeout, just read it and wait -- that's more efficient. */ if (orfds == 1 && (!timeout || *timeout == 100000) && process_tick == update_tick) { if (!kbd_count) read_input_waiting (); *rfds = 1; return 1; } /* Once a second, till the timer expires, check all the flagged read * descriptors to see if any input is available. If there is some then * set the corresponding bit in the return copy of rfds. */ while (1) { register int to_check, bit, fd; if (rfds) { for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++) { if (orfds & bit) { int avail = 0, status = 0; if (bit == 1) avail = detect_input_pending(); /* Special keyboard handler */ else {#ifdef FIONREAD status = ioctl (fd, FIONREAD, &avail);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -