📄 sysdep.c
字号:
ioctl (0, TIOCSPGRP, &pid);#else /* Just ignore this for now and hope for the best */#endif#endif}/* Record a signal code and the handler for it. */struct save_signal{ int code; int (*handler) ();};/* Suspend the Emacs process; give terminal to its superior. */sys_suspend (){#ifdef VMS unsigned long parent_id; parent_id = getppid (); if (parent_id && parent_id != 0xffffffff) { int oldsig = signal (SIGINT, SIG_IGN); int status = LIB$ATTACH (&parent_id) & 1; signal (SIGINT, oldsig); return status; } return -1;#else#ifdef SIGTSTP#ifdef BSD killpg (getpgrp (0), SIGTSTP);#else kill (-getpgrp (0), SIGTSTP);#endif#else#ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */ ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */ kill (getpid (), SIGQUIT);#else/* On a system where suspending is not implemented, instead fork a subshell and let it talk directly to the terminal while we wait. */ int pid = fork (); struct save_signal saved_handlers[5]; saved_handlers[0].code = SIGINT; saved_handlers[1].code = SIGQUIT; saved_handlers[2].code = SIGTERM;#ifdef SIGIO saved_handlers[3].code = SIGIO; saved_handlers[4].code = 0;#else saved_handlers[3].code = 0;#endif if (pid == -1) error ("Can't spawn subshell"); if (pid == 0) { char *sh; sh = (char *) egetenv ("SHELL"); if (sh == 0) sh = "sh"; /* Use our buffer's default directory for the subshell. */ { Lisp_Object dir; unsigned char *str; int len; /* mentioning current_buffer->buffer would mean including buffer.h, which somehow wedges the hp compiler. So instead... */ dir = intern ("default-directory"); /* Can't use NULL */ if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil)) goto xyzzy; dir = Fsymbol_value (dir); if (XTYPE (dir) != Lisp_String) goto xyzzy; str = (unsigned char *) alloca (XSTRING (dir)->size + 2); len = XSTRING (dir)->size; bcopy (XSTRING (dir)->data, str, len); if (str[len - 1] != '/') str[len++] = '/'; str[len] = 0; chdir (str); } xyzzy:#ifdef subprocesses close_process_descs (); /* Close Emacs's pipes/ptys */#endif execlp (sh, sh, 0); write (1, "Can't execute subshell", 22); _exit (1); } save_signal_handlers (&saved_handlers); wait_for_termination (pid); restore_signal_handlers (&saved_handlers);#endif /* no USG_JOBCTRL */#endif /* no SIGTSTP */#endif /* not VMS */}save_signal_handlers (saved_handlers) struct save_signal *saved_handlers;{ while (saved_handlers->code) { saved_handlers->handler = (int (*) ()) signal (saved_handlers->code, SIG_IGN); saved_handlers++; }}restore_signal_handlers (saved_handlers) struct save_signal *saved_handlers;{ while (saved_handlers->code) { signal (saved_handlers->code, saved_handlers->handler); saved_handlers++; }}#ifdef F_SETFLint old_fcntl_flags;init_sigio (){#ifdef FASYNC old_fcntl_flags = fcntl (0, F_GETFL, 0) & ~FASYNC;#endif request_sigio ();}reset_sigio (){ unrequest_sigio ();}#ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */request_sigio (){#ifdef SIGWINCH int omask = sigblock (0); sigsetmask (omask & ~sigmask (SIGWINCH));#endif fcntl (0, F_SETFL, old_fcntl_flags | FASYNC); interrupts_deferred = 0;}unrequest_sigio (){#ifdef SIGWINCH sigblock (sigmask (SIGWINCH));#endif fcntl (0, F_SETFL, old_fcntl_flags); interrupts_deferred = 1;}#else /* no FASYNC */#ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */request_sigio (){ int on = 1; ioctl (0, FIOASYNC, &on); interrupts_deferred = 0;}unrequest_sigio (){ int off = 0; ioctl (0, FIOASYNC, &off); interrupts_deferred = 1;}#else /* not FASYNC, not STRIDE */ request_sigio (){ croak ("request_sigio");} unrequest_sigio (){ croak ("unrequest_sigio");} #endif /* STRIDE */#endif /* FASYNC */#endif /* F_SETFL */TERMINAL old_gtty; /* The initial tty mode bits */int term_initted; /* 1 if outer tty status has been recorded */#ifdef F_SETOWNint old_fcntl_owner;#endif /* F_SETOWN */#ifdef TIOCGLTCstruct ltchars old_ltchars;#endif /* TIOCGLTC */#ifdef TIOCGETCstruct tchars old_tchars;int old_lmode;int lmode; /* Current lmode value. */ /* Needed as global for 4.1 */#endif /* TIOCGETC *//* This may also be defined in stdio, but if so, this does no harm, and using the same name avoids wasting the other one's space. */#ifdef USGunsigned char _sobuf[BUFSIZ+8];#elsechar _sobuf[BUFSIZ];#endif #ifdef TIOCGLTCstatic struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};#endif#ifdef TIOCGETC static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};#endif init_sys_modes (){ TERMINAL tty;#ifdef TIOCGETC struct tchars tchars;#endif#ifdef VMS#if 0 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */ extern int (*interrupt_signal) ();#endif#endif if (noninteractive) return;#ifdef VMS if (!input_ef) LIB$GET_EF (&input_ef); SYS$CLREF (input_ef); waiting_for_ast = 0; if (!timer_ef) LIB$GET_EF (&timer_ef); SYS$CLREF (timer_ef); if (!process_ef) { LIB$GET_EF (&process_ef); SYS$CLREF (process_ef); } if (input_ef / 32 != process_ef / 32) croak ("Input and process event flags in different clusters."); if (input_ef / 32 != timer_ef / 32) croak ("Input and process event flags in different clusters."); input_eflist = ((unsigned) 1 << (input_ef % 32)) | ((unsigned) 1 << (process_ef % 32)); timer_eflist = ((unsigned) 1 << (input_ef % 32)) | ((unsigned) 1 << (timer_ef % 32)); SYS$QIOW (0, input_chan, IO$_SENSEMODE, &old_gtty, 0, 0, &old_gtty.class, 12, 0, 0, 0, 0);#ifndef VMS4_4 sys_access_reinit ();#endif#else /* not VMS */ ioctl (0, TIOCGETP, &old_gtty);#endif /* not VMS */ if (!read_socket_hook) { tty = old_gtty;#ifdef HAVE_TERMIO tty.c_iflag |= (IGNBRK); /* Ignore break condition */ tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */#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 */ 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 tty.c_cflag |= CS8; /* allow 8th bit on input */ tty.c_cflag &= ~PARENB; /* Don't check parity */#endif tty.c_cc[VINTR] = quit_char; /* ^G gives SIGINT */ /* Set up C-g (usually) for both SIGQUIT and SIGINT. We don't know which we will get, but we handle both alike so which one it really gives us does not matter. */ tty.c_cc[VQUIT] = quit_char; 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] = CDEL; /* Turn off shell layering use of C-z */#endif /* VSWTCH */#ifdef mips /* The following code looks like the right thing in general, but it is said to cause a crash on USG V.4. Let's play safe by turning it on only for the MIPS. */#ifdef VSUSP tty.c_cc[VSUSP] = CDEL; /* Turn off mips handling of C-z. */#endif /* VSUSP */#ifdef V_DSUSP tty.c_cc[V_DSUSP] = CDEL; /* Turn off mips handling of C-y. */#endif /* V_DSUSP */#endif /* mips */#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 */ /* 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 */#else /* if not HAVE_TERMIO */#ifdef VMS tty.tt_char |= TT$M_NOECHO | TT$M_EIGHTBIT; if (flow_control) tty.tt_char |= TT$M_TTSYNC; else tty.tt_char &= ~TT$M_TTSYNC; tty.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;#else /* not VMS (BSD, that is) */ tty.sg_flags &= ~(ECHO | CRMOD | XTABS); tty.sg_flags |= ANYP; tty.sg_flags |= interrupt_input ? RAW : CBREAK;#endif /* not VMS (BSD, that is) */#endif /* not HAVE_TERMIO */#ifdef VMS SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0, &tty.class, 12, 0, 0, 0, 0);#else ioctl (0, TIOCSETN, &tty);#endif /* not VMS */ /* This code added to insure that, if flow-control is not to be used, we have an unlocked screen at the start. */#ifdef TCXONC if (!flow_control) ioctl (0, TCXONC, 1);#endif#ifdef TIOCSTART if (!flow_control) ioctl (0, TIOCSTART, 0);#endif#ifdef AIX hft_init ();#ifdef IBMR2AIX { /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it to be only LF. This is the way that is done. */ struct termio tty; if (ioctl (1, HFTGETID, &tty) != -1) write (1, "\033[20l", 5); }#endif#endif#ifdef F_SETFL#ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */ if (interrupt_input) { old_fcntl_owner = fcntl (0, F_GETOWN, 0); fcntl (0, F_SETOWN, getpid ()); init_sigio (); }#endif /* F_GETOWN */#endif /* F_SETFL */ /* If going to use CBREAK mode, we must request C-g to interrupt and turn off start and stop chars, etc. If not going to use CBREAK mode, do this anyway so as to turn off local flow control for user coming over network on 4.2; in this case, only t_stopc and t_startc really matter. */#ifdef TIOCGLTC ioctl (0, TIOCGLTC, &old_ltchars);#endif /* TIOCGLTC */#ifndef HAVE_TERMIO#ifdef TIOCGETC ioctl (0, TIOCGETC, &old_tchars); ioctl (0, TIOCLGET, &old_lmode); /* Note: if not using CBREAK mode, it makes no difference how we set this */ tchars = new_tchars; tchars.t_intrc = quit_char; if (flow_control) { tchars.t_startc = '\021'; tchars.t_stopc = '\023'; }/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */#ifndef LPASS8#define LPASS8 0#endif#ifdef BSD4_1#define LNOFLSH 0100000#endif lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_lmode; ioctl (0, TIOCSETC, &tchars); ioctl (0, TIOCLSET, &lmode);#endif /* TIOCGETC */#endif /* not HAVE_TERMIO */#ifdef TIOCGLTC ioctl (0, TIOCSLTC, &new_ltchars);#endif /* TIOCGLTC */#ifdef BSD4_1 if (interrupt_input) init_sigio ();#endif#ifdef VMS/* Appears to do nothing when in PASTHRU mode. SYS$QIOW (0, input_chan, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0, interrupt_signal, oob_chars, 0, 0, 0, 0);*/ queue_kbd_input (0);#endif /* VMS */ }#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */#undef _IOFBF#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, _sobuf, _IOFBF, sizeof _sobuf);#else setbuf (stdout, _sobuf);#endif set_terminal_modes (); if (term_initted && no_redraw_on_reenter) { if (display_completed) direct_output_forward_char (0); } else screen_garbaged = 1; term_initted = 1;}/* Return nonzero if safe to use tabs in output. At the time this is called, init_sys_modes has not been done yet. */ tabs_safe_p (){ TERMINAL tty; if (noninteractive) return 1;#ifdef VMS SYS$QIOW (0, input_chan, IO$_SENSEMODE, &tty, 0, 0, &tty.class, 12, 0, 0, 0, 0);#else ioctl (0, TIOCGETP, &tty);#endif /* not VMS */ return (TABS_OK(tty));}/* Get terminal size from system. Store number of lines into *heightp and width into *widthp. If zero or a negative number is stored, the value is not valid. */get_screen_size (widthp, heightp) int *widthp, *heightp;{/* Define the 4.3 names in terms of the Sun names if the latter exist and the former do not. */#ifdef TIOCGSIZE#ifndef TIOCGWINSZ#define TIOCGWINSZ TIOCGSIZE#define winsize ttysize#define ws_row ts_lines#define ws_col ts_cols#endif#endif /* Sun *//* Do it using the 4.3 names if possible. */#ifdef TIOCGWINSZ struct winsize size; *widthp = 0; *heightp = 0; if (ioctl (0, TIOCGWINSZ, &size) < 0) return; *widthp = size.ws_col; *heightp = size.ws_row;#else /* not TIOCGWNSIZ */#ifdef VMS TERMINAL tty; SYS$QIOW (0, input_chan, IO$_SENSEMODE, &tty, 0, 0, &tty.class, 12, 0, 0, 0, 0); *widthp = tty.scr_wid; *heightp = tty.scr_len;#else /* system doesn't know size */ *widthp = 0; *heightp = 0;#endif /* system does not know size */#endif /* not TIOCGWINSZ */}reset_sys_modes (){ if (noninteractive) { fflush (stdout); return; } if (!term_initted) return; if (read_socket_hook) return; move_cursor (screen_height - 1, 0); clear_end_of_line (screen_width); /* clear_end_of_line may move the cursor */ move_cursor (screen_height - 1, 0); /* Output raw CR so kernel can track the cursor hpos. */ cmputc ('\r');#ifdef IBMR2AIX { /* HFT devices normally use ^J as a LF/CR. We forced it to do the LF only. Now, we need to reset it. */ struct termio tty;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -