7
class UnixFileHelper : FileHelper
9
static UnixFileSystemInfo GetUnixFileInfo (string path)
12
return Mono.Unix.UnixFileInfo.GetFileSystemEntry (path);
13
} catch (DirectoryNotFoundException ex) {
14
// If we have a file /foo/bar and probe the path /foo/bar/baz, we get a DirectoryNotFound exception
15
// because 'bar' is a file and therefore 'baz' cannot possibly exist. This is annoying.
16
var inner = ex.InnerException as UnixIOException;
17
if (inner != null && inner.ErrorCode == Mono.Unix.Native.Errno.ENOTDIR)
23
public override bool CanExecute (FilePath path)
25
UnixFileInfo fi = new UnixFileInfo (path);
28
return 0 != (fi.FileAccessPermissions & (FileAccessPermissions.UserExecute | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherExecute));
31
public override bool CanWrite (FilePath path)
33
var info = GetUnixFileInfo (path);
34
return info != null && info.CanAccess (Mono.Unix.Native.AccessModes.W_OK);
37
public override bool Delete (FilePath path)
39
var info = GetUnixFileInfo (path);
40
if (info != null && info.Exists) {
45
// If the directory is not empty we return false. JGit relies on this
52
public override bool Exists (FilePath path)
54
var info = GetUnixFileInfo (path);
55
return info != null && info.Exists;
58
public override bool IsDirectory (FilePath path)
61
var info = GetUnixFileInfo (path);
62
return info != null && info.Exists && info.FileType == FileTypes.Directory;
63
} catch (DirectoryNotFoundException) {
64
// If the file /foo/bar exists and we query to see if /foo/bar/baz exists, we get a
65
// DirectoryNotFound exception for Mono.Unix. In this case the directory definitely
71
public override bool IsFile (FilePath path)
73
var info = GetUnixFileInfo (path);
74
return info != null && info.Exists && (info.FileType == FileTypes.RegularFile || info.FileType == FileTypes.SymbolicLink);
77
public override long LastModified (FilePath path)
79
var info = GetUnixFileInfo (path);
80
return info != null && info.Exists ? info.LastWriteTimeUtc.ToMillisecondsSinceEpoch() : 0;
83
public override long Length (FilePath path)
85
var info = GetUnixFileInfo (path);
86
return info != null && info.Exists ? info.Length : 0;
89
public override void MakeFileWritable (FilePath file)
91
var info = GetUnixFileInfo (file);
93
info.FileAccessPermissions |= (FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite | FileAccessPermissions.UserWrite);
96
public override bool RenameTo (FilePath path, string name)
98
var symlink = GetUnixFileInfo (path) as UnixSymbolicLinkInfo;
99
if (symlink != null) {
100
var newFile = new UnixSymbolicLinkInfo (name);
101
newFile.CreateSymbolicLinkTo (symlink.ContentsPath);
104
// This call replaces the file if it already exists.
105
// File.Move throws an exception if dest already exists
106
return Mono.Unix.Native.Stdlib.rename (path, name) == 0;
110
public override bool SetExecutable (FilePath path, bool exec)
112
UnixFileInfo fi = new UnixFileInfo (path);
113
FileAccessPermissions perms = fi.FileAccessPermissions;
115
if (perms.HasFlag (FileAccessPermissions.UserRead))
116
perms |= FileAccessPermissions.UserExecute;
117
if (perms.HasFlag (FileAccessPermissions.OtherRead))
118
perms |= FileAccessPermissions.OtherExecute;
119
if ((perms.HasFlag (FileAccessPermissions.GroupRead)))
120
perms |= FileAccessPermissions.GroupExecute;
122
if (perms.HasFlag (FileAccessPermissions.UserRead))
123
perms &= ~FileAccessPermissions.UserExecute;
124
if (perms.HasFlag (FileAccessPermissions.OtherRead))
125
perms &= ~FileAccessPermissions.OtherExecute;
126
if ((perms.HasFlag (FileAccessPermissions.GroupRead)))
127
perms &= ~FileAccessPermissions.GroupExecute;
129
fi.FileAccessPermissions = perms;
133
public override bool SetLastModified(FilePath path, long milis)
135
// How can the last write time be set on a symlink?
136
return base.SetLastModified(path, milis);
139
public override bool SetReadOnly (FilePath path)
142
var info = GetUnixFileInfo (path);
144
info.FileAccessPermissions &= ~ (FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite | FileAccessPermissions.UserWrite);