Repository navigation
Conversation
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-system-runtime |
aa575d4 to
f7afdef
Compare
fd686e7 to
675263d
Compare
There was a problem hiding this comment.
Pull request overview
Implements a Unix/WASI/browser fallback path for Environment.GetCommandLineArgs() when Environment.s_commandLineArgs isn’t initialized (hosted-library scenario), by adding a System.Native entrypoint that retrieves argv via a new minipal_getcmdline helper and wiring it into CoreLib’s GetCommandLineArgsNative().
Changes:
- Add
minipal_getcmdlineand expose it viaSystemNative_GetCommandLine/SystemNative_FreeCommandLine. - Update CoreLib Unix/Browser implementation to call the new System.Native interop and remove the prior stubbed-out implementation.
- Broaden the fallback test coverage beyond “Windows CoreCLR only” (still excluding Mono).
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/native/minipal/getcmdline.h | New minipal helper that attempts to obtain argv across multiple Unix-like targets (plus WASI/browser). |
| src/native/libs/System.Native/pal_process.h | Declares new SystemNative_GetCommandLine / SystemNative_FreeCommandLine exports. |
| src/native/libs/System.Native/pal_process.c | Implements the new exports by delegating to minipal_getcmdline. |
| src/native/libs/System.Native/pal_process_wasi.c | Implements the new exports for WASI builds. |
| src/native/libs/System.Native/entrypoints.c | Registers the new exports for System.Native DllImport dispatch. |
| src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetCommandLine.cs | Adds LibraryImport declarations for SystemNative_GetCommandLine / SystemNative_FreeCommandLine. |
| src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs | Adds a Unix/Browser GetCommandLineArgsNative() implementation that calls the new interop. |
| src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs | Removes the old stub GetCommandLineArgsNative() implementation. |
| src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs | Removes the old Browser stub for GetCommandLineArgsNative(). |
| src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems | Includes the new interop source file in CoreLib build items. |
| src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Environment.GetCommandLineArgs.cs | Updates conditions so fallback tests run on non-Mono (and parser tests run on Windows non-Mono). |
Suppressed comments (1)
src/native/minipal/getcmdline.h:83
- The /proc/self/cmdline reader doesn't check whether the initial malloc succeeded, and it doesn't handle read() returning -1 (including EINTR). As written, a read error after partial data can silently return a truncated/invalid argv buffer, and a NULL buf would be dereferenced.
size_t bufSize = 1024;
char* buf = (char*)malloc(bufSize);
size_t totalBytes = 0;
ssize_t bytesRead;
9edbb0c to
a95fc33
Compare
|
I am not sure about this feature. It is a lot of OS-specific code that tends to be difficult to port, and the benefit of feature is debatable - code outside the main executable has no business reverse engineering the app command line. @elinor-fung @dotnet/appmodel Thoughts? |
Only the calling assembly is outside the executing assembly; from the OS viewpoint, it is still the same executing .NET app. The only true "outside code" scenario would be #21941, which does raise valid security concerns. Even so, it falls under the "when you need it, you need it" rule (dotnet/msbuild#15374), especially since desktop operating systems explicitly allow it. |
My comment was about code hygiene. I do not think it is a good practice for libraries to fish for command line arguments of the main program. Apparently, Rust made equivalent of this API work in dynamic libraries. They use a creative solution that works for glibc (but it won't work for musl) |
| return PackCommandLine(1, browserArgs, argc); | ||
| #elif defined(__linux__) || defined(__sun) | ||
| int fd; | ||
| while ((fd = open("/proc/self/cmdline", O_RDONLY | O_CLOEXEC)) < 0 && errno == EINTR); |
There was a problem hiding this comment.
I'm pretty skeptical that we should return different behavior for this API depending on whether the user registered the /proc file system.
There was a problem hiding this comment.
Does .NET officially support a system without /proc? Do we have the CI coverage? I have done ad-hoc testing and fixes in the past #62513, so I know how that testing looks like in practice; system without procfs also means system without ptrace, which PAL depends on and all those else branches are never holistically tested, and just like qemu it's "if it works, it works; use at your own risk" plan.
| } | ||
| #endif | ||
|
|
||
| #if !defined(TARGET_BROWSER) && (defined(__linux__) || defined(__sun) || defined(__FreeBSD__) || defined(__APPLE__)) |
There was a problem hiding this comment.
| #if !defined(TARGET_BROWSER) && (defined(__linux__) || defined(__sun) || defined(__FreeBSD__) || defined(__APPLE__)) | |
| #if defined(__linux__) || defined(__sun) || defined(__FreeBSD__) || defined(__APPLE__) |
#128545