Skip to content
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

cmd/cgo: please provide a way to set errno from a callback #23890

Closed
jech opened this issue Feb 17, 2018 · 5 comments
Closed

cmd/cgo: please provide a way to set errno from a callback #23890

jech opened this issue Feb 17, 2018 · 5 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@jech
Copy link

jech commented Feb 17, 2018

I'm interfacing with a C library that expects callbacks to return -1 with errno set upon error. As far as I can tell, the only way to set errno in a go function is to call back into C:

void
set_errno(int e)
{
    errno = e;
}
//export callback
func callback(...)  C.int {
    ...
    C.set_errno(C.int(syscall.EAGAIN))
    return -1
    ...
}

This is in contrast with retrieving errno in Go using multiple return values, which I find elegant and Go-like. Please provide a similarly tasteful way to return from Go to C while setting errno.

@bradfitz
Copy link
Contributor

/cc @ianlancetaylor

@ianlancetaylor ianlancetaylor changed the title Cgo: please provide a way to set errno from a callback cmd/cgo: please provide a way to set errno from a callback Feb 17, 2018
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Feb 17, 2018
@ianlancetaylor ianlancetaylor added the NeedsFix The path to resolution is known, but the work has not been done. label Feb 17, 2018
@ianlancetaylor
Copy link
Contributor

This is doable in principle--we could apply special handling to an //extern function that returns two values where the second one has type int, but it would be so rarely used that I don't think it's worth the additional complexity.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
@craig65535
Copy link

I think go also needs the ability to set errno when calling into certain functions like getgrent and getpwent. These functions return NULL and set errno on error, but they may also return NULL and not set errno on success (when all the entries have been returned). So, users must explicitly set errno to 0 before calling these functions.

From the macOS man page for getpwent:

RETURN VALUES
The functions getpwent(), getpwnam(), getpwuid(), and getpwuuid() return a
valid pointer to a passwd structure on success or NULL if the entry is not
found or if an error occurs. If an error does occur, errno will be set.
Note that programs must explicitly set errno to zero before calling any of
these functions if they need to distinguish between a non-existent entry
and an error.

It seems the only way to do this is to write a C function to set errno.

@ianlancetaylor
Copy link
Contributor

As I said earlier, this case is so rarely used that I don't think it's worth the extra complexity in cgo.

For people who need this I recommend writing, in the cgo comment.

/*
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>

static struct passwd *goGetpwent() {
    errno = 0;
    return getpwent();
}
*/
import "C"

Then change your code to call goGetpwent rather than getpwent.

@jech
Copy link
Author

jech commented Sep 9, 2022

this case is so rarely used that I don't think it's worth the extra complexity in cgo.

I'm the original reporter, and with four years more experience, I fully agree with Ian. Sorry for the noise.

@jech jech closed this as completed Sep 9, 2022
@golang golang locked and limited conversation to collaborators Sep 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants