Skip to content

Conversation

SadPencil
Copy link
Contributor

@SadPencil SadPencil commented Sep 24, 2025

Introduce File.CreateHardLink and FileSystemInfo.CreateAsHardLink APIs to create hard links, with platform-specific implementations. Add comprehensive tests for hard link creation, behavior, and error cases for both File and FileInfo.

Implements and closes #69030

Introduce `File.CreateHardLink` and `FileSystemInfo.CreateAsHardLink` APIs to create hard links, with platform-specific implementations. Add comprehensive tests for hard link creation, behavior, and error cases for both File and FileInfo.

Implements dotnet#69030
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Sep 24, 2025
@SadPencil
Copy link
Contributor Author

@dotnet-policy-service agree

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request adds hard link creation APIs to .NET, implementing File.CreateHardLink and FileSystemInfo.CreateAsHardLink methods with platform-specific implementations for Windows and Unix systems.

Key changes:

  • Introduce public APIs for creating hard links in both File and FileSystemInfo classes
  • Add platform-specific implementations using Windows Kernel32 and Unix system calls
  • Implement comprehensive test coverage for hard link functionality

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/libraries/System.Runtime/ref/System.Runtime.cs Add public API signatures for CreateHardLink methods
src/libraries/System.Private.CoreLib/src/System/IO/File.cs Implement File.CreateHardLink static method
src/libraries/System.Private.CoreLib/src/System/IO/FileSystemInfo.cs Implement CreateAsHardLink instance method
src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs Windows-specific hard link implementation using Kernel32
src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs Unix-specific hard link implementation using link system call
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems Add Windows interop reference for CreateHardLink
src/libraries/Common/tests/System/IO/ReparsePointUtilities.cs Add hard link test utilities and capability detection
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Base/HardLinks/BaseHardLinks.FileSystem.cs Base test class with common hard link test scenarios
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/HardLinks.cs Tests for File.CreateHardLink API
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileInfo/HardLinks.cs Tests for FileInfo.CreateAsHardLink API
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj Add test files to project compilation

@SadPencil SadPencil requested a review from jkotas September 26, 2025 14:31
@jkotas jkotas requested review from a team and removed request for jkotas September 26, 2025 14:43
@SadPencil
Copy link
Contributor Author

Hi. May I ask the current review status of this PR?

Comment on lines 148 to 165
/// <summary>
/// Creates a hard link located in <see cref="FullName"/> that refers to the same file content as <paramref name="pathToTarget"/>.
/// </summary>
/// <param name="pathToTarget">The path of the hard link target.</param>
/// <exception cref="ArgumentNullException"><paramref name="pathToTarget"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="pathToTarget"/> is empty.
/// -or-
/// This instance was not created passing an absolute path.
/// -or-
/// <paramref name="pathToTarget"/> contains invalid path characters.</exception>
/// <exception cref="IOException">A file or directory already exists in the location of <see cref="FullName"/>.
/// -or-
/// An I/O error occurred.</exception>
public void CreateAsHardLink(string pathToTarget)
{
FileSystem.VerifyValidPath(pathToTarget, nameof(pathToTarget));
FileSystem.CreateHardLink(OriginalPath, pathToTarget);
}
Copy link
Member

Choose a reason for hiding this comment

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

This should be in FileInfo, otherwise it will show up in DirectoryInfo too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Addressed in a175919

});

/// <summary>Creates a hard link using command line tools.</summary>
public static bool CreateHardLink(string linkPath, string targetPath)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public static bool CreateHardLink(string linkPath, string targetPath)
private static bool CreateHardLink(string linkPath, string targetPath)

Copy link
Contributor Author

@SadPencil SadPencil Oct 11, 2025

Choose a reason for hiding this comment

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

In this MountHelper class (only used in System.IO.FileSystem.Tests assembly), CreateSymbolicLink and CreateJunction methods are already claimed in public. Do I still need to introduce this CreateHardLink method as a private one? It will introduce a little bit of inconsistency.

public static bool CreateSymbolicLink(string linkPath, string targetPath, bool isDirectory)

/// <paramref name="path"/> or <paramref name="pathToTarget"/> contains a null character.</exception>
/// <exception cref="IOException">A file or directory already exists in the location of <paramref name="path"/>.
/// -or-
/// An I/O error occurred.</exception>
Copy link
Member

Choose a reason for hiding this comment

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

Can you please also document the FileNotFoundException thrown in CreateHardLink_TargetDoesNotExist_Throws.

Copy link
Contributor Author

@SadPencil SadPencil Oct 11, 2025

Choose a reason for hiding this comment

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

FileNotFoundException is a subclass of IOException. It might be weird to mention FileNotFoundException in parallel with IOException?

@jozkee jozkee added the needs-author-action An issue or pull request that requires more info or actions from the author. label Oct 10, 2025
Co-authored-by: David Cantú <[email protected]>
@dotnet-policy-service dotnet-policy-service bot removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Oct 11, 2025
@SadPencil
Copy link
Contributor Author

@jozkee Thanks for your review! I have addressed all your comments. Most comments are directly addressed, while I left this comment and that comment unchanged with defenses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: create hardlinks

3 participants