Skip to content

Commit 17868b1

Browse files
committed
Add custom error handling for setattrlist
Add custom error handling for setattrlist as per dotnet#49555 (comment). ENOTDIR means it is not a directory, so directory not found seems logical to me, I think the other errors can be dealt with by an IOException, happy to change this.
1 parent e550082 commit 17868b1

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa
114114
switch (errorInfo.Error)
115115
{
116116
case Error.ENOENT:
117+
case Error.ENOTDIR:
117118
if (isDirectory)
118119
{
119120
return !string.IsNullOrEmpty(path) ?

src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.OSX.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@ internal unsafe void SetCreationTime(string path, DateTimeOffset time)
2222
attrList.commonAttr = Interop.libc.AttrList.ATTR_CMN_CRTIME;
2323

2424
// Try to set the attribute on the file system entry using setattrlist,
25-
// otherwise fall back to the method used on other unix platforms as the
26-
// path may either be on an unsupported volume type (for setattrlist) or it
27-
// could be another error (eg. no file) which the fallback implementation can throw.
28-
bool succeeded = Interop.libc.setattrlist(path, &attrList, &timeSpec, sizeof(Interop.Sys.TimeSpec), new CULong(Interop.libc.FSOPT_NOFOLLOW)) == 0;
29-
if (!succeeded)
25+
// if we get ENOTSUP then it means that "The volume does not support
26+
// setattrlist()", so we fall back to the method used on other unix
27+
// platforms, otherwise we throw an error if we get one, or invalidate
28+
// the cache if successful because otherwise it has invalid information.
29+
Interop.Error result = (Interop.Error)Interop.libc.setattrlist(path, &attrList, &timeSpec, sizeof(Interop.Sys.TimeSpec), new CULong(Interop.libc.FSOPT_NOFOLLOW));
30+
if (result == Interop.Error.ENOTSUP)
3031
{
3132
SetCreationTime_StandardUnixImpl(path, time);
3233
}
33-
else
34+
else if (result == Interop.Error.SUCCESS)
3435
{
3536
InvalidateCaches();
3637
}
38+
else
39+
{
40+
Interop.CheckIo(result, path, InitiallyDirectory);
41+
}
3742
}
3843

3944
private unsafe void SetAccessOrWriteTime(string path, DateTimeOffset time, bool isAccessTime)

0 commit comments

Comments
 (0)