Skip to content

Conversation

huoyaoyuan
Copy link
Member

First step of moving file IO to minipal.

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label May 29, 2025
// The normalization examples are :
// C:\foo\<long>\bar => \\?\C:\foo\<long>\bar
// \\server\<long>\bar => \\?\UNC\server\<long>\bar
static WCHAR* NormalizePath(const WCHAR* path)
Copy link
Member Author

@huoyaoyuan huoyaoyuan May 29, 2025

Choose a reason for hiding this comment

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

This is yet-another duplicate of the path normalization algorithm:

  • corehost\hostmisc\longfile.native.cpp, implemented with std::wstring
  • utilcode\longfilepathwrappers.cpp, implemented with SString
  • PathInternal.EnsureExtendedPrefixIfNeeded, implemented with managed string

When we eventually move all Win32 API to minipal, the utilcode version should be replaced by minipal version. Implementing this in pure C is really error-prone and unpleasable.

if (ret)
{
attributes->size = stat_data.st_size;
attributes->lastWriteTime = UnixTimeToWin32FileTime(stat_data.st_mtim);
Copy link
Member Author

Choose a reason for hiding this comment

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

minipal/time is already requiring timespec, let's see if all platforms are having timespec available in stat.

Comment on lines 191 to 192
attributes->size = stat_data.st_size;
attributes->lastWriteTime = UnixTimeToWin32FileTime(stat_data.st_mtim);
Copy link
Member Author

Choose a reason for hiding this comment

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

This somehow overlaps with libs/pal_io.c, the differences are:

  • The UTF16/UTF8 transformation is done at managed side for libs, but minipal needs cross-platform representation which prefers UTF16
  • This only includes the portion needed for native runtime, in libs there are much more information exposed.

Thus I think it's better to keep them separated.

uint64_t lastWriteTime; // Windows FILETIME precision
} minipal_file_attr_t;

bool minipal_file_get_attributes_utf16(const char16_t* path, minipal_file_attr_t* attributes);
Copy link
Member Author

Choose a reason for hiding this comment

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

pal/mstypes.h defines WCHAR as char16_t, which is incompatible with unsigned short from minipal/types.h. Since pal uses char16_t unconditionally, I assume it's broad available.

Copy link
Member

Choose a reason for hiding this comment

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

which is incompatible with unsigned short

What was the error when you used CHAR16_T? You may need to sprinkle a few (CHAR16_T*)var at call sites like we did for utf conversion API call sites.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just char16_t* and unsigned short* is incompatible. Yes there are casts like

return minipal_u16_strlen((CHAR16_T*)str);

Copy link
Member

Choose a reason for hiding this comment

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

On Windows, it is defined as wchar_t, while on Unix it is defined as unsigned short because char16_t is not available everywhere (as seen in current CI errors). I checked various platform headers when defining CHAR16_T and unsigned short was close enough (they use some flexible type but this assumption just works across our supported platforms).


// The cache is locked for read, so the list will not change.

// Figure out the size and timestamp of this file
Copy link
Member

Choose a reason for hiding this comment

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

What is this cache used for? Do we still need it? Would it be better to delete it?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's called by IMetaDataDispenser::OpenScope and reusing the same object for same file. I don't get a good insight for its impact and performance of creating new RegMeta instance.

Copy link
Member

Choose a reason for hiding this comment

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

I am deleting it in #116126. Once that change goes through, we should not need GetFileAttributes in the minipal.

@jkotas
Copy link
Member

jkotas commented May 29, 2025

I/O for core runtime should fall into two categories:

  • Generic I/O, like open a file for logging. We should use standard C runtime for that.
  • Specialized I/O, like mapping executables into memory. There should be a very few of these functions and they are likely to fit better into CoreCLR-specific PAL than a generic minipal.

Things that do not fall into any of these two categories - like the metadata cache you have changed - look suspect. They should be scrutinized heavily.

@huoyaoyuan
Copy link
Member Author

huoyaoyuan commented May 29, 2025

I/O for core runtime should fall into two categories:

  • Generic I/O, like open a file for logging. We should use standard C runtime for that.
  • Specialized I/O, like mapping executables into memory. There should be a very few of these functions and they are likely to fit better into CoreCLR-specific PAL than a generic minipal.

I did some attempt for that. For CRT I/O, the biggest problem is the string encoding of fopen. On Windows there is _wfopen available, but it would need some wrapping to handle the encoding difference. Should these functions taking file names go to shared minipal? Should they handle long path?
Using fstream is much more easier, but it's limited to non in-process components.
mmap is actually not that rare and even used by ilasm for input. Putting them under coreclr minipal looks better.
For out-of-process develop component like superpmi, it should be easier to switch to fstream instead.

@huoyaoyuan huoyaoyuan marked this pull request as draft May 29, 2025 15:08
@jkotas
Copy link
Member

jkotas commented May 29, 2025

fopen

JIT has fopen_utf8 wrapper to solve similar problem. We can have u16 variant of it.


//To delete file need to make it normal
if(!SetFileAttributesA(szReadOnlyFile,FILE_ATTRIBUTE_NORMAL))
if((last_error = chmod(szReadOnlyFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))
Copy link
Member

Choose a reason for hiding this comment

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

Should this also have the != 0 like above?

@huoyaoyuan huoyaoyuan changed the title CleanUp GetFileAttribute(Ex) and move to minipal CleanUp GetFileAttribute(Ex) in PAL May 31, 2025
@huoyaoyuan huoyaoyuan marked this pull request as ready for review May 31, 2025 01:40
#define GetFileAttributes GetFileAttributesA
#endif

typedef enum _GET_FILEEX_INFO_LEVELS {
Copy link
Member

Choose a reason for hiding this comment

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

Delete these as well enums/types as well

@jkotas
Copy link
Member

jkotas commented May 31, 2025

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@huoyaoyuan
Copy link
Member Author

error: use of undeclared identifier '_MAX_PATH'

It's a missed case of #115986. Is the automated trigger for PAL pipeline enabled now?

@am11
Copy link
Member

am11 commented May 31, 2025

Missing #116096 (comment).

@jkotas
Copy link
Member

jkotas commented May 31, 2025

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member

jkotas commented May 31, 2025

FAILED: file_io/errorpathnotfound/test2/paltest_errorpathnotfound_test2. Exit code: 1

Thread waited for 2138803459 ms! (Acceptable delta: 300)
FAILED: threading/WaitForSingleObject/WFSOExMutexTest/paltest_waitforsingleobject_wfsoexmutextest. Exit code: 1

@huoyaoyuan
Copy link
Member Author

FAILED: file_io/errorpathnotfound/test2/paltest_errorpathnotfound_test2. Exit code: 1

This is removed but missed from test list.

FAILED: threading/WaitForSingleObject/WFSOExMutexTest/paltest_waitforsingleobject_wfsoexmutextest. Exit code: 1

This doesn't look related.

@jkotas
Copy link
Member

jkotas commented Jun 1, 2025

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Thanks

@jkotas jkotas merged commit a87245f into dotnet:main Jun 1, 2025
137 of 148 checks passed
@huoyaoyuan huoyaoyuan deleted the minipal/file branch June 2, 2025 02:15
@github-actions github-actions bot locked and limited conversation to collaborators Jul 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-PAL-coreclr 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.

4 participants