Skip to content

Commit

Permalink
Merge pull request #318 from saschagrunert/dlopen
Browse files Browse the repository at this point in the history
sdjournal: use internal dlopen package
  • Loading branch information
Luca Bruno authored Nov 4, 2019
2 parents fd7a80b + 3344f03 commit d3cd4ed
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 8 deletions.
4 changes: 0 additions & 4 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[[constraint]]
name = "github.com/coreos/pkg"
version = "4.0.0"

[[constraint]]
name = "github.com/godbus/dbus"
version = "5.0"
Expand Down
82 changes: 82 additions & 0 deletions internal/dlopen/dlopen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package dlopen provides some convenience functions to dlopen a library and
// get its symbols.
package dlopen

// #cgo LDFLAGS: -ldl
// #include <stdlib.h>
// #include <dlfcn.h>
import "C"
import (
"errors"
"fmt"
"unsafe"
)

var ErrSoNotFound = errors.New("unable to open a handle to the library")

// LibHandle represents an open handle to a library (.so)
type LibHandle struct {
Handle unsafe.Pointer
Libname string
}

// GetHandle tries to get a handle to a library (.so), attempting to access it
// by the names specified in libs and returning the first that is successfully
// opened. Callers are responsible for closing the handler. If no library can
// be successfully opened, an error is returned.
func GetHandle(libs []string) (*LibHandle, error) {
for _, name := range libs {
libname := C.CString(name)
defer C.free(unsafe.Pointer(libname))
handle := C.dlopen(libname, C.RTLD_LAZY)
if handle != nil {
h := &LibHandle{
Handle: handle,
Libname: name,
}
return h, nil
}
}
return nil, ErrSoNotFound
}

// GetSymbolPointer takes a symbol name and returns a pointer to the symbol.
func (l *LibHandle) GetSymbolPointer(symbol string) (unsafe.Pointer, error) {
sym := C.CString(symbol)
defer C.free(unsafe.Pointer(sym))

C.dlerror()
p := C.dlsym(l.Handle, sym)
e := C.dlerror()
if e != nil {
return nil, fmt.Errorf("error resolving symbol %q: %v", symbol, errors.New(C.GoString(e)))
}

return p, nil
}

// Close closes a LibHandle.
func (l *LibHandle) Close() error {
C.dlerror()
C.dlclose(l.Handle)
e := C.dlerror()
if e != nil {
return fmt.Errorf("error closing %v: %v", l.Libname, errors.New(C.GoString(e)))
}

return nil
}
63 changes: 63 additions & 0 deletions internal/dlopen/dlopen_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dlopen

import (
"fmt"
"testing"
)

func checkFailure(shouldSucceed bool, err error) (rErr error) {
switch {
case err != nil && shouldSucceed:
rErr = fmt.Errorf("expected test to succeed, failed unexpectedly: %v", err)
case err == nil && !shouldSucceed:
rErr = fmt.Errorf("expected test to fail, succeeded unexpectedly")
}

return
}

func TestDlopen(t *testing.T) {
tests := []struct {
libs []string
shouldSucceed bool
}{
{
libs: []string{
"libc.so.6",
"libc.so",
},
shouldSucceed: true,
},
{
libs: []string{
"libstrange.so",
},
shouldSucceed: false,
},
}

for i, tt := range tests {
expLen := 4
len, err := strlen(tt.libs, "test")
if checkFailure(tt.shouldSucceed, err) != nil {
t.Errorf("case %d: %v", i, err)
}

if tt.shouldSucceed && len != expLen {
t.Errorf("case %d: expected length %d, got %d", i, expLen, len)
}
}
}
1 change: 0 additions & 1 deletion scripts/jenkins/periodic-go-systemd-builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ if [ ! -h gopath/src/github.com/coreos/go-systemd ]; then
fi
export GOPATH=${PWD}/gopath
go get -u github.com/godbus/dbus
go get github.com/coreos/pkg/dlopen

sudo -E ./test
2 changes: 1 addition & 1 deletion sdjournal/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package sdjournal

import (
"github.com/coreos/pkg/dlopen"
"github.com/coreos/go-systemd/internal/dlopen"
"sync"
"unsafe"
)
Expand Down
1 change: 0 additions & 1 deletion test
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ if [ -z "$GOPATH" ]; then
fi
export GOPATH=${PWD}/gopath
go get -u github.com/godbus/dbus
go get -u github.com/coreos/pkg/dlopen
fi

TESTABLE="activation daemon journal login1 unit"
Expand Down
2 changes: 1 addition & 1 deletion util/util_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import (
"syscall"
"unsafe"

"github.com/coreos/pkg/dlopen"
"github.com/coreos/go-systemd/internal/dlopen"
)

var libsystemdNames = []string{
Expand Down

0 comments on commit d3cd4ed

Please sign in to comment.