-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
std.c: define freopen() and the stdio streams #24446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
For windows support, this part of wine's msvcrt |
I have a patch in the works for NetBSD, OpenBSD, Solaris, and Illumos. It's a bit ugly, but I think it gets the job done. Completely untested and just based on reading headers, as I don't have VMs for these at the ready: https://zigbin.io/576105 . |
Seems like it'd be more robust to just declare the fields and let the compiler figure out the layout? |
Agreed. I was just cribbing that style from e.g. pthread_mutex_t defs and keeping things succinct. Would you rather I push this all in the same PR, or save the complicated ones for a separate PR and leave this one with just the basic easy ones? |
It's fine to do it all in this PR. |
Updated with two new commits: the NetBSD/OpenBSD/Solaris/Illumos one (with expanded struct defs), and a draft Windows one (I'm really not a Windows person, so I have no idea if something else is needed there in |
This allows for daemonization and output-redirection sorts of code in libc-linked Zig projects on *nix-y platforms to affect the stdio stream usage of other libc-based library code the project may be linking, e.g.: // Set stderr to go nowhere without errors: _ = std.c.freopen("/dev/null", "r+", std.c.stderr()); // Append stdout to a file: _ = std.c.freopen("/tmp/output.txt", "a", std.c.stdout()); The stdio streams are returned from function calls because they're commonly #defines in the libc headers pointing at variously-named externs, and one doesn't generally assign to them directly anyways (freopen() is the portable way to assign something new to a stdio stream). NetBSD, OpenBSD, and Solaris stdio streams are not supported in this patch and will cause a compileError if you try to use the them, for now. Supporting them would require a more complex and fragile solution using a definition of "FILE" that is not just an opaque type (because their C libraries publish an extern array of FILE objects and then #define the stdio stream names as pointers to the array elements).
Updated for WASI as well. I added a hacky temporary test at the bottom of
And then with a test-std run with
As well as WASI and Windows:
|
Managed to manually test this with a cross-compiled binary on FreeBSD in qemu, to validate that this approach works at all for at least one of these This is my test source:
Cross-compiled from Linux -> FreeBSD via:
|
Tested NetBSD 10.1 manually now as well (same
This gets us at least one working example of the extern-array-of-FILE pattern (and that at least the NetBSD struct sizing comes out correctly on x86_64, or else we'd be off quite a bit by the time we get to |
I don't think we need these functions in the zig standard library. In fact, I think all functions dealing with |
That's a reasonable stance too, I think! Basically everyone porting C code that was using |
Closing this for now, given the above! Thanks! |
@blblack i started https://github.com/nektro/zig-libc if you'd like to move there |
This allows for daemonization and output-redirection sorts of code in libc-linked Zig projects on *nix-y platforms to affect the stdio stream usage of other libc-based library code the project may be linking, e.g.:
The stdio streams are returned from function calls because they're commonly #defines in the libc headers pointing at variously-named externs, and one doesn't generally assign to them directly anyways (freopen() is the portable way to assign something new to a stdio stream).
NetBSD, OpenBSD, and Solaris stdio streams are not supported in this patch and will cause a compileError if you try to use the them, for now. Supporting them would require a more complex and fragile solution using a definition of "FILE" that is not just an opaque type (because their C libraries publish an extern array of FILE objects and then #define the stdio stream names as pointers to the array elements).