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

📄 input.c

📁 UNIX下SH的实现源码
💻 C
字号:
/* input.c -- character input functions for readline. *//* Copyright (C) 1994 Free Software Foundation, Inc.   This file is part of the GNU Readline Library, a library for   reading lines of text with interactive input and history editing.   The GNU Readline Library is free software; you can redistribute it   and/or modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version 2, or   (at your option) any later version.   The GNU Readline Library is distributed in the hope that it will be   useful, but WITHOUT ANY WARRANTY; without even the implied warranty   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   The GNU General Public License is often shipped with GNU software, and   is generally kept in a file called COPYING or LICENSE.  If you do not   have a copy of the license, write to the Free Software Foundation,   59 Temple Place, Suite 330, Boston, MA 02111 USA. */#define READLINE_LIBRARY#if defined (HAVE_CONFIG_H)#  include <config.h>#endif#include <sys/types.h>#include <fcntl.h>#if defined (HAVE_SYS_FILE_H)#  include <sys/file.h>#endif /* HAVE_SYS_FILE_H */#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif /* HAVE_UNISTD_H */#if defined (HAVE_STDLIB_H)#  include <stdlib.h>#else#  include "ansi_stdlib.h"#endif /* HAVE_STDLIB_H */#if defined (HAVE_SELECT)#  if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)#    include <sys/time.h>#  endif#endif /* HAVE_SELECT */#if defined (HAVE_SYS_SELECT_H)#  include <sys/select.h>#endif#if defined (FIONREAD_IN_SYS_IOCTL)#  include <sys/ioctl.h>#endif#include <stdio.h>#include <errno.h>#if !defined (errno)extern int errno;#endif /* !errno *//* System-specific feature definitions and include files. */#include "rldefs.h"/* Some standard library routines. */#include "readline.h"#include "rlprivate.h"#include "rlshell.h"#include "xmalloc.h"/* What kind of non-blocking I/O do we have? */#if !defined (O_NDELAY) && defined (O_NONBLOCK)#  define O_NDELAY O_NONBLOCK	/* Posix style */#endif/* Non-null means it is a pointer to a function to run while waiting for   character input. */Function *rl_event_hook = (Function *)NULL;Function *rl_getc_function = rl_getc;/* **************************************************************** *//*								    *//*			Character Input Buffering       	    *//*								    *//* **************************************************************** */static int pop_index, push_index;static unsigned char ibuffer[512];static int ibuffer_len = sizeof (ibuffer) - 1;#define any_typein (push_index != pop_index)int_rl_any_typein (){  return any_typein;}/* Return the amount of space available in the buffer for stuffing   characters. */static intibuffer_space (){  if (pop_index > push_index)    return (pop_index - push_index - 1);  else    return (ibuffer_len - (push_index - pop_index));}/* Get a key from the buffer of characters to be read.   Return the key in KEY.   Result is KEY if there was a key, or 0 if there wasn't. */static intrl_get_char (key)     int *key;{  if (push_index == pop_index)    return (0);  *key = ibuffer[pop_index++];  if (pop_index >= ibuffer_len)    pop_index = 0;  return (1);}/* Stuff KEY into the *front* of the input buffer.   Returns non-zero if successful, zero if there is   no space left in the buffer. */static intrl_unget_char (key)     int key;{  if (ibuffer_space ())    {      pop_index--;      if (pop_index < 0)	pop_index = ibuffer_len - 1;      ibuffer[pop_index] = key;      return (1);    }  return (0);}/* If a character is available to be read, then read it   and stuff it into IBUFFER.  Otherwise, just return. */static voidrl_gather_tyi (){  int tty;  register int tem, result;  int chars_avail;  char input;#if defined(HAVE_SELECT)  fd_set readfds, exceptfds;  struct timeval timeout;#endif  tty = fileno (rl_instream);#if defined (HAVE_SELECT)  FD_ZERO (&readfds);  FD_ZERO (&exceptfds);  FD_SET (tty, &readfds);  FD_SET (tty, &exceptfds);  timeout.tv_sec = 0;  timeout.tv_usec = 100000;	/* 0.1 seconds */  if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)    return;	/* Nothing to read. */#endif  result = -1;#if defined (FIONREAD)  result = ioctl (tty, FIONREAD, &chars_avail);#endif#if defined (O_NDELAY)  if (result == -1)    {      tem = fcntl (tty, F_GETFL, 0);      fcntl (tty, F_SETFL, (tem | O_NDELAY));      chars_avail = read (tty, &input, 1);      fcntl (tty, F_SETFL, tem);      if (chars_avail == -1 && errno == EAGAIN)	return;    }#endif /* O_NDELAY */  /* If there's nothing available, don't waste time trying to read     something. */  if (chars_avail <= 0)    return;  tem = ibuffer_space ();  if (chars_avail > tem)    chars_avail = tem;  /* One cannot read all of the available input.  I can only read a single     character at a time, or else programs which require input can be     thwarted.  If the buffer is larger than one character, I lose.     Damn! */  if (tem < ibuffer_len)    chars_avail = 0;  if (result != -1)    {      while (chars_avail--)	rl_stuff_char ((*rl_getc_function) (rl_instream));    }  else    {      if (chars_avail)	rl_stuff_char (input);    }}/* Is there input available to be read on the readline input file   descriptor?  Only works if the system has select(2) or FIONREAD. */int_rl_input_available (){#if defined(HAVE_SELECT)  fd_set readfds, exceptfds;  struct timeval timeout;#endif#if defined(FIONREAD)  int chars_avail;#endif  int tty;  tty = fileno (rl_instream);#if defined (HAVE_SELECT)  FD_ZERO (&readfds);  FD_ZERO (&exceptfds);  FD_SET (tty, &readfds);  FD_SET (tty, &exceptfds);  timeout.tv_sec = 0;  timeout.tv_usec = 100000;	/* 0.1 seconds */  return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);#endif#if defined (FIONREAD)  if (ioctl (tty, FIONREAD, &chars_avail) == 0)    return (chars_avail);#endif  return 0;}void_rl_insert_typein (c)     int c;     {    	  int key, t, i;  char *string;  i = key = 0;  string = xmalloc (ibuffer_len + 1);  string[i++] = (char) c;  while ((t = rl_get_char (&key)) &&	 _rl_keymap[key].type == ISFUNC &&	 _rl_keymap[key].function == rl_insert)    string[i++] = key;  if (t)    rl_unget_char (key);  string[i] = '\0';  rl_insert_text (string);  free (string);}/* Add KEY to the buffer of characters to be read.  Returns 1 if the   character was stuffed correctly; 0 otherwise. */intrl_stuff_char (key)     int key;{  if (ibuffer_space () == 0)    return 0;  if (key == EOF)    {      key = NEWLINE;      rl_pending_input = EOF;    }  ibuffer[push_index++] = key;  if (push_index >= ibuffer_len)    push_index = 0;  return 1;}/* Make C be the next command to be executed. */intrl_execute_next (c)     int c;{  rl_pending_input = c;  return 0;}/* **************************************************************** *//*								    *//*			     Character Input			    *//*								    *//* **************************************************************** *//* Read a key, including pending input. */intrl_read_key (){  int c;  rl_key_sequence_length++;  if (rl_pending_input)    {      c = rl_pending_input;      rl_pending_input = 0;    }  else    {      /* If input is coming from a macro, then use that. */      if (c = _rl_next_macro_key ())	return (c);      /* If the user has an event function, then call it periodically. */      if (rl_event_hook)	{	  while (rl_event_hook && rl_get_char (&c) == 0)	    {	      (*rl_event_hook) ();	      rl_gather_tyi ();	    }	}      else	{	  if (rl_get_char (&c) == 0)	    c = (*rl_getc_function) (rl_instream);	}    }  return (c);}intrl_getc (stream)     FILE *stream;{  int result;  unsigned char c;  while (1)    {      result = read (fileno (stream), &c, sizeof (unsigned char));      if (result == sizeof (unsigned char))	return (c);      /* If zero characters are returned, then the file that we are	 reading from is empty!  Return EOF in that case. */      if (result == 0)	return (EOF);#if defined (__BEOS__)      if (errno == EINTR)	continue;#endif#if defined (EWOULDBLOCK)#  define X_EWOULDBLOCK EWOULDBLOCK#else#  define X_EWOULDBLOCK -99#endif#if defined (EAGAIN)#  define X_EAGAIN EAGAIN#else#  define X_EAGAIN -99#endif      if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)	{	  if (unset_nodelay_mode (fileno (stream)) < 0)	    return (EOF);	  continue;	}#undef X_EWOULDBLOCK#undef X_EAGAIN      /* If the error that we received was SIGINT, then try again,	 this is simply an interrupted system call to read ().	 Otherwise, some error ocurred, also signifying EOF. */      if (errno != EINTR)	return (EOF);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -