⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -