Skip to content

Commit

Permalink
Add custom error handling for setattrlist
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hamarb123 committed May 30, 2021
1 parent e550082 commit 17868b1
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa
switch (errorInfo.Error)
{
case Error.ENOENT:
case Error.ENOTDIR:
if (isDirectory)
{
return !string.IsNullOrEmpty(path) ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,23 @@ internal unsafe void SetCreationTime(string path, DateTimeOffset time)
attrList.commonAttr = Interop.libc.AttrList.ATTR_CMN_CRTIME;

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

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

0 comments on commit 17868b1

Please sign in to comment.