diff options
Diffstat (limited to 'mcs/class/Mono.Posix')
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/ChangeLog | 10 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/Syscall.cs | 16 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/UnixPath.cs | 42 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/UnixSymbolicLinkInfo.cs | 8 |
4 files changed, 54 insertions, 22 deletions
diff --git a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog index 30d83b0ca3a..35148170042 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog +++ b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog @@ -1,3 +1,13 @@ +2004-12-29 Jonathan Pryor <jonpryor@vt.edu> + + * Syscall.cs: Fix Object.Equals implementations. + * UnixPath.cs: New & improved, with Testing! GetRealPath() is changed so + that it doesn't walk the entire path looking for symlinks, it just reads + the leaf. GetCompletRealPath() walks the entire path resolving symlinks. + GetCanonicalPath() added, which "cleans up" a path (removing extraneous + "." and ".." entries). + * UnixSymbolicLinkInfo.cs: Rename ContentsLength -> MaxContentsSize. + 2004-12-28 Jonathan Pryor <jonpryor@vt.edu> * UnixFileSystemInfo.cs: Add a link(2) wrapper, CreateLink(). Strictly diff --git a/mcs/class/Mono.Posix/Mono.Unix/Syscall.cs b/mcs/class/Mono.Posix/Mono.Unix/Syscall.cs index 0a16ec25b70..43d9f33b4af 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/Syscall.cs +++ b/mcs/class/Mono.Posix/Mono.Unix/Syscall.cs @@ -838,7 +838,7 @@ namespace Mono.Unix { Dirent d = (Dirent) obj; return d.d_ino == d_ino && d.d_off == d_off && d.d_reclen == d_reclen && d.d_type == d_type && - d.d_name == d.d_name; + d.d_name == d_name; } public override string ToString () @@ -925,8 +925,14 @@ namespace Mono.Unix { Group g = (Group) obj; if (g.gr_gid != gr_gid) return false; - if (g.gr_gid == gr_gid && g.gr_name == g.gr_name && - g.gr_passwd == g.gr_passwd && g.gr_mem.Length == gr_mem.Length) { + if (g.gr_gid == gr_gid && g.gr_name == gr_name && + g.gr_passwd == gr_passwd) { + if (g.gr_mem == gr_mem) + return true; + if (g.gr_mem == null || gr_mem == null) + return false; + if (g.gr_mem.Length != gr_mem.Length) + return false; for (int i = 0; i < gr_mem.Length; ++i) if (gr_mem[i] != g.gr_mem[i]) return false; @@ -989,8 +995,8 @@ namespace Mono.Unix { return false; Passwd p = (Passwd) obj; return p.pw_uid == pw_uid && p.pw_gid == pw_gid && p.pw_name == pw_name && - p.pw_passwd == pw_passwd && p.pw_gecos == p.pw_gecos && - p.pw_dir == p.pw_dir && p.pw_shell == p.pw_shell; + p.pw_passwd == pw_passwd && p.pw_gecos == pw_gecos && + p.pw_dir == pw_dir && p.pw_shell == pw_shell; } // Generate string in /etc/passwd format diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixPath.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixPath.cs index 679c2c1405a..6503c7a7429 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/UnixPath.cs +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixPath.cs @@ -103,10 +103,7 @@ namespace Mono.Unix { public static string GetFullPath (string path) { path = _GetFullPath (path); - string [] dirs; - int lastIndex; - GetPathComponents (path, out dirs, out lastIndex); - return string.Join ("/", dirs, 0, lastIndex); + return GetCanonicalPath (path); } private static string _GetFullPath (string path) @@ -119,15 +116,25 @@ namespace Mono.Unix { return path; } + public static string GetCanonicalPath (string path) + { + string [] dirs; + int lastIndex; + GetPathComponents (path, out dirs, out lastIndex); + string end = string.Join ("/", dirs, 0, lastIndex); + return IsPathRooted (path) ? "/" + end : end; + } + private static void GetPathComponents (string path, out string[] components, out int lastIndex) { string [] dirs = path.Split (DirectorySeparatorChar); int target = 0; for (int i = 0; i < dirs.Length; ++i) { - if (dirs [i] == "." || (i != 0 && dirs [i] == string.Empty)) continue; + if (dirs [i] == "." || dirs [i] == string.Empty) continue; else if (dirs [i] == "..") { if (target != 0) --target; + else ++target; } else dirs [target++] = dirs [i]; @@ -145,25 +152,32 @@ namespace Mono.Unix { return "/"; } - public static string GetRealPath (string path) + public static string GetCompleteRealPath (string path) { - path = _GetFullPath (path); + if (path == null) + throw new ArgumentNullException ("path"); string [] dirs; int lastIndex; GetPathComponents (path, out dirs, out lastIndex); StringBuilder realPath = new StringBuilder (); - for (int i = 0; i < dirs.Length; ++i) { + if (dirs.Length > 0) { + string dir = IsPathRooted (path) ? "/" : ""; + dir += dirs [0]; + realPath.Append (GetRealPath (dir)); + } + for (int i = 1; i < lastIndex; ++i) { realPath.Append ("/").Append (dirs [i]); - string p = _GetRealPath (realPath.ToString()); + string p = GetRealPath (realPath.ToString()); realPath.Remove (0, realPath.Length); realPath.Append (p); } return realPath.ToString (); } - private static string _GetRealPath (string path) + public static string GetRealPath (string path) { - StringBuilder buf = new StringBuilder (1024); + StringBuilder buf = + new StringBuilder (UnixSymbolicLinkInfo.MaxContentsSize); int r; do { r = Syscall.readlink (path, buf); @@ -178,8 +192,10 @@ namespace Mono.Unix { break; } } - path = buf.ToString (); - } while (r == 0); + string name = buf.ToString (0, r); + path = GetDirectoryName (path) + DirectorySeparatorChar + name; + path = GetCanonicalPath (path); + } while (r >= 0); return path; } diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixSymbolicLinkInfo.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixSymbolicLinkInfo.cs index ea0336da154..1411410a1a0 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/UnixSymbolicLinkInfo.cs +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixSymbolicLinkInfo.cs @@ -50,7 +50,7 @@ namespace Mono.Unix { } // maximum number of bytes read from the symbolic link - public static readonly int ContentsLength = 1024; + public static readonly int MaxContentsSize = 1024; public UnixFileSystemInfo Contents { get { @@ -108,11 +108,11 @@ namespace Mono.Unix { { // Who came up with readlink(2)? There doesn't seem to be a way to // properly handle it. - StringBuilder sb = new StringBuilder (ContentsLength+1); - int r = Syscall.readlink (FullPath, sb, (ulong) ContentsLength); + StringBuilder sb = new StringBuilder (MaxContentsSize+1); + int r = Syscall.readlink (FullPath, sb, (ulong) MaxContentsSize); if (r == -1) return null; - return sb.ToString().Substring (0, r); + return sb.ToString(0, r); } } } |