Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@davidkaya
Copy link

Closes #29323

I am not sure about the change in Interop.Stat.cs whether it should be merged to CoreFX or whether I should revert it here and make a PR with that change to CoreCLR.

cc: @JeremyKuhne @danmosemsft

// approximation for the validation done by the Win32 function.
const FileAttributes allValidFlags =
FileAttributes.Archive | FileAttributes.Compressed | FileAttributes.Device |
FileAttributes.Directory | FileAttributes.Encrypted | FileAttributes.Hidden |
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FileAttributes.Hidden attribute was twice in the list.

@davidkaya
Copy link
Author

Builds failed because of SIGABRT, I got those during development when I didn't use private bits of CoreCLR (I don't know whether that is intended). So I guess the change in Interop.Stat.cs will have to be done to CoreCLR. Will wait for comment from the team though before I proceed with the change.

int64_t BirthTimeNsec; // nanosecond part
int64_t Dev; // ID of the device containing the file
int64_t Ino; // inode number of the file
uint32_t UserFlags; // user defined flags
Copy link
Member

@stephentoub stephentoub Jan 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be problematic.

Because of how we've moved code around and shared it between the coreclr and corefx repos, some code in System.Private.CoreLib in the coreclr repo depends on System.Native.so/dylib and this type. When we add this field here, we'll end up corrupting data in System.Private.CoreLib until it can be updated accordingly, but that can't happen until these changes are merged. Catch-22.

I see two immediate ways around that:

  1. Temporarily introduce a new set of APIs/structs that this code uses, e.g. Xx2 instead of Xx. Then once everything has flown to coreclr and it's been updated accordingly and those bits consumed back into corefx, the old ones can be deleted. Then repeat the process to rename everything back to the "good" names.
  2. Try to work within the confines of the existing struct as it's defined, e.g. use the Flags field (which we introduced as part of the PAL and so can do with it what we want) to pass the relevant data rather than defining a new UserFlags field.

How would things look if we did (2)? Is it possible? Could it be done in a relatively clean way, or would it be messy? My preference right now would be (2) if it can be done in at all a reasonable way.

cc: @jkotas, @danmosemsft (longer term we may want to rethink where the shared shims live)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x2 instead of Xx.

We do have x2 APIs for this today because of similar type of change some time ago. We can use this to go back to APIs without the 2 suffix.

I see two immediate ways around that:

3rd option would be to first add the field and let the change propagate everywhere. Once the field is everywhere start actually using it.

This is not that different from how any changes on the CoreCLR/CoreFX boundaries need to be staged, e.g. changes of public APIs that are in use by CoreFX have to be often staged in similar way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3rd option

Ah, right. I like that option, too.

We do have x2 APIs for this today because of similar type of change some time ago. We can use this to go back to APIs without the 2 suffix.

You're right. Let's do that, then.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understood it correctly I should extract this change to separate PR and this PR will be merged once it is propagated everywhere, correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes @davidkaya I believe htat's right. (We didn't notice you were waiting on this q)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, we first add the field, and then add the rest subsequently.

#endif

#if HAVE_STAT_FLAGS
dst->UserFlags = src->st_flags;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it applies to UF_HIDDEN, but in the past we've seen a lot of these defines have different values across platforms, which is one of the reasons we have these shims. As such, if we stick with the UserFlags (see my other previous comment about that), we should define a PAL_ version in pal_io.h that has values which match the managed side, regardless of how the native platform defines it, and then here do the translation, e.g.

dst->UserFlags = (src->st_flags & UF_HIDDEN == UF_HIDDEN) ? PAL_UF_HIDDEN : 0;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to limit the flags only for the UF_HIDDEN one? As I went through the possible flags, I've noticed that you can also set SF_ARCHIVED (0x00010000) in OSX which can be mapped to FileAttributes.Archived and currently it is not. Is it ok to limit it currently only to UF_HIDDEN for now and if e.g SF_ARCHIVED was to be implemented in the future, then the one implementing it should change the implementation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok to limit it currently only to UF_HIDDEN for now and if e.g SF_ARCHIVED was to be implemented in the future, then the one implementing it should change the implementation?

Yup. Let's stick with just hidden for now.

if ((attributes & FileAttributes.Hidden) != 0 && (_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) != (uint)Interop.Sys.UserFlags.UF_HIDDEN)
{
// If Hidden flag is set and cached file status does not have the flag set then set it
Interop.Sys.LChflags(path, (uint)Interop.Sys.UserFlags.UF_HIDDEN);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok that we're ignoring errors? Assuming yes, a comment to that effect (saying why) would be good.

Copy link
Author

@davidkaya davidkaya Jan 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the Windows implementation of SetAttributes and it throws when the operation returned != 0 code

if (!Interop.Kernel32.SetFileAttributes(fullPath, (int)attributes))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)
throw new ArgumentException(SR.Arg_InvalidFileAttrs, nameof(attributes));
throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath);
}

also Unix one throws

Interop.CheckIo(Interop.Sys.ChMod(path, newMode), path, InitiallyDirectory);

I will wrap it in the Interop.CheckIo to match the existing unix implementation which uses Interop.ChMod.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

// If Hidden flag is set and cached file status does not have the flag set then set it
Interop.Sys.LChflags(path, (uint)Interop.Sys.UserFlags.UF_HIDDEN);
}
else if ((attributes & FileAttributes.Hidden) == 0 && (_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == (uint)Interop.Sys.UserFlags.UF_HIDDEN)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this would be better structured as:

if ((attributes & FileAttributes.Hidden) != 0)
{
    if (_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) != (uint)Interop.Sys.UserFlags.UF_HIDDEN)
    {
        ...
    }
}
else
{
    if (_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == (uint)Interop.Sys.UserFlags.UF_HIDDEN)
    {
    }
}

otherwise we're unnecessarily doing the attributes & Hidden test again for the else block if the if condition is true in the first clause but false in the second. Plus it avoids needing to write the same condition check (one inverted) twice.

@stephentoub
Copy link
Member

Thanks for working on this.

internal long BirthTimeNsec;
internal long Dev;
internal long Ino;
internal uint UserFlags;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephentoub Should I use the new UserFlags enum here or leave it as uint?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with uint.

@davidkaya
Copy link
Author

davidkaya commented Jan 17, 2019

@stephentoub made changes based on review, I don't know which changes I should extract to separate PR, could you help me out with that?

Only src/Common/src/CoreLib/Interop/** or everything in src/Common/** && src/Native/**?

@danmoseley
Copy link
Member

@stephentoub there are some questions for you above it looks like.

@karelz
Copy link
Member

karelz commented Mar 4, 2019

@stephentoub ping?
@JeremyKuhne can you please help push it forward? It's almost 2 months old PR with long non-activity time (slipped through the cracks).
cc @wfurt for Mac & FreeBSD expertise

@davidkaya
Copy link
Author

@stephentoub ping?
@JeremyKuhne can you please help push it forward? It's almost 2 months old PR with long non-activity time (slipped through the cracks).
cc @wfurt for Mac & FreeBSD expertise

I will incorporate changes as soon as I get some feedback :)

@wfurt
Copy link
Member

wfurt commented Mar 5, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@danmoseley danmoseley requested a review from JeremyKuhne March 5, 2019 21:31
@wfurt
Copy link
Member

wfurt commented Mar 5, 2019

It seems like the change to pal_io.h should come out first @davidkaya. Since it is ABI breaking change it should come out first before we start writing to that field. If I'm not mistaken, rest can come all together e.g. start using new field when every part of the code base sees updated size.

@stephentoub
Copy link
Member

Sorry, somehow I managed to accidentally mute this thread and wasn't getting any notifications from it.

<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.UTimensat.cs">
<Link>Common\Interop\Unix\Interop.UTimensat.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.LChflags.cs">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit...sorted list?

{
if ((attributes & FileAttributes.Hidden) != 0)
{
if ((_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) != (uint)Interop.Sys.UserFlags.UF_HIDDEN)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this style terser
if ((_fileStatus.UserFlags &(uint)Interop.Sys.UserFlags.UF_HIDDEN) == 0)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it might. Will change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case you might also change if ((_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == (uint)Interop.Sys.UserFlags.UF_HIDDEN) to if ((_fileStatus.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) != 0)

@davidkaya
Copy link
Author

davidkaya commented Mar 7, 2019

Incorporated all comments, extracted UserFlags field change to #35851

Also removed UserFlags fields from the cs file.

Will merge master into the branch once the second PR gets merged.

@danmoseley
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@danmoseley
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@danmoseley
Copy link
Member

Tests are clean save unrelated http test

@danmoseley
Copy link
Member

Any more review feedback?

@danmoseley
Copy link
Member

@JeremyKuhne @stephentoub @jkotas any other feedback

@davidkaya
Copy link
Author

Sorry for making the changes based on review this late. Unexpected business trip.

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this.

@stephentoub stephentoub merged commit b37f018 into dotnet:master Mar 28, 2019
@karelz karelz added this to the 3.0 milestone Apr 1, 2019
steveisok pushed a commit to steveisok/corefx that referenced this pull request Oct 31, 2019
akoeplinger pushed a commit to mono/mono that referenced this pull request Nov 18, 2019
Backport of dotnet/corefx#34560

Added HAVE_LCHFLAGS & HAVE_STAT_FLAGS to configure.
ManickaP pushed a commit to ManickaP/runtime that referenced this pull request Jan 20, 2020
Backport of dotnet/corefx#34560

Added HAVE_LCHFLAGS & HAVE_STAT_FLAGS to configure.



Commit migrated from mono/mono@0269f7b
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
)

* Added UserFlags field

* Added UserFlags


Commit migrated from dotnet/corefx@8c66b0f
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…29323) (dotnet/corefx#34560)

* Added support for UF_HIDDEN flag on macOS and FreeBSD (dotnet/corefx#29323)

* Changes based on review

* Reverted UserFlags field

* Sorted include in csproj

* Changed comparison style

* Reverted UserFlags field

* Fixed parentheses

* Changes based on PR review

* Add missing newline

* Add missing newline


Commit migrated from dotnet/corefx@b37f018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants