using System.Security;
using System.Security.Permissions;
using System.Text;
+#if NET_2_0
+using System.Security.AccessControl;
+using System.Runtime.InteropServices;
+#endif
namespace System.IO
{
+#if NET_2_0
+ [ComVisible (true)]
+#endif
public
#if NET_2_0
static
if (path.Trim ().Length == 0)
throw new ArgumentException ("Only blank characters in path");
+
+#if NET_2_0
+ if (File.Exists(path))
+ throw new IOException ("Cannot create " + path + " because a file with the same name already exists.");
+#endif
// LAMESPEC: with .net 1.0 version this throw NotSupportedException and msdn says so too
// but v1.1 throws ArgumentException.
return CreateDirectoriesInternal (path);
}
+#if NET_2_0
+ [MonoTODO ("DirectorySecurity not implemented")]
+ public static DirectoryInfo CreateDirectory (string path, DirectorySecurity directorySecurity)
+ {
+ return(CreateDirectory (path));
+ }
+#endif
+
static DirectoryInfo CreateDirectoriesInternal (string path)
{
if (SecurityManager.SecurityEnabled) {
// and having di.Exists return false afterwards.
// I hope we don't break anyone's code, as they should be catching
// the exception anyway.
- if (error != MonoIOError.ERROR_ALREADY_EXISTS)
+ if (error != MonoIOError.ERROR_ALREADY_EXISTS &&
+ error != MonoIOError.ERROR_FILE_EXISTS)
throw MonoIO.GetException (path, error);
}
throw new NotSupportedException ("Only ':' In path");
MonoIOError error;
+ bool success;
- if (!MonoIO.RemoveDirectory (path, out error)) {
+ if (MonoIO.ExistsSymlink (path, out error)) {
+ /* RemoveDirectory maps to rmdir()
+ * which fails on symlinks (ENOTDIR)
+ */
+ success = MonoIO.DeleteFile (path, out error);
+ } else {
+ success = MonoIO.RemoveDirectory (path, out error);
+ }
+
+ if (!success) {
/*
* FIXME:
* In io-layer/io.c rmdir returns error_file_not_found if directory does not exists.
* So maybe this could be handled somewhere else?
*/
if (error == MonoIOError.ERROR_FILE_NOT_FOUND)
- throw new DirectoryNotFoundException ("Directory '" + path + "' doesnt exists.");
+ throw new DirectoryNotFoundException ("Directory '" + path + "' does not exist");
else
throw MonoIO.GetException (path, error);
}
static void RecursiveDelete (string path)
{
- foreach (string dir in GetDirectories (path))
- RecursiveDelete (dir);
+ MonoIOError error;
+
+ foreach (string dir in GetDirectories (path)) {
+ if (MonoIO.ExistsSymlink (dir, out error)) {
+ MonoIO.DeleteFile (dir, out error);
+ } else {
+ RecursiveDelete (dir);
+ }
+ }
foreach (string file in GetFiles (path))
File.Delete (file);
exists = MonoIO.ExistsDirectory (path, out error);
if (error != MonoIOError.ERROR_SUCCESS &&
- error != MonoIOError.ERROR_PATH_NOT_FOUND) {
+ error != MonoIOError.ERROR_PATH_NOT_FOUND &&
+ error != MonoIOError.ERROR_INVALID_HANDLE &&
+ error != MonoIOError.ERROR_ACCESS_DENIED) {
+
+ // INVALID_HANDLE might happen if the file is moved
+ // while testing for the existence, a kernel issue
+ // according to Larry Ewing.
+
throw MonoIO.GetException (path, error);
}
{
return File.GetLastAccessTime (path);
}
-
+
public static DateTime GetLastAccessTimeUtc (string path)
{
return GetLastAccessTime (path).ToUniversalTime ();
}
-
+
public static DateTime GetLastWriteTime (string path)
{
return File.GetLastWriteTime (path);
return GetFileSystemEntries (path, pattern, FileAttributes.Directory, FileAttributes.Directory);
}
+#if NET_2_0
+ public static string [] GetDirectories (string path, string pattern, SearchOption option)
+ {
+ if (option == SearchOption.TopDirectoryOnly)
+ return GetDirectories (path, pattern);
+ ArrayList all = new ArrayList ();
+ GetDirectoriesRecurse (path, pattern, all);
+ return (string []) all.ToArray (typeof (string));
+ }
+
+ static void GetDirectoriesRecurse (string path, string pattern, ArrayList all)
+ {
+ all.AddRange (GetDirectories (path, pattern));
+ foreach (string dir in GetDirectories (path))
+ GetDirectoriesRecurse (dir, pattern, all);
+ }
+#endif
+
public static string GetDirectoryRoot (string path)
{
return new String(Path.DirectorySeparatorChar,1);
return GetFileSystemEntries (path, pattern, FileAttributes.Directory, 0);
}
+#if NET_2_0
+ public static string[] GetFiles (string path, string searchPattern, SearchOption searchOption)
+ {
+ if (searchOption == SearchOption.TopDirectoryOnly)
+ return GetFiles (path, searchPattern);
+ ArrayList all = new ArrayList ();
+ GetFilesRecurse (path, searchPattern, all);
+ return (string []) all.ToArray (typeof (string));
+ }
+
+ static void GetFilesRecurse (string path, string pattern, ArrayList all)
+ {
+ all.AddRange (GetFiles (path, pattern));
+ foreach (string dir in GetDirectories (path))
+ GetFilesRecurse (dir, pattern, all);
+ }
+#endif
+
public static string [] GetFileSystemEntries (string path)
{
return GetFileSystemEntries (path, "*");
static bool IsRootDirectory (string path)
{
// Unix
- if (Path.DirectorySeparatorChar == '/' && path == "/")
- return true;
+ if (Path.DirectorySeparatorChar == '/' && path == "/")
+ return true;
- // Windows
- if (Path.DirectorySeparatorChar == '\\')
- if (path.Length == 3 && path.EndsWith (":\\"))
- return true;
+ // Windows
+ if (Path.DirectorySeparatorChar == '\\')
+ if (path.Length == 3 && path.EndsWith (":\\"))
+ return true;
- return false;
+ return false;
}
public static DirectoryInfo GetParent (string path)
// return null if the path is the root directory
if (IsRootDirectory (path))
return null;
-
- return new DirectoryInfo (Path.GetDirectoryName (path));
+
+ string parent_name = Path.GetDirectoryName (path);
+ if (parent_name == "")
+ parent_name = GetCurrentDirectory();
+
+ return new DirectoryInfo (parent_name);
}
- public static void Move (string src, string dest)
+ public static void Move (string sourceDirName, string destDirName)
{
- if (src == null)
- throw new ArgumentNullException ("src");
+ if (sourceDirName == null)
+ throw new ArgumentNullException ("sourceDirName");
- if (dest == null)
- throw new ArgumentNullException ("dest");
+ if (destDirName == null)
+ throw new ArgumentNullException ("destDirName");
- if (src.Trim () == "" || src.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Invalid source directory name: " + src, "src");
+ if (sourceDirName.Trim () == "" || sourceDirName.IndexOfAny (Path.InvalidPathChars) != -1)
+ throw new ArgumentException ("Invalid source directory name: " + sourceDirName, "sourceDirName");
- if (dest.Trim () == "" || dest.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException ("Invalid target directory name: " + dest, "dest");
+ if (destDirName.Trim () == "" || destDirName.IndexOfAny (Path.InvalidPathChars) != -1)
+ throw new ArgumentException ("Invalid target directory name: " + destDirName, "destDirName");
- if (src == dest)
- throw new IOException ("Source directory cannot be same as a target directory.");
+ if (sourceDirName == destDirName)
+ throw new IOException ("Source and destination path must be different.");
- if (Exists (dest))
- throw new IOException (dest + " already exists.");
+ if (Exists (destDirName))
+ throw new IOException (destDirName + " already exists.");
- if (!Exists (src))
- throw new DirectoryNotFoundException (src + " does not exist");
+ if (!Exists (sourceDirName) && !File.Exists (sourceDirName))
+ throw new DirectoryNotFoundException (sourceDirName + " does not exist");
MonoIOError error;
- if (!MonoIO.MoveFile (src, dest, out error))
+ if (!MonoIO.MoveFile (sourceDirName, destDirName, out error))
throw MonoIO.GetException (error);
}
+#if NET_2_0
+ public static void SetAccessControl (string path, DirectorySecurity directorySecurity)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
+
public static void SetCreationTime (string path, DateTime creation_time)
{
File.SetCreationTime (path, creation_time);
private static string [] GetFileSystemEntries (string path, string pattern, FileAttributes mask, FileAttributes attrs)
{
- MonoIOStat stat;
- IntPtr find;
-
if (path == null || pattern == null)
throw new ArgumentNullException ();
throw new ArgumentException ("Path is invalid", "path");
}
- find = MonoIO.FindFirstFile (wild, out stat, out error);
- if (find == MonoIO.InvalidHandle) {
- switch (error) {
- case MonoIOError.ERROR_PATH_NOT_FOUND:
- string message = String.Format ("Could not find a part of the path \"{0}\"",
- wildpath);
- throw new DirectoryNotFoundException (message);
- case MonoIOError.ERROR_FILE_NOT_FOUND:
- case MonoIOError.ERROR_NO_MORE_FILES:
- return new string [0];
-
- default:
- throw MonoIO.GetException (wildpath, error);
- }
- }
+ string path_with_pattern = Path.Combine (wildpath, pattern);
+ string [] result = MonoIO.GetFileSystemEntries (path, path_with_pattern, (int) attrs, (int) mask, out error);
+ if (error != 0)
+ throw MonoIO.GetException (wildpath, error);
- ArrayList entries = new ArrayList ();
-
- do {
- if ((stat.Attributes & mask) == attrs)
- entries.Add (Path.Combine (wildpath, stat.Name));
- } while (MonoIO.FindNextFile (find, out stat, out error));
+ return result;
+ }
- MonoIO.FindClose (find, out error);
+#if NET_2_0
+ [MonoNotSupported ("DirectorySecurity isn't implemented")]
+ public static DirectorySecurity GetAccessControl (string path, AccessControlSections includeSections)
+ {
+ throw new PlatformNotSupportedException ();
+ }
- return (string []) entries.ToArray (typeof (string));
+ [MonoNotSupported ("DirectorySecurity isn't implemented")]
+ public static DirectorySecurity GetAccessControl (string path)
+ {
+ throw new PlatformNotSupportedException ();
}
+#endif
}
}