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

📄 path.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 5 页
字号:
	  (pathbuf[n] == '/' && pathbuf[n + 1] == '.' && !pathbuf[n + 2]))	{	  unit = 0;	  dst[0] = '\0';	  if (mount_table->cygdrive_len > 1)	    devn = FH_CYGDRIVE;	}      else if (cygdrive_win32_path (pathbuf, dst, unit))	{	  set_flags (flags, (unsigned) cygdrive_flags);	  goto out;	}      else if (mount_table->cygdrive_len > 1)	return ENOENT;    }  int chrooted_path_len;  chrooted_path_len = 0;  /* Check the mount table for prefix matches. */  for (i = 0; i < nmounts; i++)    {      const char *path;      int len;      mi = mount + posix_sorted[i];      if (!cygheap->root.exists ()	  || (mi->posix_pathlen == 1 && mi->posix_path[0] == '/'))	{	  path = mi->posix_path;	  len = mi->posix_pathlen;	}      else if (cygheap->root.posix_ok (mi->posix_path))	{	  path = cygheap->root.unchroot (mi->posix_path);	  chrooted_path_len = len = strlen (path);	}      else	{	  chrooted_path_len = 0;	  continue;	}      if (path_prefix_p (path, pathbuf, len))	break;    }  if (i >= nmounts)    {      backslashify (pathbuf, dst, 0);	/* just convert */      set_flags (flags, PATH_BINARY);    }  else    {      int n;      const char *native_path;      int posix_pathlen;      if (chroot_ok || chrooted_path_len || mi->posix_pathlen != 1	  || mi->posix_path[0] != '/')	{	  n = mi->native_pathlen;	  native_path = mi->native_path;	  posix_pathlen = chrooted_path_len ?: mi->posix_pathlen;	  chroot_ok = 1;	}      else	{	  n = cygheap->root.native_length ();	  native_path = cygheap->root.native_path ();	  posix_pathlen = mi->posix_pathlen;	  chroot_ok = 1;	}      memcpy (dst, native_path, n + 1);      const char *p = pathbuf + posix_pathlen;      if (*p == '/')	/* nothing */;      else if ((isdrive (dst) && !dst[2]) || *p)	dst[n++] = '\\';      strcpy (dst + n, p);      backslashify (dst, dst, 0);      set_flags (flags, (unsigned) mi->flags);    }  if (!isvirtual_dev (devn))    win32_device_name (src_path, dst, devn, unit); out:  MALLOC_CHECK;  if (chroot_ok || cygheap->root.ischroot_native (dst))    rc = 0;  else    {      debug_printf ("attempt to access outside of chroot '%s = %s'",		    cygheap->root.posix_path (), cygheap->root.native_path ());      rc = ENOENT;    } out_no_chroot_check:  debug_printf ("src_path %s, dst %s, flags %p, rc %d", src_path, dst, *flags, rc);  return rc;}/* cygdrive_posix_path: Build POSIX path used as the   mount point for cygdrives created when there is no other way to   obtain a POSIX path from a Win32 one. */voidmount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p){  int len = cygdrive_len;  memcpy (dst, cygdrive, len + 1);  /* Now finish the path off with the drive letter to be used.     The cygdrive prefix always ends with a trailing slash so     the drive letter is added after the path. */  dst[len++] = cyg_tolower (src[0]);  if (!src[2] || (SLASH_P (src[2]) && !src[3]))    dst[len++] = '\000';  else    {      int n;      dst[len++] = '/';      if (SLASH_P (src[2]))	n = 3;      else	n = 2;      strcpy (dst + len, src + n);    }  slashify (dst, dst, trailing_slash_p);}intmount_info::cygdrive_win32_path (const char *src, char *dst, int& unit){  int res;  const char *p = src + cygdrive_len;  if (!isalpha (*p) || (!isdirsep (p[1]) && p[1]))    {      unit = -1;      dst[0] = '\0';      res = 0;    }  else    {      dst[0] = cyg_tolower (*p);      dst[1] = ':';      strcpy (dst + 2, p + 1);      backslashify (dst, dst, !dst[2]);      unit = dst[0];      res = 1;    }  debug_printf ("src '%s', dst '%s'", src, dst);  return res;}/* conv_to_posix_path: Ensure src_path is a POSIX path.   The result is zero for success, or an errno value.   posix_path must have sufficient space (i.e. MAX_PATH bytes).   If keep_rel_p is non-zero, relative paths stay that way.  */intmount_info::conv_to_posix_path (const char *src_path, char *posix_path,				int keep_rel_p){  int src_path_len = strlen (src_path);  int relative_path_p = !isabspath (src_path);  int trailing_slash_p;  if (src_path_len <= 1)    trailing_slash_p = 0;  else    {      const char *lastchar = src_path + src_path_len - 1;      trailing_slash_p = SLASH_P (*lastchar) && lastchar[-1] != ':';    }  debug_printf ("conv_to_posix_path (%s, %s, %s)", src_path,		keep_rel_p ? "keep-rel" : "no-keep-rel",		trailing_slash_p ? "add-slash" : "no-add-slash");  MALLOC_CHECK;  if (src_path_len >= MAX_PATH)    {      debug_printf ("ENAMETOOLONG");      return ENAMETOOLONG;    }  /* FIXME: For now, if the path is relative and it's supposed to stay     that way, skip mount table processing. */  if (keep_rel_p && relative_path_p)    {      slashify (src_path, posix_path, 0);      debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path);      return 0;    }  char pathbuf[MAX_PATH];  int rc = normalize_win32_path (src_path, pathbuf);  if (rc != 0)    {      debug_printf ("%d = conv_to_posix_path (%s)", rc, src_path);      return rc;    }  int pathbuflen = strlen (pathbuf);  for (int i = 0; i < nmounts; ++i)    {      mount_item &mi = mount[native_sorted[i]];      if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen))	continue;      if (cygheap->root.exists () && !cygheap->root.posix_ok (mi.posix_path))	continue;      /* SRC_PATH is in the mount table. */      int nextchar;      const char *p = pathbuf + mi.native_pathlen;      if (!*p || !p[1])	nextchar = 0;      else if (isdirsep (*p))	nextchar = -1;      else	nextchar = 1;      int addslash = nextchar > 0 ? 1 : 0;      if ((mi.posix_pathlen + (pathbuflen - mi.native_pathlen) + addslash) >= MAX_PATH)	return ENAMETOOLONG;      strcpy (posix_path, mi.posix_path);      if (addslash)	strcat (posix_path, "/");      if (nextchar)	slashify (p,		  posix_path + addslash + (mi.posix_pathlen == 1 ? 0 : mi.posix_pathlen),		  trailing_slash_p);      if (cygheap->root.exists ())	{	  const char *p = cygheap->root.unchroot (posix_path);	  memmove (posix_path, p, strlen (p) + 1);	}      goto out;    }  if (!cygheap->root.exists ())    /* nothing */;  else if (cygheap->root.ischroot_native (pathbuf))    {      const char *p = pathbuf + cygheap->root.native_length ();      if (*p)	slashify (p, posix_path, trailing_slash_p);      else	{	  posix_path[0] = '/';	  posix_path[1] = '\0';	}    }  else    return ENOENT;  /* Not in the database.  This should [theoretically] only happen if either     the path begins with //, or / isn't mounted, or the path has a drive     letter not covered by the mount table.  If it's a relative path then the     caller must want an absolute path (otherwise we would have returned     above).  So we always return an absolute path at this point. */  if (isdrive (pathbuf))    cygdrive_posix_path (pathbuf, posix_path, trailing_slash_p);  else    {      /* The use of src_path and not pathbuf here is intentional.	 We couldn't translate the path, so just ensure no \'s are present. */      slashify (src_path, posix_path, trailing_slash_p);    }out:  debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path);  MALLOC_CHECK;  return 0;}/* Return flags associated with a mount point given the win32 path. */unsignedmount_info::set_flags_from_win32_path (const char *p){  for (int i = 0; i < nmounts; i++)    {      mount_item &mi = mount[native_sorted[i]];      if (path_prefix_p (mi.native_path, p, mi.native_pathlen))	return mi.flags;    }  return PATH_BINARY;}/* read_mounts: Given a specific regkey, read mounts from under its   key. */voidmount_info::read_mounts (reg_key& r){  char posix_path[MAX_PATH];  HKEY key = r.get_key ();  DWORD i, posix_path_size;  int res;  /* Loop through subkeys */  /* FIXME: we would like to not check MAX_MOUNTS but the heap in the     shared area is currently statically allocated so we can't have an     arbitrarily large number of mounts. */  for (i = 0; ; i++)    {      char native_path[MAX_PATH];      int mount_flags;      posix_path_size = MAX_PATH;      /* FIXME: if maximum posix_path_size is 256, we're going to	 run into problems if we ever try to store a mount point that's	 over 256 but is under MAX_PATH. */      res = RegEnumKeyEx (key, i, posix_path, &posix_path_size, NULL,			  NULL, NULL, NULL);      if (res == ERROR_NO_MORE_ITEMS)	break;      else if (res != ERROR_SUCCESS)	{	  debug_printf ("RegEnumKeyEx failed, error %d!", res);	  break;	}      /* Get a reg_key based on i. */      reg_key subkey = reg_key (key, KEY_READ, posix_path, NULL);      /* Fetch info from the subkey. */      subkey.get_string ("native", native_path, sizeof (native_path), "");      mount_flags = subkey.get_int ("flags", 0);      /* Add mount_item corresponding to registry mount point. */      res = mount_table->add_item (native_path, posix_path, mount_flags, false);      if (res && get_errno () == EMFILE)	break; /* The number of entries exceeds MAX_MOUNTS */    }}/* from_registry: Build the entire mount table from the registry.  Also,   read in cygdrive-related information from its registry location. */voidmount_info::from_registry (){  /* Use current mount areas if either user or system mount areas     already exist.  Otherwise, import old mounts. */  reg_key r;  /* Retrieve cygdrive-related information. */  read_cygdrive_info_from_registry ();  nmounts = 0;  /* First read mounts from user's table. */  read_mounts (r);  /* Then read mounts from system-wide mount table. */  reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE",	      CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,	      CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,	      NULL);  read_mounts (r1);}/* add_reg_mount: Add mount item to registry.  Return zero on success,   non-zero on failure. *//* FIXME: Need a mutex to avoid collisions with other tasks. */intmount_info::add_reg_mount (const char * native_path, const char * posix_path, unsigned mountflags){  int res = 0;  /* Add the mount to the right registry location, depending on     whether MOUNT_SYSTEM is set in the mount flags. */  if (!(mountflags & MOUNT_SYSTEM)) /* current_user mount */    {      /* reg_key for user mounts in HKEY_CURRENT_USER. */      reg_key reg_user;      /* Start by deleting existing mount if one exists. */      res = reg_user.kill (posix_path);      if (res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND)	goto err;      /* Create the new mount. */      reg_key subkey = reg_key (reg_user.get_key (),				KEY_ALL_ACCESS,				posix_path, NULL);      res = subkey.set_string ("native", native_path);      if (res != ERROR_SUCCESS)	goto err;      res = subkey.set_int ("flags", mountflags);    }  else /* local_machine mount */    {      /* reg_key for system mounts in HKEY_LOCAL_MACHINE. */      reg_key reg_sys (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",		       CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,		       CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,		       NULL);      /* Start by deleting existing mount if one exists. */      res = reg_sys.kill (posix_path);      if (res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND)	goto err;      /* Create the new mount. */      reg_key subkey = reg_key (reg_sys.get_key (),				KEY_ALL_ACCESS,				posix_path, NULL);      res = subkey.set_string ("native", native_path);      if (res != ERROR_SUCCESS)	goto err;      res = subkey.set_int ("flags", mountflags);      sys_mount_table_counter++;      cygwin_shared->sys_mount_table_counter++;    }  return 0; /* Success */ err:  __seterrno_from_win_error (res);  return -1;}/* del_reg_mount: delete mount item from registry indicated in flags.   Return zero on success, non-zero on failure.*//* FIXME: Need a mutex to avoid collisions with other tasks. */intmount_info::del_reg_mount (const char * posix_path, unsigned flags){  int res;  if (!(flags & MOUNT_SYSTEM))	/* Delete from user registry */    {      reg_key reg_user (KEY_ALL_ACCESS,			CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME, NULL);      res = reg_user.kill (posix_path);    }  else					/* Delete from system registry */    {      sys_mount_table_counter++;      cygwin_shared->sys_mount_table_counter++;      reg_key reg_sys (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",		       CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,		       CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,		       NULL);      res = reg_sys.kill (posix_path);    }  if (res != ERROR_SUCCESS)    {      __seterrno_from_win_error (res);      return -1;    }  return 0; /* Success */}/* read_cygdrive_info_from_registry: Read the default prefix and flags   to use when creating cygdrives from the special user registry   location used to store cygdrive information. */voidmount_info::read_cygdrive_info_from_registry (){  /* reg_key for user path prefix in HKEY_CURRENT_USER. */  reg_key r;  if (r.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, cygdrive, sizeof (cygdrive), "") != 0)    {      /* Didn't find the user path prefix so check the system path prefix. */      /* reg_key for system path prefix in HKEY_LOCAL_MACHINE.  */      reg_key r2 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE",		 CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,		 CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,		 NULL);      if (r2.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, cygdrive,	  sizeof (cygdrive), ""))	strcpy (cygdrive, CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX);      cygdrive_flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);      slashify (cygdrive, cygdrive, 1);      cygdrive_len = strlen (cygdrive);

⌨️ 快捷键说明

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