-
Notifications
You must be signed in to change notification settings - Fork 18k
x/sys/unix: mksyscall_solaris.go doesn't deduplicate so libc functions can only be referenced once #45097
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
Comments
Fixes golang/go#45097 Change-Id: I043f7a90d58767df68388f60c4cc7dc34c5baea1
Change https://golang.org/cl/302310 mentions this issue: |
Thank you @nshalman for taking the time to elaborate on this and writing this issue in such detail!
If this is only about introducing I'd be interested in @ianlancetaylor's opinion on this though. |
Well, that was @danderson's original approach and I should have just gone with it. With my original clunky deduplication code it felt like a less invasive change to the actual {,z}syscall_solaris files, but if these sorts of wrappers are common and the compiler does the right thing, let's just do that after all. This has all been very educational for me, and I thank all the reviewers for their patience with a new contributor. I'll go clean up my branch and update gerrit. |
This is to document a design decision within a series of commits I will be submitting for review, but I want to lay out the rationale behind the approach for posterity. See golang/sys#102 / https://golang.org/cl/302310 for additional context.
Summary: In order to link to libc function calls more than once in syscall_{solaris,illumos} we need to prevent duplication in the resulting cgo import directives, linkname directives, and variable declarations.
Details:
unix/sycall_solaris.go already contains the following line:
//sys ioctl(fd int, req uint, arg uintptr) (err error)
so the ioctl wrapper for the libc ioctl function is currently written to only return an error, however the C function signature is (from the man page) is:
I am working on WireGuard/wireguard-go#39 and have the need to perform some ioctls where the return value is needed.
If I attempt to add the following line to the file:
//sys ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) = libc.ioctl
And then rerun the regeneration command for unix/zsyscall_solaris_amd64.go I end up with, among other bits of the diff, these hunks (using -U1 to be concise):
Note the doubling. The compiler certainly does:
If we accept that wanting to create this second wrapper for ioctl is reasonable, then we need mksyscall_solaris.go to keep track and not create duplication. Originally I wrote a version that does a very naive tracking of the previously seen values so that consecutive lines could be processed correctly, but a reviewer suggested that using maps would make it safe to do this anywhere in the file.
Possible alternatives:
Replace
//sys ioctl(fd int, req uint, arg uintptr) (err error)
with e.g.
This on its face is nice and simple, but it means that all existing codepaths dependent on
ioctl
suddenly have an extra function call through ioctl_ret (or whatever we name it, this is verbatim from an older attempt). This seems like not a nice thing to do to existing code.Another alternative would be to hardcode the generated code for ioctlRet into unix/syscall_illumos.go alongside its consumers. Probably fine, but feels inelegant.
One final note:
None of this solves the problem that moving
//sys ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) = libc.ioctl
into unix/syscall_illumos.go will cause a similar redeclaration problem because the code generating unix/zsyscall_illumos.go has no insight into the content of unix/{,z}syscall_solaris.go
Thank you, dear reader, for joining me down here in this sadness.
The text was updated successfully, but these errors were encountered: