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

📄 path.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 5 页
字号:
    ...    FH_FLOPPY	250	from mount tab	\\.\Z:*/static intget_raw_device_number (const char *name, const char *w32_path, int &unit){  DWORD devn = FH_BAD;  if (!w32_path)  /* New approach using fixed device names. */    {      if (deveqn ("st", 2))	{	  unit = digits (name + 2);	  if (unit >= 0 && unit < 128)	    devn = FH_TAPE;	}      else if (deveqn ("nst", 3))	{	  unit = digits (name + 3) + 128;	  if (unit >= 128 && unit < 256)	    devn = FH_TAPE;	}      else if (deveqn ("fd", 2))	{	  unit = digits (name + 2);	  if (unit >= 0 && unit < 16)	    devn = FH_FLOPPY;	}      else if (deveqn ("scd", 3))	{	  unit = digits (name + 3) + 16;	  if (unit >= 16 && unit < 32)	    devn = FH_FLOPPY;	}      else if (deveqn ("sd", 2) && isalpha (name[2]))	{	  unit = (cyg_tolower (name[2]) - 'a') * 16 + 32;	  if (unit >= 32 && unit < 224)	    if (!name[3])	      devn = FH_FLOPPY;	    else	      {		int d = digits (name + 3);		if (d >= 1 && d < 16)		  {		    unit += d;		    devn = FH_FLOPPY;		  }	      }	}    }  else /* Backward compatible checking of mount table device mapping. */    {      if (wdeveqn ("tape", 4))	{	  unit = digits (w32_path + 4);	  /* Norewind tape devices have leading n in name. */	  if (deveqn ("n", 1))	    unit += 128;	  devn = FH_TAPE;	}      else if (wdeveqn ("physicaldrive", 13))	{	  unit = digits (w32_path + 13) * 16 + 32;	  devn = FH_FLOPPY;	}      else if (isdrive (w32_path))	{	  unit = cyg_tolower (w32_path[0]) - 'a' + 224;	  devn = FH_FLOPPY;	}    }  return devn;}static int __stdcall get_device_number (const char *unix_path,					const char *w32_path, int &unit)  __attribute__ ((regparm(3)));static int __stdcallget_device_number (const char *unix_path, const char *w32_path, int &unit){  DWORD devn = FH_BAD;  unit = 0;  if (*unix_path == '/' && udeveqn ("/dev/", 5))    {      devn = get_devn (unix_path, unit);      if (devn == FH_BAD && *w32_path == '\\' && wdeveqn ("\\dev\\", 5))	devn = get_devn (w32_path, unit);      if (devn == FH_BAD && wdeveqn ("\\\\.\\", 4))	devn = get_raw_device_number (unix_path + 5, w32_path + 4, unit);      if (devn == FH_BAD)	devn = get_raw_device_number (unix_path + 5, NULL, unit);    }  else    {      char *p = strrchr (unix_path, '/');      if (p)	unix_path = p + 1;      if (udeveqn ("com", 3)	 && (unit = digits (unix_path + 3)) >= 0 && unit < 100)	devn = FH_SERIAL;    }  return devn;}/* Return TRUE if src_path is a Win32 device name, filling out the device   name in win32_path */static BOOLwin32_device_name (const char *src_path, char *win32_path,		   DWORD &devn, int &unit){  const char *devfmt;  devn = get_device_number (src_path, win32_path, unit);  if (devn == FH_BAD)    return false;  if ((devfmt = windows_device_names[FHDEVN (devn)]) == NULL)    return false;  switch (devn)    {      case FH_RANDOM:	__small_sprintf (win32_path, devfmt, unit == 8 ? "" : "u");	break;      case FH_TAPE:	__small_sprintf (win32_path, "\\Device\\Tape%d", unit % 128);	break;      case FH_FLOPPY:	if (unit < 16)	  __small_sprintf (win32_path, "\\Device\\Floppy%d", unit);	else if (unit < 32)	  __small_sprintf (win32_path, "\\Device\\CdRom%d", unit - 16);	else if (unit < 224)	  __small_sprintf (win32_path, "\\Device\\Harddisk%d\\Partition%d",				       (unit - 32) / 16, unit % 16);	else	  __small_sprintf (win32_path, "\\DosDevices\\%c:", unit - 224 + 'A');	break;      default:	__small_sprintf (win32_path, devfmt, unit);	break;    }  return TRUE;}/* Normalize a Win32 path.   /'s are converted to \'s in the process.   All duplicate \'s, except for 2 leading \'s, are deleted.   The result is 0 for success, or an errno error value.   FIXME: A lot of this should be mergeable with the POSIX critter.  */static intnormalize_win32_path (const char *src, char *dst){  const char *src_start = src;  char *dst_start = dst;  char *dst_root_start = dst;  bool beg_src_slash = isdirsep (src[0]);  if (beg_src_slash && isdirsep (src[1]))    {      *dst++ = '\\';      src++;      if (src[1] == '.' && isdirsep (src[2]))	{	  *dst++ = '\\';	  *dst++ = '.';	  src += 2;	}    }  else if (strchr (src, ':') == NULL && *src != '/')    {      if (!cygheap->cwd.get (dst, 0))	return get_errno ();      if (beg_src_slash)	{	  if (dst[1] == ':')	    dst[2] = '\0';	  else if (slash_unc_prefix_p (dst))	    {	      char *p = strpbrk (dst + 2, "\\/");	      if (p && (p = strpbrk (p + 1, "\\/")))		  *p = '\0';	    }	}      if (strlen (dst) + 1 + strlen (src) >= MAX_PATH)	{	  debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src);	  return ENAMETOOLONG;	}      dst += strlen (dst);      if (!beg_src_slash)	*dst++ = '\\';    }  while (*src)    {      /* Strip duplicate /'s.  */      if (SLASH_P (src[0]) && SLASH_P (src[1]))	src++;      /* Ignore "./".  */      else if (src[0] == '.' && SLASH_P (src[1])	       && (src == src_start || SLASH_P (src[-1])))	src += 2;      /* Backup if "..".  */      else if (src[0] == '.' && src[1] == '.'	       /* dst must be greater than dst_start */	       && dst[-1] == '\\'	       && (SLASH_P (src[2]) || src[2] == 0))	{	  /* Back up over /, but not if it's the first one.  */	  if (dst > dst_root_start + 1)	    dst--;	  /* Now back up to the next /.  */	  while (dst > dst_root_start + 1 && dst[-1] != '\\' && dst[-2] != ':')	    dst--;	  src += 2;	  if (SLASH_P (*src))	    src++;	}      /* Otherwise, add char to result.  */      else	{	  if (*src == '/')	    *dst++ = '\\';	  else	    *dst++ = *src;	  ++src;	}      if ((dst - dst_start) >= MAX_PATH)	return ENAMETOOLONG;    }  *dst = 0;  debug_printf ("%s = normalize_win32_path (%s)", dst_start, src_start);  return 0;}/* Various utilities.  *//* slashify: Convert all back slashes in src path to forward slashes   in dst path.  Add a trailing slash to dst when trailing_slash_p arg   is set to 1. */static voidslashify (const char *src, char *dst, int trailing_slash_p){  const char *start = src;  while (*src)    {      if (*src == '\\')	*dst++ = '/';      else	*dst++ = *src;      ++src;    }  if (trailing_slash_p      && src > start      && !isdirsep (src[-1]))    *dst++ = '/';  *dst++ = 0;}/* backslashify: Convert all forward slashes in src path to back slashes   in dst path.  Add a trailing slash to dst when trailing_slash_p arg   is set to 1. */static voidbackslashify (const char *src, char *dst, int trailing_slash_p){  const char *start = src;  while (*src)    {      if (*src == '/')	*dst++ = '\\';      else	*dst++ = *src;      ++src;    }  if (trailing_slash_p      && src > start      && !isdirsep (src[-1]))    *dst++ = '\\';  *dst++ = 0;}/* nofinalslash: Remove trailing / and \ from SRC (except for the   first one).  It is ok for src == dst.  */void __stdcallnofinalslash (const char *src, char *dst){  int len = strlen (src);  if (src != dst)    memcpy (dst, src, len + 1);  while (len > 1 && SLASH_P (dst[--len]))    dst[len] = '\0';}/* slash_unc_prefix_p: Return non-zero if PATH begins with //UNC/SHARE */int __stdcallslash_unc_prefix_p (const char *path){  char *p = NULL;  int ret = (isdirsep (path[0])	     && isdirsep (path[1])	     && isalpha (path[2])	     && path[3] != 0	     && !isdirsep (path[3])	     && ((p = strpbrk (path + 3, "\\/")) != NULL));  if (!ret || p == NULL)    return ret;  return ret && isalnum (p[1]);}/* conv_path_list: Convert a list of path names to/from Win32/POSIX. */static voidconv_path_list (const char *src, char *dst, int to_posix_p){  char *s;  char *d = dst;  char src_delim = to_posix_p ? ';' : ':';  char dst_delim = to_posix_p ? ':' : ';';  int (*conv_fn) (const char *, char *) = (to_posix_p					   ? cygwin_conv_to_posix_path					   : cygwin_conv_to_win32_path);  char *srcbuf = (char *) alloca (strlen (src) + 1);  for (;;)    {      s = strccpy (srcbuf, &src, src_delim);      int len = s - srcbuf;      if (len >= MAX_PATH)	srcbuf[MAX_PATH - 1] = '\0';      (*conv_fn) (len ? srcbuf : ".", d);      if (!*src++)	break;      d = strchr (d, '\0');      *d++ = dst_delim;    }}/* init: Initialize the mount table.  */voidmount_info::init (){  nmounts = 0;  /* Fetch the mount table and cygdrive-related information from     the registry.  */  from_registry ();}static voidset_flags (unsigned *flags, unsigned val){  *flags = val;  if (!(*flags & PATH_BINARY))    {      *flags |= PATH_TEXT;      debug_printf ("flags: text (%p)", *flags & (PATH_TEXT | PATH_BINARY));    }  else    {      *flags |= PATH_BINARY;      debug_printf ("flags: binary (%p)", *flags & (PATH_TEXT | PATH_BINARY));    }}/* conv_to_win32_path: Ensure src_path is a pure Win32 path and store   the result in win32_path.   If win32_path != NULL, the relative path, if possible to keep, is   stored in win32_path.  If the relative path isn't possible to keep,   the full path is stored.   If full_win32_path != NULL, the full path is stored there.   The result is zero for success, or an errno value.   {,full_}win32_path must have sufficient space (i.e. MAX_PATH bytes).  */intmount_info::conv_to_win32_path (const char *src_path, char *dst,				DWORD &devn, int &unit, unsigned *flags,				bool no_normalize){  while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter)    {      init ();      sys_mount_table_counter++;    }  int src_path_len = strlen (src_path);  MALLOC_CHECK;  unsigned dummy_flags;  int chroot_ok = !cygheap->root.exists ();  devn = FH_BAD;  unit = 0;  if (!flags)    flags = &dummy_flags;  *flags = 0;  debug_printf ("conv_to_win32_path (%s)", src_path);  if (src_path_len >= MAX_PATH)    {      debug_printf ("ENAMETOOLONG = conv_to_win32_path (%s)", src_path);      return ENAMETOOLONG;    }  int i, rc;  mount_item *mi = NULL;	/* initialized to avoid compiler warning */  char pathbuf[MAX_PATH];  if (dst == NULL)    goto out;		/* Sanity check. */  /* An MS-DOS spec has either a : or a \.  If this is found, short     circuit most of the rest of this function. */  if (strpbrk (src_path, ":\\") != NULL || slash_unc_prefix_p (src_path))    {      debug_printf ("%s already win32", src_path);      rc = normalize_win32_path (src_path, dst);      if (rc)	{	  debug_printf ("normalize_win32_path failed, rc %d", rc);	  return rc;	}      set_flags (flags, (unsigned) set_flags_from_win32_path (dst));      goto out;    }  /* Normalize the path, taking out ../../ stuff, we need to do this     so that we can move from one mounted directory to another with relative     stuff.     eg mounting c:/foo /foo     d:/bar /bar     cd /bar     ls ../foo     should look in c:/foo, not d:/foo.     We do this by first getting an absolute UNIX-style path and then     converting it to a DOS-style path, looking up the appropriate drive     in the mount table.  */  if (no_normalize)    strcpy (pathbuf, src_path);  else    {      rc = normalize_posix_path (src_path, pathbuf);      if (rc)	{	  debug_printf ("%d = conv_to_win32_path (%s)", rc, src_path);	  return rc;	}    }  /* See if this is a cygwin "device" */  if (win32_device_name (pathbuf, dst, devn, unit))    {      *flags = MOUNT_BINARY;	/* FIXME: Is this a sensible default for devices? */      rc = 0;      goto out_no_chroot_check;    }  /* Check if the cygdrive prefix was specified.  If so, just strip     off the prefix and transform it into an MS-DOS path. */  MALLOC_CHECK;  if (isproc (pathbuf))    {      devn = fhandler_proc::get_proc_fhandler (pathbuf);      if (devn == FH_BAD)	return ENOENT;    }  else if (iscygdrive (pathbuf))    {      int n = mount_table->cygdrive_len - 1;      if (!pathbuf[n] ||

⌨️ 快捷键说明

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