Stop passing Go pointers to C

This commit is contained in:
Michael Steinert
2015-12-03 14:59:51 -06:00
parent 6534f23b39
commit 8ec1202046
5 changed files with 77 additions and 30 deletions

View File

@@ -4,7 +4,7 @@ package pam
//#include <stdlib.h>
//#cgo CFLAGS: -Wall -std=c99
//#cgo LDFLAGS: -lpam
//struct pam_conv *make_pam_conv(void *);
//void init_pam_conv(struct pam_conv *conv, long c);
import "C"
import (
@@ -50,31 +50,31 @@ func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error) {
return f(s, msg)
}
// Internal conversation structure
type conversation struct {
handler ConversationHandler
conv *C.struct_pam_conv
}
// Constructs a new conversation object with a given handler and a newly
// allocated pam_conv struct that uses this object as its appdata_ptr.
func newConversation(handler ConversationHandler) (*conversation, C.int) {
c := &conversation{}
c.handler = handler
c.conv = C.make_pam_conv(unsafe.Pointer(c))
if c.conv == nil {
return nil, C.PAM_BUF_ERR
}
return c, C.PAM_SUCCESS
func newConversation(handler ConversationHandler) (*C.struct_pam_conv, C.int) {
c := cbAdd(handler)
conv := &C.struct_pam_conv{}
C.init_pam_conv(conv, C.long(c))
return conv, C.PAM_SUCCESS
}
// Go-side function for processing a single conversational message. Ultimately
// this calls the associated ConversationHandler's ResponsePAM callback with data
// coming in from a C-side call.
//export cbPAMConv
func cbPAMConv(s C.int, msg *C.char, appdata unsafe.Pointer) (*C.char, C.int) {
c := (*conversation)(appdata)
r, err := c.handler.RespondPAM(Style(s), C.GoString(msg))
func cbPAMConv(s C.int, msg *C.char, c int) (*C.char, C.int) {
var r string
var err error
v := cbGet(c)
switch cb := v.(type) {
case ConversationFunc:
r, err = cb(Style(s), C.GoString(msg))
case ConversationHandler:
r, err = cb.RespondPAM(Style(s), C.GoString(msg))
default:
return nil, C.PAM_CONV_ERR
}
if err != nil {
return nil, C.PAM_CONV_ERR
}
@@ -84,14 +84,13 @@ func cbPAMConv(s C.int, msg *C.char, appdata unsafe.Pointer) (*C.char, C.int) {
// Transaction is the application's handle for a PAM transaction.
type Transaction struct {
handle *C.pam_handle_t
conv *conversation
conv *C.struct_pam_conv
status C.int
}
// Finalize a PAM transaction.
func transactionFinalizer(t *Transaction) {
C.pam_end(t.handle, t.status)
C.free(unsafe.Pointer(t.conv.conv))
}
// Start initiates a new PAM transaction. Service is treated identically to
@@ -112,9 +111,8 @@ func Start(service, user string, handler ConversationHandler) (*Transaction, err
u = C.CString(user)
defer C.free(unsafe.Pointer(u))
}
t.status = C.pam_start(s, u, t.conv.conv, &t.handle)
t.status = C.pam_start(s, u, t.conv, &t.handle)
if t.status != C.PAM_SUCCESS {
C.free(unsafe.Pointer(t.conv.conv))
return nil, t
}
runtime.SetFinalizer(t, transactionFinalizer)