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

📄 fhandler_disk_file.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
 * This shouldn't break many apps but denying all locking * would. * For now just convert to Win32 locks and hope for the best. */intfhandler_disk_file::lock (int cmd, struct flock *fl){  __off64_t win32_start;  int win32_len;  DWORD win32_upper;  __off64_t startpos;  /*   * We don't do getlck calls yet.   */  if (cmd == F_GETLK)    {      set_errno (ENOSYS);      return -1;    }  /*   * Calculate where in the file to start from,   * then adjust this by fl->l_start.   */  switch (fl->l_whence)    {      case SEEK_SET:	startpos = 0;	break;      case SEEK_CUR:	if ((startpos = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK)	  return -1;	break;      case SEEK_END:	{	  BY_HANDLE_FILE_INFORMATION finfo;	  if (GetFileInformationByHandle (get_handle (), &finfo) == 0)	    {	      __seterrno ();	      return -1;	    }	  startpos = ((__off64_t)finfo.nFileSizeHigh << 32)		     + finfo.nFileSizeLow;	  break;	}      default:	set_errno (EINVAL);	return -1;    }  /*   * Now the fun starts. Adjust the start and length   *  fields until they make sense.   */  win32_start = startpos + fl->l_start;  if (fl->l_len < 0)    {      win32_start -= fl->l_len;      win32_len = -fl->l_len;    }  else    win32_len = fl->l_len;  if (win32_start < 0)    {      /* watch the signs! */      win32_len -= -win32_start;      if (win32_len <= 0)	{	  /* Failure ! */	  set_errno (EINVAL);	  return -1;	}      win32_start = 0;    }  /*   * Special case if len == 0 for POSIX means lock   * to the end of the entire file (and all future extensions).   */  if (win32_len == 0)    {      win32_len = 0xffffffff;      win32_upper = wincap.lock_file_highword ();    }  else    win32_upper = 0;  BOOL res;  if (wincap.has_lock_file_ex ())    {      DWORD lock_flags = (cmd == F_SETLK) ? LOCKFILE_FAIL_IMMEDIATELY : 0;      lock_flags |= (fl->l_type == F_WRLCK) ? LOCKFILE_EXCLUSIVE_LOCK : 0;      OVERLAPPED ov;      ov.Internal = 0;      ov.InternalHigh = 0;      ov.Offset = (DWORD)win32_start;      ov.OffsetHigh = 0;      ov.hEvent = (HANDLE) 0;      if (fl->l_type == F_UNLCK)	{	  res = UnlockFileEx (get_handle (), 0, (DWORD)win32_len, win32_upper, &ov);	}      else	{	  res = LockFileEx (get_handle (), lock_flags, 0, (DWORD)win32_len,							win32_upper, &ov);	  /* Deal with the fail immediately case. */	  /*	   * FIXME !! I think this is the right error to check for	   * but I must admit I haven't checked....	   */	  if ((res == 0) && (lock_flags & LOCKFILE_FAIL_IMMEDIATELY) &&			    (GetLastError () == ERROR_LOCK_FAILED))	    {	      set_errno (EAGAIN);	      return -1;	    }	}    }  else    {      /* Windows 95 -- use primitive lock call */      if (fl->l_type == F_UNLCK)	res = UnlockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len,							win32_upper);      else	res = LockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len, win32_upper);    }  if (res == 0)    {      __seterrno ();      return -1;    }  return 0;}DIR *fhandler_disk_file::opendir (path_conv& real_name){  DIR *dir;  DIR *res = NULL;  size_t len;  if (!real_name.isdir ())    set_errno (ENOTDIR);  else if ((len = strlen (real_name))> MAX_PATH - 3)    set_errno (ENAMETOOLONG);  else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)    set_errno (ENOMEM);  else if ((dir->__d_dirname = (char *) malloc (len + 3)) == NULL)    {      free (dir);      set_errno (ENOMEM);    }  else if ((dir->__d_dirent =	    (struct dirent *) malloc (sizeof (struct dirent))) == NULL)    {      free (dir->__d_dirname);      free (dir);      set_errno (ENOMEM);    }  else    {      strcpy (dir->__d_dirname, real_name.get_win32 ());      dir->__d_dirent->d_version = __DIRENT_VERSION;      cygheap_fdnew fd;      fd = this;      fd->set_nohandle (true);      dir->__d_dirent->d_fd = fd;      dir->__d_u.__d_data.__fh = this;      /* FindFirstFile doesn't seem to like duplicate /'s. */      len = strlen (dir->__d_dirname);      if (len == 0 || SLASH_P (dir->__d_dirname[len - 1]))	strcat (dir->__d_dirname, "*");      else	strcat (dir->__d_dirname, "\\*");  /**/      dir->__d_cookie = __DIRENT_COOKIE;      dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;      dir->__d_position = 0;      dir->__d_dirhash = get_namehash ();      res = dir;    }  syscall_printf ("%p = opendir (%s)", res, get_name ());  return res;}struct dirent *fhandler_disk_file::readdir (DIR *dir){  WIN32_FIND_DATA buf;  HANDLE handle;  struct dirent *res = NULL;  if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE      && dir->__d_position == 0)    {      handle = FindFirstFileA (dir->__d_dirname, &buf);      DWORD lasterr = GetLastError ();      dir->__d_u.__d_data.__handle = handle;      if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))	{	  seterrno_from_win_error (__FILE__, __LINE__, lasterr);	  return res;	}    }  else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)    {      return res;    }  else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf))    {      DWORD lasterr = GetLastError ();      (void) FindClose (dir->__d_u.__d_data.__handle);      dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;      /* POSIX says you shouldn't set errno when readdir can't	 find any more files; so, if another error we leave it set. */      if (lasterr != ERROR_NO_MORE_FILES)	  seterrno_from_win_error (__FILE__, __LINE__, lasterr);      syscall_printf ("%p = readdir (%p)", res, dir);      return res;    }  /* We get here if `buf' contains valid data.  */  strcpy (dir->__d_dirent->d_name, buf.cFileName);  /* Check for Windows shortcut. If it's a Cygwin or U/WIN     symlink, drop the .lnk suffix. */  if (buf.dwFileAttributes & FILE_ATTRIBUTE_READONLY)    {      char *c = dir->__d_dirent->d_name;      int len = strlen (c);      if (strcasematch (c + len - 4, ".lnk"))	{	  char fbuf[MAX_PATH + 1];	  strcpy (fbuf, dir->__d_dirname);	  strcpy (fbuf + strlen (fbuf) - 1, dir->__d_dirent->d_name);	  path_conv fpath (fbuf, PC_SYM_NOFOLLOW);	  if (fpath.issymlink ())	    c[len - 4] = '\0';	}    }  dir->__d_position++;  res = dir->__d_dirent;  syscall_printf ("%p = readdir (%p) (%s)",		  &dir->__d_dirent, dir, buf.cFileName);  return res;}__off64_tfhandler_disk_file::telldir (DIR *dir){  return dir->__d_position;}voidfhandler_disk_file::seekdir (DIR *dir, __off64_t loc){    rewinddir (dir);    while (loc > dir->__d_position)      if (!readdir (dir))	break;}voidfhandler_disk_file::rewinddir (DIR *dir){  if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE)    {      (void) FindClose (dir->__d_u.__d_data.__handle);      dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;    }  dir->__d_position = 0;}intfhandler_disk_file::closedir (DIR *dir){  int res = 0;  if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE &&      FindClose (dir->__d_u.__d_data.__handle) == 0)    {      __seterrno ();      res = -1;    }  syscall_printf ("%d = closedir (%p)", res, dir);  return 0;}fhandler_cygdrive::fhandler_cygdrive (int unit) :  fhandler_disk_file (FH_CYGDRIVE), unit (unit), ndrives (0), pdrive (NULL){}#define DRVSZ sizeof ("x:\\")voidfhandler_cygdrive::set_drives (){  const int len = 1 + 26 * DRVSZ;  char *p = (char *) crealloc ((void *) win32_path_name,				sizeof (".") + sizeof ("..") + len);  win32_path_name = pdrive = p;  strcpy (p, ".");  strcpy (p + sizeof ("."), "..");  p += sizeof (".") + sizeof ("..");  ndrives = GetLogicalDriveStrings (len, p) / DRVSZ;}intfhandler_cygdrive::fstat (struct __stat64 *buf, path_conv *pc){  if (!iscygdrive_root ())    return fhandler_disk_file::fstat (buf, pc);  buf->st_mode = S_IFDIR | 0555;  if (!ndrives)    set_drives ();  buf->st_nlink = ndrives;  return 0;}DIR *fhandler_cygdrive::opendir (path_conv& real_name){  DIR *dir;  dir = fhandler_disk_file::opendir (real_name);  if (dir && iscygdrive_root () && !ndrives)    set_drives ();  return dir;}struct dirent *fhandler_cygdrive::readdir (DIR *dir){  if (!iscygdrive_root ())    return fhandler_disk_file::readdir (dir);  if (!pdrive || !*pdrive)    {      set_errno (ENMFILE);      return NULL;    }  else if (dir->__d_position > 1	   && GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES)    {      pdrive = strchr (pdrive, '\0') + 1;      return readdir (dir);    }  else if (*pdrive == '.')    strcpy (dir->__d_dirent->d_name, pdrive);  else    {      *dir->__d_dirent->d_name = cyg_tolower (*pdrive);      dir->__d_dirent->d_name[1] = '\0';    }  dir->__d_position++;  pdrive = strchr (pdrive, '\0') + 1;  syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,		  dir->__d_dirent->d_name);  return dir->__d_dirent;}__off64_tfhandler_cygdrive::telldir (DIR *dir){  return fhandler_disk_file::telldir (dir);}voidfhandler_cygdrive::seekdir (DIR *dir, __off64_t loc){  if (!iscygdrive_root ())    return fhandler_disk_file::seekdir (dir, loc);  for (pdrive = win32_path_name, dir->__d_position = -1; *pdrive;       pdrive = strchr (pdrive, '\0') + 1)    if (++dir->__d_position >= loc)      break;  return;}voidfhandler_cygdrive::rewinddir (DIR *dir){  if (!iscygdrive_root ())    return fhandler_disk_file::rewinddir (dir);  pdrive = win32_path_name;  dir->__d_position = 0;  return;}intfhandler_cygdrive::closedir (DIR *dir){  if (!iscygdrive_root ())    return fhandler_disk_file::closedir (dir);  pdrive = win32_path_name;  return -1;}

⌨️ 快捷键说明

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