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

📄 rlfe.c

📁 在非GUI环境下
💻 C
📖 第 1 页 / 共 2 页
字号:
	{	  perror("could not set session leader");	}      /* Tie us to our new controlling tty. */#ifdef TIOCSCTTY      if (ioctl(slave, TIOCSCTTY, NULL))	{	  perror("could not set new controlling tty");	}#else      if ((slave = get_slave_pty(name)) < 0)	{	  perror("ptypair: could not open slave pty");	  exit(1);	}      free(name);#endif      /* make slave pty be standard in, out, and error */      dup2(slave, STDIN_FILENO);      dup2(slave, STDOUT_FILENO);      dup2(slave, STDERR_FILENO);      /* at this point the slave pty should be standard input */      if (slave > 2)	{	  close(slave);	}      /* Try to restore window size; failure isn't critical */      if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0)	{	  perror("could not restore window size");	}      /* now start the shell */      {	static char* command_args[] = { COMMAND_ARGS, NULL };	if (argc < 1)	  execvp(COMMAND, command_args);	else	  execvp(argv[0], &argv[0]);      }      /* should never be reached */      exit(1);    }  /* parent */  signal (SIGCHLD, sig_child);  free(name);  /* Note that we only set termios settings for standard input;   * the master side of a pty is NOT a tty.   */  tcgetattr(STDIN_FILENO, &orig_term);  t = orig_term;  eof_char = t.c_cc[VEOF];  /*  add_special_char(t.c_cc[VEOF]);*/  add_special_char(t.c_cc[VINTR]);  add_special_char(t.c_cc[VQUIT]);  add_special_char(t.c_cc[VSUSP]);#if defined (VDISCARD)  add_special_char(t.c_cc[VDISCARD]);#endif#if 0  t.c_lflag |= (ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \		ECHOK | ECHOKE | ECHONL | ECHOPRT );#else  t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \		 ECHOK | ECHOKE | ECHONL | ECHOPRT );#endif  t.c_iflag |= IGNBRK;  t.c_cc[VMIN] = 1;  t.c_cc[VTIME] = 0;  tcsetattr(STDIN_FILENO, TCSANOW, &t);  in_from_inferior_fd = master;  out_to_inferior_fd = master;  rl_instream = fdopen (master, "r");  rl_getc_function = my_rl_getc;  rl_prep_term_function = null_prep_terminal;   rl_deprep_term_function = null_deprep_terminal;   rl_callback_handler_install (prompt, line_handler);#if 1  rl_directory_completion_hook = rlfe_directory_completion_hook;  rl_completion_entry_function = rlfe_filename_completion_function;#else  rl_directory_rewrite_hook = rlfe_directory_rewrite_hook;#endif  in_from_tty_fd = STDIN_FILENO;  FD_ZERO (&in_set);  maxfd = in_from_inferior_fd > in_from_tty_fd ? in_from_inferior_fd    : in_from_tty_fd;  for (;;)    {      int num;      FD_SET (in_from_inferior_fd, &in_set);      FD_SET (in_from_tty_fd, &in_set);      num = select(maxfd+1, &in_set, NULL, NULL, NULL);      if (propagate_sigwinch)	{	  struct winsize ws;	  if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)	    {	      ioctl (master, TIOCSWINSZ, &ws);	    }	  propagate_sigwinch = 0;	  continue;	}      if (num <= 0)	{	  perror ("select");	  exit (-1);	}      if (FD_ISSET (in_from_tty_fd, &in_set))	{	  extern int readline_echoing_p;	  struct termios term_master;	  int do_canon = 1;	  int ioctl_ret;	  DPRINT1("[tty avail num_keys:%d]\n", num_keys);	  /* If we can't get tty modes for the master side of the pty, we	     can't handle non-canonical-mode programs.  Always assume the	     master is in canonical echo mode if we can't tell. */	  ioctl_ret = tcgetattr(master, &term_master);	  if (ioctl_ret >= 0)	    {	      DPRINT2 ("echo:%d, canon:%d\n",			(term_master.c_lflag & ECHO) != 0,			(term_master.c_lflag & ICANON) != 0);	      do_canon = (term_master.c_lflag & ICANON) != 0;	      readline_echoing_p = (term_master.c_lflag & ECHO) != 0;	    }	  else	    {	      if (ioctl_err == 0)		DPRINT1("tcgetattr on master fd failed: errno = %d\n", errno);	      ioctl_err = 1;	    }	  if (do_canon == 0 && num_keys == 0)	    {	      char ch[10];	      int count = read (STDIN_FILENO, ch, sizeof(ch));	      write (out_to_inferior_fd, ch, count);	    }	  else	    {	      if (num_keys == 0)		{		  int i;		  /* Re-install callback handler for new prompt. */		  if (prompt != empty_string)		    free (prompt);		  prompt = malloc (buf_count + 1);		  if (prompt == NULL)		    prompt = empty_string;		  else		    {		      memcpy (prompt, buf, buf_count);		      prompt[buf_count] = '\0';		      DPRINT1("New prompt '%s'\n", prompt);#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED -- doesn't work */		      rl_already_prompted = buf_count > 0;#else		      if (buf_count > 0)			write (1, "\r", 1);#endif		    }		  rl_callback_handler_install (prompt, line_handler);		}	      num_keys++;	      rl_callback_read_char ();	    }	}      else /* input from inferior. */	{	  int i;	  int count;	  int old_count;	  if (buf_count > (sizeof(buf) >> 2))	    buf_count = 0;	  count = read (in_from_inferior_fd, buf+buf_count,			sizeof(buf) - buf_count);	  if (count <= 0)	    {	      DPRINT0 ("(Connection closed by foreign host.)\n");	      tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);	      exit (0);	    }	  old_count = buf_count;	  /* Do some minimal carriage return translation and backspace	     processing before logging the input line. */	  if (logfile)	    {#ifndef __GNUC__	      char *b;#else	      char b[count + 1];#endif	      int i, j;#ifndef __GNUC__	      b = malloc (count + 1);	      if (b) {#endif	      for (i = 0; i < count; i++)	        b[i] = buf[buf_count + i];	      b[i] = '\0';	      for (i = j = 0; i <= count; i++)		{		  if (b[i] == '\r')		    {		      if (b[i+1] != '\n')		        b[j++] = '\n';		    }		  else if (b[i] == '\b')		    {		      if (i)			j--;		    }		  else		    b[j++] = b[i];		}	      fprintf (logfile, "%s", b);#ifndef __GNUC__	      free (b);	      }#endif	    }          /* Look for any pending echo that we need to suppress. */	  while (echo_suppress_start < echo_suppress_limit		 && count > 0		 && buf[buf_count] == echo_suppress_buffer[echo_suppress_start])	    {	      count--;	      buf_count++;	      echo_suppress_start++;	    }          /* Write to the terminal anything that was not suppressed. */          if (count > 0)            write (1, buf + buf_count, count);          /* Finally, look for a prompt candidate.           * When we get around to going input (from the keyboard),           * we will consider the prompt to be anything since the last           * line terminator.  So we need to save that text in the           * initial part of buf.  However, anything before the           * most recent end-of-line is not interesting. */	  buf_count += count;#if 1	  for (i = buf_count;  --i >= old_count; )#else	  for (i = buf_count - 1;  i-- >= buf_count - count; )#endif	    {	      if (buf[i] == '\n' || buf[i] == '\r')		{		  i++;		  memmove (buf, buf+i, buf_count - i);		  buf_count -= i;		  break;		}	    }	  DPRINT2("-> i: %d, buf_count: %d\n", i, buf_count);	}    }}/* * * FILENAME COMPLETION FOR RLFE * */#ifndef PATH_MAX#  define PATH_MAX 1024#endif#define DIRSEP		'/'#define ISDIRSEP(x)	((x) == '/')#define PATHSEP(x)	(ISDIRSEP(x) || (x) == 0)#define DOT_OR_DOTDOT(x) \	((x)[0] == '.' && (PATHSEP((x)[1]) || \			  ((x)[1] == '.' && PATHSEP((x)[2]))))#define FREE(x)		if (x) free(x)#define STRDUP(s, x)	do { \			  s = strdup (x);\			  if (s == 0) \			    return ((char *)NULL); \			} while (0)static intget_inferior_cwd (path, psize)     char *path;     size_t psize;{  int n;  static char procfsbuf[PATH_MAX] = { '\0' };  if (procfsbuf[0] == '\0')    sprintf (procfsbuf, "/proc/%d/cwd", (int)child);  n = readlink (procfsbuf, path, psize);  if (n < 0)    return n;  if (n > psize)    return -1;  path[n] = '\0';  return n;}static intrlfe_directory_rewrite_hook (dirnamep)     char **dirnamep;{  char *ldirname, cwd[PATH_MAX], *retdir, *ld;  int n, ldlen;  ldirname = *dirnamep;  if (*ldirname == '/')    return 0;  n = get_inferior_cwd (cwd, sizeof(cwd) - 1);  if (n < 0)    return 0;  if (n == 0)	/* current directory */    {      cwd[0] = '.';      cwd[1] = '\0';      n = 1;    }  /* Minimally canonicalize ldirname by removing leading `./' */  for (ld = ldirname; *ld; )    {      if (ISDIRSEP (ld[0]))	ld++;      else if (ld[0] == '.' && PATHSEP(ld[1]))	ld++;      else	break;    }  ldlen = (ld && *ld) ? strlen (ld) : 0;  retdir = (char *)malloc (n + ldlen + 3);  if (retdir == 0)    return 0;  if (ldlen)    sprintf (retdir, "%s/%s", cwd, ld);  else    strcpy (retdir, cwd);  free (ldirname);  *dirnamep = retdir;  DPRINT1("rl_directory_rewrite_hook returns %s\n", retdir);  return 1;}/* Translate *DIRNAMEP to be relative to the inferior's CWD.  Leave a trailing   slash on the result. */static intrlfe_directory_completion_hook (dirnamep)     char **dirnamep;{  char *ldirname, *retdir;  int n, ldlen;  ldirname = *dirnamep;  if (*ldirname == '/')    return 0;  n = rlfe_directory_rewrite_hook (dirnamep);  if (n == 0)    return 0;  ldirname = *dirnamep;  ldlen = (ldirname && *ldirname) ? strlen (ldirname) : 0;  if (ldlen == 0 || ldirname[ldlen - 1] != '/')    {      retdir = (char *)malloc (ldlen + 3);      if (retdir == 0)	return 0;      if (ldlen)	strcpy (retdir, ldirname);      else	retdir[ldlen++] = '.';      retdir[ldlen] = '/';      retdir[ldlen+1] = '\0';      free (ldirname);      *dirnamep = retdir;    }  DPRINT1("rl_directory_completion_hook returns %s\n", retdir);  return 1;}static char *rlfe_filename_completion_function (text, state)     const char *text;     int state;{  static DIR *directory;  static char *filename = (char *)NULL;  static char *dirname = (char *)NULL, *ud = (char *)NULL;  static int flen, udlen;  char *temp;  struct dirent *dentry;  if (state == 0)    {      if (directory)	{	  closedir (directory);	  directory = 0;	}      FREE (dirname);      FREE (filename);      FREE (ud);      if (text && *text)        STRDUP (filename, text);      else	{	  filename = malloc(1); 	  if (filename == 0)	    return ((char *)NULL);	  filename[0] = '\0';	}      dirname = (text && *text) ? strdup (text) : strdup (".");      if (dirname == 0)        return ((char *)NULL);      temp = strrchr (dirname, '/');      if (temp)	{	  strcpy (filename, ++temp);	  *temp = '\0';	}      else	{	  dirname[0] = '.';	  dirname[1] = '\0';	}      STRDUP (ud, dirname);      udlen = strlen (ud);      rlfe_directory_completion_hook (&dirname);      directory = opendir (dirname);      flen = strlen (filename);      rl_filename_completion_desired = 1;    }  dentry = 0;  while (directory && (dentry = readdir (directory)))    {      if (flen == 0)	{          if (DOT_OR_DOTDOT(dentry->d_name) == 0)            break;	}      else	{	  if ((dentry->d_name[0] == filename[0]) &&	      (strlen (dentry->d_name) >= flen) &&	      (strncmp (filename, dentry->d_name, flen) == 0))	    break;	}    }  if (dentry == 0)    {      if (directory)	{	  closedir (directory);	  directory = 0;	}      FREE (dirname);      FREE (filename);      FREE (ud);      dirname = filename = ud = 0;      return ((char *)NULL);    }  if (ud == 0 || (ud[0] == '.' && ud[1] == '\0'))    temp = strdup (dentry->d_name);  else    {      temp = malloc (1 + udlen + strlen (dentry->d_name));      strcpy (temp, ud);      strcpy (temp + udlen, dentry->d_name);    }  return (temp);}

⌨️ 快捷键说明

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