Skip to content

Use SetUnixFileMode for chmod#53481

Open
kasperk81 wants to merge 1 commit intodotnet:mainfrom
kasperk81:unixmode
Open

Use SetUnixFileMode for chmod#53481
kasperk81 wants to merge 1 commit intodotnet:mainfrom
kasperk81:unixmode

Conversation

@kasperk81
Copy link
Contributor

@kasperk81 kasperk81 commented Mar 16, 2026

To stay compatible with the behavior described in the .NET specs:

these specs effectively define the permission string as whatever chmod accepts which makes the format somewhat vague and underspecified.

To accommodate this, I added chmod-style permission parsing based on POSIX spec e.g. cases handled in: https://github.com/landley/toybox/blob/c9c0d42aae50b80cda27bd6131f315e57513be47/lib/lib.c#L950. This is used as a fallback when parsing user-provided System.IO.UnixFileMode enum names fails: https://learn.microsoft.com/en-us/dotnet/api/system.io.unixfilemode#fields

As a result, the following formats are supported.

Existing data/UnixFilePermissions.xml (unchanged)
<FileList>
  <File Path="data/Darwin/mono" Permission="755" />
  <File Path="data/Darwin/dotnet" Permission="+x" />
</FileList>
New (enum-based permissions)
<FileList>
  <File Path="data/Darwin/mono" Permission="UserWrite|OtherRead" />
</FileList>

This preserves backward compatibility while also allowing explicit permissions using the UnixFileMode enum.

@kasperk81 kasperk81 requested a review from a team as a code owner March 16, 2026 15:20
Copy link
Contributor

@KalleOlaviNiemitalo KalleOlaviNiemitalo left a comment

Choose a reason for hiding this comment

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

Does this support o+r-w? In chmod, that is the same as o+r,o-w.

@kasperk81
Copy link
Contributor Author

kasperk81 commented Mar 16, 2026

Does this support o+r-w? In chmod, that is the same as o+r,o-w.

yes it does same as POSIX/toybox implementation

@KalleOlaviNiemitalo
Copy link
Contributor

Really? It seems to me there aren't enough nested loops.

@KalleOlaviNiemitalo
Copy link
Contributor

KalleOlaviNiemitalo commented Mar 16, 2026

It seems to execute o+r-w as o+r,-w rather than o+r,o-w.

  1. Initializes int i = 0 and enters the while (i < argument.Length) loop on line 84.
  2. Parses u/g/o/a, finds o.
  3. Sets op = '+'.
  4. Enters the “Parse permissions” loop while (i < argument.Length && argument[i] != ',' && "+-=".IndexOf(argument[i]) == -1).
  5. Recognises 'r' and sets permMask.
  6. Reaches '-' and exits the “Parse permissions” loop.
  7. Applies the + operation and the 'r' permission to o.
  8. Loops back to line 84 while (i < argument.Length).
  9. Tries to parse u/g/o/a but doesn’t find any, thus defaults to u = g = o = true!
  10. Sets op = '-'.
  11. Enters the “Parse permissions” loop.
  12. Recognises 'w' and sets permMask.
  13. Reaches argument.Length and exits the “Parse permissions” loop.
  14. Applies the - operation and the w permission to ugo rather than only to o!

@kasperk81
Copy link
Contributor Author

@KalleOlaviNiemitalo thanks! after the fix, tested with:

Console.WriteLine("o+r-w -> " + ChmodHelper.Parse("o+r-w", UnixFileMode.UserWrite | UnixFileMode.GroupWrite));
Console.WriteLine("u+x,g-w -> " + ChmodHelper.Parse("u+x,g-w", UnixFileMode.UserWrite | UnixFileMode.GroupWrite));
Console.WriteLine("a=r -> " + ChmodHelper.Parse("a=r", 0));
Console.WriteLine("g=u -> " + ChmodHelper.Parse("g=u", UnixFileMode.UserRead | UnixFileMode.UserWrite));
Console.WriteLine("u+s,g+s,o+t -> " + ChmodHelper.Parse("u+s,g+s,o+t", 0));
Console.WriteLine("u+rwx,g-r,o-r -> " + ChmodHelper.Parse("u+rwx,g-r,o-r", UnixFileMode.UserWrite | UnixFileMode.GroupWrite | UnixFileMode.OtherRead));
Console.WriteLine("o+x,u-g -> " + ChmodHelper.Parse("o+x,u-g", UnixFileMode.UserRead | UnixFileMode.GroupRead));
o+r-w -> OtherRead, GroupWrite, UserWrite
u+x,g-w -> UserExecute, UserWrite
a=r -> OtherRead, GroupRead, UserRead
g=u -> GroupWrite, GroupRead, UserWrite, UserRead
u+s,g+s,o+t -> StickyBit, SetGroup, SetUser
u+rwx,g-r,o-r -> GroupWrite, UserExecute, UserWrite, UserRead
o+x,u-g -> OtherExecute, GroupRead

@kasperk81 kasperk81 force-pushed the unixmode branch 3 times, most recently from c044646 to f5b22ec Compare March 16, 2026 22:04
@kasperk81
Copy link
Contributor Author

@tmds, @akoeplinger ptal

@akoeplinger
Copy link
Member

@kasperk81 I'm not sure adding all this parsing logic is a good idea. For the UnixFilePermissions.xml we can just support the numerical formats and use SetUnixFileMode, but for the templating case I'd just leave it as is

@marcpopMSFT marcpopMSFT requested a review from nagilson March 17, 2026 20:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants