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

📄 tminit.c

📁 UNIX下SH的实现源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#if 1
	  r.h.al = ch;
	  __dpmi_int (0x29, &r);
#else
	  (void) putch (ch);
#endif
	}
    }
}

static void
__direct_outputs_at (const unsigned char *s)
{
  while (*s)
    __direct_output_at (*s++);
}

/******************************************************************************/
/* special read function ******************************************************/

static ssize_t
__libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv)
{
  short devmod;
  ssize_t bytes;

  /* check handle whether valid or not */
  devmod = _get_dev_info (handle);
  if (devmod == -1)
    {
      *rv = -1;
      return 1;
    }

  /* special case */
  if (count == 0)
    {
      *rv = 0;
      return 1;
    }

  /* console only... */
  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
    {
      /* character device */
      if ((devmod & _DEV_RAW) && (__file_handle_modes[handle] & O_BINARY))
	*rv = __libc_termios_read_raw_tty (handle, buffer, count);
      else
	*rv = __libc_termios_read_cooked_tty (handle, buffer, count);
      return 1;
    }

  if (__file_handle_modes[handle] & O_BINARY)
    {
      bytes = _read (handle, buffer, count);
      if (bytes < 0)
	{
	  *rv = -1;
	  return 1;
	}
    }
  else
    {
      unsigned char *rp, *wp;
      ssize_t n;

      bytes = _read (handle, buffer, count);
      if (bytes < 0)
	{
	  *rv = -1;
	  return 1;
	}

      rp = wp = buffer;
      n = bytes;
      while (--n >= 0)
	{
	  unsigned char ch;

	  ch = *rp++;
	  if (ch == CPMEOF)
	    {
	      ++n;
	      (void) lseek (handle, -n, SEEK_CUR);
	      break;
	    }
	  else if (ch == '\r')
	    {
	      if (n > 0)
		{
		  /* peek next character */
		  if (*rp == '\n')
		    {
		      /* if found '\n', delete '\r' */
		      ch = *rp++;
		      --n;
		    }
		}
	      else
		{
		  unsigned char tmpch;

		  /* read a character to peek */
		  if (_read (handle, &tmpch, 1) == 1)
		    {
		      if (tmpch == '\n')
			ch = tmpch;
		      else
			(void) lseek (handle, -1, SEEK_CUR);
		    }
		}
	    }
	  *wp++ = ch;
	}
      bytes = wp - (unsigned char *) buffer;
    }

  /* result of read() */
  *rv =  bytes;
  return 1;
}

static ssize_t
__libc_termios_read_cooked_tty (int handle, void *buffer, size_t count)
{
  unsigned char *wp;
  ssize_t n;

  wp = buffer;
  n = count;

#if 0
  /* clear cooked queue */
  if (__libc_termios_exist_queue ())
    __libc_termios_clear_queue ();
#endif

  if (__libc_tty_p->t_lflag & ICANON)
    {
      /* get inputs (wait for NL or EOT) */
      if (! __libc_termios_exist_queue ())
	__libc_termios_fill_queue ();

      while (--n >= 0)
	{
	  if (! __libc_termios_exist_queue ())
	    break;

	  *wp++ = __libc_termios_get_queue ();
	}
    }
  else
    {
      /* block until getting inputs */
      while (! __libc_termios_exist_queue ())
	{
	  __dpmi_yield ();
	  __libc_termios_fill_queue ();
	}

      while (--n >= 0)
	{
	  *wp++ = __libc_termios_get_queue ();

	  if (! __libc_termios_exist_queue ())
	    {
	      __libc_termios_fill_queue ();
	      if (! __libc_termios_exist_queue ())
		break;
	    }
	}
    }

  return (ssize_t) (wp - (unsigned char *) buffer);
}

static ssize_t
__libc_termios_read_raw_tty (int handle, void *buffer, size_t count)
{
  unsigned char *wp;
  unsigned char ch;
  ssize_t n;

  n = count;
  wp = buffer;

  /* clear cooked queue */
  if (__libc_termios_exist_queue ())
    __libc_termios_clear_queue ();

  /* block until getting inputs */
  while (! __direct_keysense ())
    __dpmi_yield ();

  while (--n >= 0)
    {
      /* exhaust inputs ? */
      if (! __direct_keysense ())
	break;

      /* realy get */
      ch = __direct_keyinput ();

      /* replace CTRL+SPACE with 0x00 */
      if (ch == ' ' && __direct_ctrlsense ())
	ch = '\0';

      /* copy a character into buffer and echo */
      *wp++ = ch;
      __libc_termios_maybe_echo (ch);
    }

  return (ssize_t) (wp - (unsigned char *) buffer);
}

/******************************************************************************/
/* special write function *****************************************************/

static unsigned char __libc_termios_write_sbuf_internal[64];
static unsigned char *__libc_termios_write_sbuf = NULL;
static size_t __libc_termios_write_sbuflen = 0;
static int __libc_termios_write_count = -1;

static ssize_t
__libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv)
{
  short devmod;
  ssize_t bytes;

  /* check handle whether valid or not */
  devmod = _get_dev_info (handle);
  if (devmod == -1)
    {
      *rv = -1;
      return 1;
    }

  /* special case */
  if (count == 0)
    {
      *rv = 0;
      return 1;
    }

  /* console only... */
  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
    {
      /* character device */
      if ((devmod & _DEV_RAW) && (__file_handle_modes[handle] & O_BINARY))
	*rv = __libc_termios_write_raw_tty (handle, buffer, count);
      else
	*rv = __libc_termios_write_cooked_tty (handle, buffer, count);
      return 1;
    }

  if (__file_handle_modes[handle] & O_BINARY)
    {
      bytes = _write (handle, buffer, count);
      if (bytes < 0)
	{
	  *rv = -1;
	  return 1;
	}
    }
  else
    {
      const unsigned char *rp;
      unsigned char *tp, *ep;
      ssize_t n;

      /* initialize local buffer */
      if (__libc_termios_write_count != __bss_count)
	{
	  __libc_termios_write_count = __bss_count;
	  __libc_termios_write_sbuflen = _go32_info_block.size_of_transfer_buffer;
	  __libc_termios_write_sbuf = malloc (__libc_termios_write_sbuflen);
	  if (__libc_termios_write_sbuf == NULL)
	    {
	      __libc_termios_write_sbuf = &__libc_termios_write_sbuf_internal[0];
	      __libc_termios_write_sbuflen = sizeof (__libc_termios_write_sbuf_internal);
	    }
	}

      rp = buffer;
      tp = __libc_termios_write_sbuf;
      ep = tp + __libc_termios_write_sbuflen;
      n = count;
      bytes = 0;
      while (n >= 0)
	{
	  unsigned char *wp;
	  unsigned char ch;
	  ssize_t ncr, wbytes;

	  /* fill local buffer */
	  wp = tp;
	  ncr = 0;
	  while ((wp < ep) && (--n >= 0))
	    {
	      /* get character */
	      ch = *rp++;

	      /* LF conversion */
	      if (ch == '\n')
		{
		  if (wp == (ep - 1))
		    {
		      n++;
		      rp--;
		      break;
		    }
		  *wp++ = '\r';
		  ncr++;
		}

	      /* put character */
	      *wp++ = ch;
	    }

	  /* write on handle */
	  wbytes = _write (handle, tp, (size_t) (wp - tp));
	  if (wbytes < 0)
	    {
	      *rv = -1;
	      return 1;
	    }
	  if (wbytes < (ssize_t) (wp - tp))
	    {
	      /* detected disk full, but the result is not reality */
	      *rv = bytes + (wbytes > ncr ? wbytes - ncr : 0);
	      return 1;
	    }

	  /* don't count CR */
	  bytes += wbytes - ncr;
	}
    }

  __libc_termios_check_bytes -= bytes;
  if (__libc_termios_check_bytes <= 0)
    {
      __libc_termios_check_bytes = CHECKBYTES;
      __libc_termios_check_signals ();
    }

  /* result of write() */
  *rv =  bytes;
  return 1;
}

static ssize_t
__libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count)
{
  ssize_t bytes;

  /* output process if need */
  if (__libc_tty_p->t_oflag & OPOST)
    {
      const unsigned char *rp;
      unsigned char ch;
      ssize_t n, nn;

      rp = buffer;
      n = count;
      while (n > 0)
	{
	  nn = (n < __libc_termios_check_bytes) ? n : __libc_termios_check_bytes;
	  n -= nn;
	  __libc_termios_check_bytes -= nn;

	  while (--nn >= 0)
	    {
	      /* get character */
	      ch = *rp++;

	      /* NOTE: multibyte character don't contain control character */
	      /* map NL to CRNL */
	      if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR))
		__direct_output ('\r');
	      /* map CR to NL */
	      else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL))
		ch = '\n';

	      __direct_output (ch);
	    }

	  if (__libc_termios_check_bytes <= 0)
	    {
	      __libc_termios_check_bytes = CHECKBYTES;
	      __libc_termios_check_signals ();
	    }
	}

      /* don't count CR */
      bytes = count;
    }
  else
    {
      /* output with no effect */
      bytes = __libc_termios_write_raw_tty (handle, buffer, count);
    }

  return bytes;
}

static ssize_t
__libc_termios_write_raw_tty (int handle, const void *buffer, size_t count)
{
  const unsigned char *rp;
  ssize_t n;

  rp = buffer;
  n = count;
  while (n > 0)
    {
      if (n < __libc_termios_check_bytes)
	{
	  __libc_termios_check_bytes -= n;
	  __direct_outputns (n, rp);
	  rp += n;
	  break;
	}
      else
	{
	  n -= __libc_termios_check_bytes;
	  __direct_outputns (__libc_termios_check_bytes, rp);
	  rp += __libc_termios_check_bytes;
	  __libc_termios_check_bytes = CHECKBYTES;
	  __libc_termios_check_signals ();
	}
    }

  return count;
}

/******************************************************************************/
/* special fsext function *****************************************************/

static int
__libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap)
{
  short devmod;
  ssize_t bytes;
  int handle;

  handle = va_arg (ap, int);
  devmod = _get_dev_info (handle);
  if (devmod == -1)
    return 0;
  if (!(devmod & _DEV_CDEV) || !(devmod & (_DEV_STDIN|_DEV_STDOUT)))
    return 0;

  /* console only... */
  switch (n)
    {
#if 0
    case __FSEXT_read:
      {
	void *buffer;
	size_t count;

	buffer = va_arg (ap, void *);
	count = va_arg (ap, size_t);
	if (devmod & _DEV_RAW)
	  bytes = __libc_termios_read_raw_tty (handle, buffer, count);
	else
	  bytes = __libc_termios_read_cooked_tty (handle, buffer, count);

	/* result of read */
	*rv = bytes;
	return 1;
      }
    case __FSEXT_write:
      {
	const void *buffer;
	size_t count;

	buffer = va_arg (ap, const void *);
	count = va_arg (ap, size_t);
	if (devmod & _DEV_RAW)
	  bytes = __libc_termios_write_raw_tty (handle, buffer, count);
	else
	  bytes = __libc_termios_write_cooked_tty (handle, buffer, count);

	/* result of write */
	*rv = bytes;
	return 1;
      }
#else
    case __FSEXT_write:
      {
	size_t count;
	const void *buffer;

	buffer = va_arg (ap, const void *);
	count = va_arg (ap, size_t);
	bytes = __libc_termios_write_raw_tty (handle, buffer, count);

	/* result of write */
	*rv = bytes;
	return 1;
      }
#endif
    default:
      break;
    }

  return 0;
}

⌨️ 快捷键说明

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