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

📄 fhandler.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
	}    }  if (get_w_binary ())    {      debug_printf ("binary write");      res = raw_write (ptr, len);    }  else    {      debug_printf ("text write");      /* This is the Microsoft/DJGPP way.  Still not ideal, but it's	 compatible.	 Modified slightly by CGF 2000-10-07 */      int left_in_data = len;      char *data = (char *)ptr;      res = 0;      while (left_in_data > 0)	{	  char buf[CHUNK_SIZE + 1], *buf_ptr = buf;	  int left_in_buf = CHUNK_SIZE;	  while (left_in_buf > 0 && left_in_data > 0)	    {	      char ch = *data++;	      if (ch == '\n')		{		  *buf_ptr++ = '\r';		  left_in_buf--;		}	      *buf_ptr++ = ch;	      left_in_buf--;	      left_in_data--;	      if (left_in_data > 0 && ch == '\r' && *data == '\n')		{		  *buf_ptr++ = *data++;		  left_in_buf--;		  left_in_data--;		}	    }	  /* We've got a buffer-full, or we're out of data.  Write it out */	  int nbytes;	  int want = buf_ptr - buf;	  if ((nbytes = raw_write (buf, want)) == want)	    {	      /* Keep track of how much written not counting additional \r's */	      res = data - (char *)ptr;	      continue;	    }	  if (nbytes == -1)	    res = -1;		/* Error */	  else	    res += nbytes;	/* Partial write.  Return total bytes written. */	  break;		/* All done */	}    }  debug_printf ("%d = write (%p, %d)", res, ptr, len);  return res;}ssize_tfhandler_base::readv (const struct iovec *const iov, const int iovcnt,		      ssize_t tot){  assert (iov);  assert (iovcnt >= 1);  if (iovcnt == 1)    return read (iov->iov_base, iov->iov_len);  if (tot == -1)		// i.e. if not pre-calculated by the caller.    {      tot = 0;      const struct iovec *iovptr = iov + iovcnt;      do	{	  iovptr -= 1;	  tot += iovptr->iov_len;	}      while (iovptr != iov);    }  assert (tot >= 0);  if (tot == 0)    return 0;  char *buf = (char *) alloca (tot);  if (!buf)    {      set_errno (ENOMEM);      return -1;    }  const ssize_t res = read (buf, tot);  const struct iovec *iovptr = iov;  int nbytes = res;  while (nbytes > 0)    {      const int frag = min (nbytes, (ssize_t) iovptr->iov_len);      memcpy (iovptr->iov_base, buf, frag);      buf += frag;      iovptr += 1;      nbytes -= frag;    }  return res;}ssize_tfhandler_base::writev (const struct iovec *const iov, const int iovcnt,		       ssize_t tot){  assert (iov);  assert (iovcnt >= 1);  if (iovcnt == 1)    return write (iov->iov_base, iov->iov_len);  if (tot == -1)		// i.e. if not pre-calculated by the caller.    {      tot = 0;      const struct iovec *iovptr = iov + iovcnt;      do	{	  iovptr -= 1;	  tot += iovptr->iov_len;	}      while (iovptr != iov);    }  assert (tot >= 0);  if (tot == 0)    return 0;  char *const buf = (char *) alloca (tot);  if (!buf)    {      set_errno (ENOMEM);      return -1;    }  char *bufptr = buf;  const struct iovec *iovptr = iov;  int nbytes = tot;  while (nbytes != 0)    {      const int frag = min (nbytes, (ssize_t) iovptr->iov_len);      memcpy (bufptr, iovptr->iov_base, frag);      bufptr += frag;      iovptr += 1;      nbytes -= frag;    }  return write (buf, tot);}__off64_tfhandler_base::lseek (__off64_t offset, int whence){  __off64_t res;  /* 9x/Me doesn't support 64bit offsets.  We trap that here and return     EINVAL.  It doesn't make sense to simulate bigger offsets by a     SetFilePointer sequence since FAT and FAT32 don't support file     size >= 4GB anyway. */  if (!wincap.has_64bit_file_access ()      && (offset < LONG_MIN || offset > LONG_MAX))    {      debug_printf ("Win9x, offset not 32 bit.");      set_errno (EINVAL);      return (__off64_t)-1;    }  /* Seeks on text files is tough, we rewind and read till we get to the     right place.  */  if (whence != SEEK_CUR || offset != 0)    {      if (whence == SEEK_CUR)	offset -= ralen - raixget;      set_readahead_valid (0);    }  debug_printf ("lseek (%s, %D, %d)", unix_path_name, offset, whence);  DWORD win32_whence = whence == SEEK_SET ? FILE_BEGIN		       : (whence == SEEK_CUR ? FILE_CURRENT : FILE_END);  LONG off_low = offset & 0xffffffff;  LONG *poff_high, off_high;  if (!wincap.has_64bit_file_access ())    poff_high = NULL;  else    {      off_high =  offset >> 32;      poff_high = &off_high;    }  debug_printf ("setting file pointer to %u (high), %u (low)", off_high, off_low);  res = SetFilePointer (get_handle (), off_low, poff_high, win32_whence);  if (res == INVALID_SET_FILE_POINTER && GetLastError ())    {      __seterrno ();    }  else    {      /* When next we write(), we will check to see if *this* seek went beyond	 the end of the file, and back-seek and fill with zeros if so - DJ */      set_check_win95_lseek_bug ();      /* If this was a SEEK_CUR with offset 0, we still might have	 readahead that we have to take into account when calculating	 the actual position for the application.  */      if (whence == SEEK_CUR)	res -= ralen - raixget;    }  return res;}intfhandler_base::close (){  int res = -1;  syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());  if (get_nohandle () || CloseHandle (get_handle ()))    res = 0;  else    {      paranoid_printf ("CloseHandle (%d <%s>) failed", get_handle (),		       get_name ());      __seterrno ();    }  return res;}intfhandler_base::ioctl (unsigned int cmd, void *buf){  if (cmd == FIONBIO)    syscall_printf ("ioctl (FIONBIO, %p)", buf);  else    syscall_printf ("ioctl (%x, %p)", cmd, buf);  set_errno (EINVAL);  return -1;}intfhandler_base::lock (int, struct flock *){  set_errno (EINVAL);  return -1;}extern "C" char * __stdcallrootdir (char *full_path){  /* Possible choices:   * d:... -> d:/   * \\server\share... -> \\server\share\   * else current drive.   */  char *root = full_path;  if (full_path[1] == ':')    strcpy (full_path + 2, "\\");  else if (full_path[0] == '\\' && full_path[1] == '\\')    {      char *cp = full_path + 2;      while (*cp && *cp != '\\')	cp++;      if (!*cp)	{	  set_errno (ENOTDIR);	  return NULL;	}      cp++;      while (*cp && *cp != '\\')	cp++;      strcpy (cp, "\\");    }  else    root = NULL;  return root;}int __stdcallfhandler_base::fstat (struct __stat64 *buf, path_conv *){  debug_printf ("here");  switch (get_device ())    {    case FH_PIPE:      buf->st_mode = S_IFIFO | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;      break;    case FH_PIPEW:      buf->st_mode = S_IFIFO | STD_WBITS | S_IWGRP | S_IWOTH;      break;    case FH_PIPER:      buf->st_mode = S_IFIFO | STD_RBITS;      break;    case FH_FLOPPY:      buf->st_mode = S_IFBLK | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;      break;    default:      buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;      break;    }  buf->st_nlink = 1;  buf->st_blksize = S_BLKSIZE;  time_as_timestruc_t (&buf->st_ctim);  buf->st_atim = buf->st_mtim = buf->st_ctim;  return 0;}voidfhandler_base::init (HANDLE f, DWORD a, mode_t bin){  set_io_handle (f);  access = a;  a &= GENERIC_READ | GENERIC_WRITE;  int flags = 0;  if (a == GENERIC_READ)    flags = O_RDONLY;  else if (a == GENERIC_WRITE)    flags = O_WRONLY;  else if (a == (GENERIC_READ | GENERIC_WRITE))    flags = O_RDWR;  set_flags (flags | bin);  set_open_status ();  debug_printf ("created new fhandler_base for handle %p, bin %d", f, get_r_binary ());}voidfhandler_base::dump (void){  paranoid_printf ("here");}intfhandler_base::dup (fhandler_base *child){  debug_printf ("in fhandler_base dup");  HANDLE nh;  if (!get_nohandle ())    {      if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, &nh, 0, TRUE,			    DUPLICATE_SAME_ACCESS))	{	  system_printf ("dup(%s) failed, handle %x, %E",			 get_name (), get_handle ());	  __seterrno ();	  return -1;	}      child->set_io_handle (nh);    }  return 0;}int fhandler_base::fcntl (int cmd, void *arg){  int res;  switch (cmd)    {    case F_GETFD:      res = get_close_on_exec () ? FD_CLOEXEC : 0;      break;    case F_SETFD:      set_close_on_exec ((int) arg);      res = 0;      break;    case F_GETFL:      res = get_flags ();      debug_printf ("GETFL: %d", res);      break;    case F_SETFL:      {	/*	 * Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.	 * Each other flag will be ignored.	 * Since O_ASYNC isn't defined in fcntl.h it's currently	 * ignored as well.	 */	const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;	int new_flags = (int) arg & allowed_flags;	/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.	   Set only the flag that has been passed in.  If both are set, just	   record O_NONBLOCK.   */	if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))	  new_flags = O_NONBLOCK;	set_flags ((get_flags () & ~allowed_flags) | new_flags);      }      res = 0;      break;    case F_GETLK:    case F_SETLK:    case F_SETLKW:      res = lock (cmd, (struct flock *) arg);      break;    default:      set_errno (EINVAL);      res = -1;      break;    }  return res;}/* Base terminal handlers.  These just return errors.  */intfhandler_base::tcflush (int){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcsendbreak (int){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcdrain (void){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcflow (int){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcsetattr (int, const struct termios *){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcgetattr (struct termios *){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcsetpgrp (const pid_t){  set_errno (ENOTTY);  return -1;}intfhandler_base::tcgetpgrp (void){  set_errno (ENOTTY);  return -1;}voidfhandler_base::operator delete (void *p){  cfree (p);  return;}/* Normal I/O constructor */fhandler_base::fhandler_base (DWORD devtype, int unit):  status (devtype),  access (0),  io_handle (NULL),  namehash (0),  openflags (0),  rabuf (NULL),  ralen (0),  raixget (0),  raixput (0),  rabuflen (0),  unix_path_name (NULL),  win32_path_name (NULL),  open_status (0){}/* Normal I/O destructor */fhandler_base::~fhandler_base (void){  if (unix_path_name != NULL)    cfree ((void *) unix_path_name);  if (win32_path_name != NULL)    cfree ((void *) win32_path_name);  if (rabuf)    free (rabuf);  unix_path_name = win32_path_name = NULL;}/**********************************************************************//* /dev/null */fhandler_dev_null::fhandler_dev_null () :	fhandler_base (FH_NULL){}voidfhandler_dev_null::dump (void){  paranoid_printf ("here");}voidfhandler_base::set_inheritance (HANDLE &h, int not_inheriting){#ifdef DEBUGGING_AND_FDS_PROTECTED  HANDLE oh = h;#endif  /* Note that we could use SetHandleInformation here but it is not available     on all platforms.  Test cases seem to indicate that using DuplicateHandle     in this fashion does not actually close the original handle, which is     what we want.  If this changes in the future, we may be forced to use     SetHandleInformation on newer OS's */  if (!DuplicateHandle (hMainProc, h, hMainProc, &h, 0, !not_inheriting,			     DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))    debug_printf ("DuplicateHandle failed, %E");#ifdef DEBUGGING_AND_FDS_PROTECTED  if (h)    setclexec (oh, h, not_inheriting);#endif}voidfhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name){  if (/* !is_socket () && */ !get_close_on_exec ())    debug_printf ("handle %p already opened", h);  else if (!DuplicateHandle (parent, h, hMainProc, &h, 0, !get_close_on_exec (),			     DUPLICATE_SAME_ACCESS))    system_printf ("%s - %E, handle %s<%p>", get_name (), name, h);#ifdef DEBUGGING_AND_FDS_PROTECTED  else if (get_close_on_exec ())    ProtectHandle (h);	/* would have to be fancier than this */  else    /* ProtectHandleINH (h) */;	/* Should already be protected */#endif}voidfhandler_base::set_close_on_exec (int val){  if (!get_nohandle ())    set_inheritance (io_handle, val);  set_close_on_exec_flag (val);  debug_printf ("set close_on_exec for %s to %d", get_name (), val);}voidfhandler_base::fixup_after_fork (HANDLE parent){  debug_printf ("inheriting '%s' from parent", get_name ());  if (!get_nohandle ())    fork_fixup (parent, io_handle, "io_handle");}boolfhandler_base::is_nonblocking (){  return (openflags & O_NONBLOCK_MASK) != 0;}voidfhandler_base::set_nonblocking (int yes){  int current = openflags & O_NONBLOCK_MASK;  int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0;  openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;}DIR *fhandler_base::opendir (path_conv&){  set_errno (ENOTDIR);  return NULL;}struct dirent *fhandler_base::readdir (DIR *){  set_errno (ENOTDIR);  return NULL;}__off64_tfhandler_base::telldir (DIR *){  set_errno (ENOTDIR);  return -1;}voidfhandler_base::seekdir (DIR *, __off64_t){  set_errno (ENOTDIR);  return;}voidfhandler_base::rewinddir (DIR *){  set_errno (ENOTDIR);  return;}intfhandler_base::closedir (DIR *){  set_errno (ENOTDIR);  return -1;}

⌨️ 快捷键说明

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