12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // 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
- }
|