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

📄 path.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 5 页
字号:
    }  else    {      /* Fetch user cygdrive_flags from registry; returns MOUNT_CYGDRIVE on	 error. */      cygdrive_flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);      slashify (cygdrive, cygdrive, 1);      cygdrive_len = strlen (cygdrive);    }}/* write_cygdrive_info_to_registry: Write the default prefix and flags   to use when creating cygdrives to the special user registry   location used to store cygdrive information. */intmount_info::write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags){  /* Determine whether to modify user or system cygdrive path prefix. */  HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;  if (flags & MOUNT_SYSTEM)    {      sys_mount_table_counter++;      cygwin_shared->sys_mount_table_counter++;    }  /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in     HKEY_LOCAL_MACHINE.  */  reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",	     CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,	     CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,	     NULL);  /* Verify cygdrive prefix starts with a forward slash and if there's     another character, it's not a slash. */  if ((cygdrive_prefix == NULL) || (*cygdrive_prefix == 0) ||      (!isslash (cygdrive_prefix[0])) ||      ((cygdrive_prefix[1] != '\0') && (isslash (cygdrive_prefix[1]))))      {	set_errno (EINVAL);	return -1;      }  char hold_cygdrive_prefix[strlen (cygdrive_prefix) + 1];  /* Ensure that there is never a final slash */  nofinalslash (cygdrive_prefix, hold_cygdrive_prefix);  int res;  res = r.set_string (CYGWIN_INFO_CYGDRIVE_PREFIX, hold_cygdrive_prefix);  if (res != ERROR_SUCCESS)    {      __seterrno_from_win_error (res);      return -1;    }  r.set_int (CYGWIN_INFO_CYGDRIVE_FLAGS, flags);  /* This also needs to go in the in-memory copy of "cygdrive", but only if     appropriate:       1. setting user path prefix, or       2. overwriting (a previous) system path prefix */  if (!(flags & MOUNT_SYSTEM) || (mount_table->cygdrive_flags & MOUNT_SYSTEM))    {      slashify (cygdrive_prefix, mount_table->cygdrive, 1);      mount_table->cygdrive_flags = flags;      mount_table->cygdrive_len = strlen (mount_table->cygdrive);    }  return 0;}intmount_info::remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags){  /* Determine whether to modify user or system cygdrive path prefix. */  HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;  if (flags & MOUNT_SYSTEM)    {      sys_mount_table_counter++;      cygwin_shared->sys_mount_table_counter++;    }  /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in     HKEY_LOCAL_MACHINE.  */  reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",	     CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,	     CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,	     NULL);  /* Delete cygdrive prefix and flags. */  int res = r.killvalue (CYGWIN_INFO_CYGDRIVE_PREFIX);  int res2 = r.killvalue (CYGWIN_INFO_CYGDRIVE_FLAGS);  /* Reinitialize the cygdrive path prefix to reflect to removal from the     registry. */  read_cygdrive_info_from_registry ();  return (res != ERROR_SUCCESS) ? res : res2;}intmount_info::get_cygdrive_info (char *user, char *system, char* user_flags,			       char* system_flags){  /* Get the user path prefix from HKEY_CURRENT_USER. */  reg_key r;  int res = r.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, user, MAX_PATH, "");  /* Get the user flags, if appropriate */  if (res == ERROR_SUCCESS)    {      int flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);      strcpy (user_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode");    }  /* Get the system path prefix from 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);  int res2 = r2.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, system, MAX_PATH, "");  /* Get the system flags, if appropriate */  if (res2 == ERROR_SUCCESS)    {      int flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);      strcpy (system_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode");    }  return (res != ERROR_SUCCESS) ? res : res2;}static mount_item *mounts_for_sort;/* sort_by_posix_name: qsort callback to sort the mount entries.  Sort   user mounts ahead of system mounts to the same POSIX path. *//* FIXME: should the user should be able to choose whether to   prefer user or system mounts??? */static intsort_by_posix_name (const void *a, const void *b){  mount_item *ap = mounts_for_sort + (*((int*) a));  mount_item *bp = mounts_for_sort + (*((int*) b));  /* Base weighting on longest posix path first so that the most     obvious path will be chosen. */  size_t alen = strlen (ap->posix_path);  size_t blen = strlen (bp->posix_path);  int res = blen - alen;  if (res)    return res;		/* Path lengths differed */  /* The two paths were the same length, so just determine normal     lexical sorted order. */  res = strcmp (ap->posix_path, bp->posix_path);  if (res == 0)   {     /* need to select between user and system mount to same POSIX path */     if (!(bp->flags & MOUNT_SYSTEM))	/* user mount */      return 1;     else      return -1;   }  return res;}/* sort_by_native_name: qsort callback to sort the mount entries.  Sort   user mounts ahead of system mounts to the same POSIX path. *//* FIXME: should the user should be able to choose whether to   prefer user or system mounts??? */static intsort_by_native_name (const void *a, const void *b){  mount_item *ap = mounts_for_sort + (*((int*) a));  mount_item *bp = mounts_for_sort + (*((int*) b));  /* Base weighting on longest win32 path first so that the most     obvious path will be chosen. */  size_t alen = strlen (ap->native_path);  size_t blen = strlen (bp->native_path);  int res = blen - alen;  if (res)    return res;		/* Path lengths differed */  /* The two paths were the same length, so just determine normal     lexical sorted order. */  res = strcmp (ap->native_path, bp->native_path);  if (res == 0)   {     /* need to select between user and system mount to same POSIX path */     if (!(bp->flags & MOUNT_SYSTEM))	/* user mount */      return 1;     else      return -1;   }  return res;}voidmount_info::sort (){  for (int i = 0; i < nmounts; i++)    native_sorted[i] = posix_sorted[i] = i;  /* Sort them into reverse length order, otherwise we won't     be able to look for /foo in /.  */  mounts_for_sort = mount;	/* ouch. */  qsort (posix_sorted, nmounts, sizeof (posix_sorted[0]), sort_by_posix_name);  qsort (native_sorted, nmounts, sizeof (native_sorted[0]), sort_by_native_name);}/* Add an entry to the mount table.   Returns 0 on success, -1 on failure and errno is set.   This is where all argument validation is done.  It may not make sense to   do this when called internally, but it's cleaner to keep it all here.  */intmount_info::add_item (const char *native, const char *posix, unsigned mountflags, int reg_p){  /* Something's wrong if either path is NULL or empty, or if it's     not a UNC or absolute path. */  if ((native == NULL) || (*native == 0) ||      (posix == NULL) || (*posix == 0) ||      !isabspath (native) || !isabspath (posix) ||      slash_unc_prefix_p (posix) || isdrive (posix))    {      set_errno (EINVAL);      return -1;    }  /* Make sure both paths do not end in /. */  char nativetmp[MAX_PATH];  char posixtmp[MAX_PATH];  backslashify (native, nativetmp, 0);  nofinalslash (nativetmp, nativetmp);  slashify (posix, posixtmp, 0);  nofinalslash (posixtmp, posixtmp);  debug_printf ("%s[%s], %s[%s], %p",		native, nativetmp, posix, posixtmp, mountflags);  /* Duplicate /'s in path are an error. */  for (char *p = posixtmp + 1; *p; ++p)    {      if (p[-1] == '/' && p[0] == '/')	{	  set_errno (EINVAL);	  return -1;	}    }  /* Write over an existing mount item with the same POSIX path if     it exists and is from the same registry area. */  int i;  for (i = 0; i < nmounts; i++)    {      if (strcasematch (mount[i].posix_path, posixtmp) &&	  (mount[i].flags & MOUNT_SYSTEM) == (mountflags & MOUNT_SYSTEM))	break;    }  if (i == nmounts && nmounts == MAX_MOUNTS)    {      set_errno (EMFILE);      return -1;    }  if (reg_p && add_reg_mount (nativetmp, posixtmp, mountflags))    return -1;  if (i == nmounts)    nmounts++;  mount[i].init (nativetmp, posixtmp, mountflags);  sort ();  return 0;}/* Delete a mount table entry where path is either a Win32 or POSIX   path. Since the mount table is really just a table of aliases,   deleting / is ok (although running without a slash mount is   strongly discouraged because some programs may run erratically   without one).  If MOUNT_SYSTEM is set in flags, remove from system   registry, otherwise remove the user registry mount.*/intmount_info::del_item (const char *path, unsigned flags, int reg_p){  char pathtmp[MAX_PATH];  int posix_path_p = false;  /* Something's wrong if path is NULL or empty. */  if (path == NULL || *path == 0 || !isabspath (path))    {      set_errno (EINVAL);      return -1;    }  if (slash_unc_prefix_p (path) || strpbrk (path, ":\\"))    backslashify (path, pathtmp, 0);  else    {      slashify (path, pathtmp, 0);      posix_path_p = TRUE;    }  nofinalslash (pathtmp, pathtmp);  if (reg_p && posix_path_p &&      del_reg_mount (pathtmp, flags) &&      del_reg_mount (path, flags)) /* for old irregular entries */    return -1;  for (int i = 0; i < nmounts; i++)    {      int ent = native_sorted[i]; /* in the same order as getmntent() */      if (((posix_path_p)	   ? strcasematch (mount[ent].posix_path, pathtmp)	   : strcasematch (mount[ent].native_path, pathtmp)) &&	  (mount[ent].flags & MOUNT_SYSTEM) == (flags & MOUNT_SYSTEM))	{	  if (!posix_path_p &&	      reg_p && del_reg_mount (mount[ent].posix_path, flags))	    return -1;	  nmounts--; /* One less mount table entry */	  /* Fill in the hole if not at the end of the table */	  if (ent < nmounts)	    memmove (mount + ent, mount + ent + 1,		     sizeof (mount[ent]) * (nmounts - ent));	  sort (); /* Resort the table */	  return 0;	}    }  set_errno (EINVAL);  return -1;}/************************* mount_item class ****************************/static mntent *fillout_mntent (const char *native_path, const char *posix_path, unsigned flags){#ifdef _MT_SAFE  struct mntent &ret=_reent_winsup ()->mntbuf;#else  static NO_COPY struct mntent ret;#endif  /* Remove drivenum from list if we see a x: style path */  if (strlen (native_path) == 2 && native_path[1] == ':')    {      int drivenum = cyg_tolower (native_path[0]) - 'a';      if (drivenum >= 0 && drivenum <= 31)	available_drives &= ~(1 << drivenum);    }  /* Pass back pointers to mount_table strings reserved for use by     getmntent rather than pointers to strings in the internal mount     table because the mount table might change, causing weird effects     from the getmntent user's point of view. */  strcpy (_reent_winsup ()->mnt_fsname, native_path);  ret.mnt_fsname = _reent_winsup ()->mnt_fsname;  strcpy (_reent_winsup ()->mnt_dir, posix_path);  ret.mnt_dir = _reent_winsup ()->mnt_dir;  if (!(flags & MOUNT_SYSTEM))		/* user mount */    strcpy (_reent_winsup ()->mnt_type, (char *) "user");  else					/* system mount */    strcpy (_reent_winsup ()->mnt_type, (char *) "system");  ret.mnt_type = _reent_winsup ()->mnt_type;  /* mnt_opts is a string that details mount params such as     binary or textmode, or exec.  We don't print     `silent' here; it's a magic internal thing. */  if (!(flags & MOUNT_BINARY))    strcpy (_reent_winsup ()->mnt_opts, (char *) "textmode");  else    strcpy (_reent_winsup ()->mnt_opts, (char *) "binmode");  if (flags & MOUNT_CYGWIN_EXEC)    strcat (_reent_winsup ()->mnt_opts, (char *) ",cygexec");  else if (flags & MOUNT_EXEC)    strcat (_reent_winsup ()->mnt_opts, (char *) ",exec");  else if (flags & MOUNT_NOTEXEC)    strcat (_reent_winsup ()->mnt_opts, (char *) ",noexec");  if ((flags & MOUNT_CYGDRIVE))		/* cygdrive */    strcat (_reent_winsup ()->mnt_opts, (char *) ",noumount");  ret.mnt_opts = _reent_winsup ()->mnt_opts;  ret.mnt_freq = 1;  ret.mnt_passno = 1;  return &ret;}struct mntent *mount_item::getmntent (){  return fillout_mntent (native_path, posix_path, flags);}static struct mntent *cygdrive_getmntent (){  char native_path[4];  char posix_path[MAX_PATH];  DWORD mask = 1, drive = 'a';  struct mntent *ret = NULL;  while (available_drives)    {      for (/* nothing */; drive <= 'z'; mask <<= 1, drive++)	if (available_drives & mask)	  break;      __small_sprintf (native_path, "%c:\\", drive);      if (GetDriveType (native_path) == DRIVE_REMOVABLE ||	  GetFileAttributes (native_path) == INVALID_FILE_ATTRIBUTES)	{	  available_drives &= ~mask;	  continue;	}      native_path[2] = '\0';      __small_sprintf (posix_path, "%s%c", mount_table->cygdrive, drive);      ret = fillout_mntent (native_path, posix_path, mount_table->cygdrive_flags);      break;    }  return ret;}struct mntent *mount_info::getmntent (int x){  if (x < 0 || x >= nmounts)    return cygdrive_getmntent ();  return mount[native_sorted[x]].getmntent ();}/* Fill in the fields of a mount table entry.  */voidmount_item::init (const char *native, const char *posix, unsigned mountflags){  strcpy ((char *) native_path, native);  strcpy ((char *) posix_path, posix);  native_pathlen = strlen (native_path);  posix_pathlen = strlen (posix_path);  flags = mountflags;}/********************** Mount System Calls **************************//* Mount table system calls.   Note that these are exported to the application.  *//* mount: Add a mount to the mount table in memory and to the registry   that will cause paths under win32_path to be translated to paths   under posix_path. */extern "C" intmount (const char *win32_path, const char *posix_path, unsigned flags){  int res = -1;  if (flags & MOUNT_CYGDRIVE) /* normal mount */    {      /* When flags include MOUNT_CYGDRIVE, take this to mean that	we actually want to change the cygdrive prefix and flags	without actually mounting anything. */      res = mount_table->write_cygdrive_info_to_

⌨️ 快捷键说明

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