Skip to content

Remove alternate file stream code from non-Windows - #4567

Merged
Dongbo Wang (daxian-dbw) merged 5 commits into
PowerShell:masterfrom
SteveL-MSFT:copy-item-streams
Aug 28, 2017
Merged

Remove alternate file stream code from non-Windows#4567
Dongbo Wang (daxian-dbw) merged 5 commits into
PowerShell:masterfrom
SteveL-MSFT:copy-item-streams

Conversation

@SteveL-MSFT

Copy link
Copy Markdown
Member

AlternateStreams support relies on pinvoke to win32 apis which don't work

on non-Windows and produces errors about not loading a dll in the case of copy-item

Fix #4542

@iSazonov Ilya (iSazonov) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Leave a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unblock-File is excluded from Unix at all so we don't need to exclude the code here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That file is still being compiled on Unix

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should exclude them in csproj.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm fine with that but then we have effectively conditional compilation in both the source and the csproj files

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we rename this to UnblockFile.Windows.cs?


In reply to: 133130873 [](ancestors = 133130873)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please add a check that ${testPath}:Stream is a file name.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Doesn't Get-Content implicitly cover that?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I guess if the Content cmdlets were doing something funny it could mask an issue, I'll add a check

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Extra line.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will remove

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unnecessary change of line.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The change of grouping of the variables makes it a bit more readable to me

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Closed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this block be surrounded by #if !UNIX?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Some of this code is unnecessary on UNIX so I'll wrap it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be Test-Path instead of Test_path

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, odd that this test passed

@SteveL-MSFT
Steve Lee (SteveL-MSFT) force-pushed the copy-item-streams branch 2 times, most recently from 0191663 to 8c69d06 Compare August 15, 2017 07:41

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we add #if !UNIX to the start of the file like: https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/utils/tracing/EtwActivity.cs#L1

That seems more discoverable to me when doing code reviews or debugging.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's what I had originally. Did a search and I don't see other cases of conditional compilation, so I think it's more consistent to use a whole file #ifdef. Ilya (@iSazonov) ok?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it's technically better to exclude files in csproj files. But currently we don't use a lot of opportunities of MSBuild and also we are cleaning up FullCLR files and respectively remove "Compile Remove" from csproj files. So it is Ok to use #ifdef .

/cc Dongbo Wang (@daxian-dbw) Could you comment too?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't really have a preference although csproj approach seems more discoverable. However in this case, I don't think Unblockfile.cs should be completely excluded from Unix build as it will increase the number of #if unix/endif blocks in places where the code from this file is used, which will impact readability.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This #if/#endif block is cumbersome to read. Suggest instead:
if (result != null)
{
#if UNIX
WriteItemObject(...)
#else
original code
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The WriteItemObject code applies to both UNIX and !UNIX. If I move that bit of code up, I'd need more #ifdefs making it less readable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, if you don't mind duplicating the WriteItemObject line, it can be a pure #if #else block. Your call.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think the other case I was fine with a bit of duplication, but prefer to leave this one as-is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As above, the code is easier to read if you use a #if UNIX and contain the UNIX lines completely. Its a simple if/else with a single statement for UNIX but looks unwieldy with the current #if/#else placement.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can move some code around so the UNIX code is in one place and the !UNIX code is also together.

@dantraMSFT

Copy link
Copy Markdown
Contributor
                if (isAlternateDataStream)

Should this also be conditioned on !UNIX?


Refers to: src/System.Management.Automation/namespaces/FileSystemProvider.cs:4270 in 7209973. [](commit_id = 720997351e1de1cf26593cfe0e95699d8b3b9eb3, deletion_comment = False)

@dantraMSFT

Copy link
Copy Markdown
Contributor
        return Platform.NonWindowsIsSameFileSystemItem(pathOne, pathTwo);

Shouldn't there be a Platform.IsSameFileSystemItem?


Refers to: src/System.Management.Automation/namespaces/FileSystemProvider.cs:8274 in 7209973. [](commit_id = 720997351e1de1cf26593cfe0e95699d8b3b9eb3, deletion_comment = False)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

On UNIX, _stream will be null causing a ArgumentNullException from new StreamReader at line 874. At best, it will be misleading. Consider throwing NotSupportException on UNIX in the associated constructors

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

makes sense, will change

@SteveL-MSFT

Copy link
Copy Markdown
Member Author

Dan Travison (@dantraMSFT) I addressed your feedback. Regarding Platform.IsSameFileSystem we should probably have a single API that is platform agnostic, but that's out of scope of this PR.

@SteveL-MSFT
Steve Lee (SteveL-MSFT) force-pushed the copy-item-streams branch 4 times, most recently from 22cc78b to f0260d7 Compare August 17, 2017 12:41
@SteveL-MSFT

Copy link
Copy Markdown
Member Author

I believe all feedback has been addressed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be in the #if !UNIX block?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yes, will fix

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

will fix

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This variable won't be used on Unix and should be moved to the #if !UNIX block below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

will fix

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The alternate streams can be specified using -Stream or an inline stream syntax "file::stream", the check of the inline stream syntax is done in 7 places in FileSystemProvider.cs but some of them are not within #if !UNIX block.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And when running Get-Content -Path file::stream on Linux, it probably should throw an error message about "alternate stream is not supported" instead of working unexpectedly or fail with other errors.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

On Unix, a colon is completely allowed in a filename, so we want that to continue working as just a filename. Tests were added to make sure this works.

I'll fix other cases of using the file:stream syntax.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I thought about it more and now have this question: which the following experience is better -- copy Get-Content -Path <file> -Stream <stream> to Linux powershell and see the error "A parameter cannot be found", or "Alternate stream is not supported on this platform"? I think the latter message is better. To achieve this, maybe we can make the setter of the Stream property throw PlatformNotSupportedException on non-windows.

As for #if UNIX/endif blocks, IMHO, we don't necessarily need to have all codes that only apply to a specific platform guarded by the compile definition. I think it's OK to keep such codes around even for other platforms, and the guideline should be readability and maintainability. I still feel it's better to avoid most of the #if UNIX blocks by controlling the entry points:

  1. Make sure -Stream not available on Unix platforms
  2. Throw error when the inline stream syntax is used for -Path on Unix platforms
  3. Skip the alternate stream discovery codes during remote copy (both PerformCopyFileFromRemoteSession and PerformCopyFileToRemoteSession) on Unix platforms.

After controlling those entry points (and put some comments for sure), it's safe to know that the alternate stream related code paths will not be hit on Unix platforms.

@TravisEz13 Travis Plunk (TravisEz13) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please work on correctly resolving merge/rebase issue.

Comment thread assets/Product.wxs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

something isn't correct in your PR. Already committed changes are in the diff.

@TravisEz13

Copy link
Copy Markdown
Member

It looks like the email on your latest commit is not associated with your github account.

@SteveL-MSFT

Copy link
Copy Markdown
Member Author

Travis Plunk (@TravisEz13) fixed

@SteveL-MSFT

Copy link
Copy Markdown
Member Author

Travis Plunk (@TravisEz13) Dongbo Wang (@daxian-dbw) feedback addressed

@daxian-dbw
Dongbo Wang (daxian-dbw) dismissed Travis Plunk (TravisEz13)’s stale review August 28, 2017 20:05

Comment is addressed by new commits.

@daxian-dbw
Dongbo Wang (daxian-dbw) merged commit deb8c44 into PowerShell:master Aug 28, 2017
@SteveL-MSFT
Steve Lee (SteveL-MSFT) deleted the copy-item-streams branch August 29, 2017 00:01
Thatgfsj (Thatgfsj) pushed a commit to Thatgfsj/PowerShell that referenced this pull request Aug 6, 2026
* AlternateStreams support relies on pinvoke to win32 APIs which don't work on non-Windows and produces errors about not loading a DLL in the case of copy-item
* Address PR feedback, remove -Stream parameter for Unix added new -stream tests
* if/def out alternate stream syntax checks not applicable to Unix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants