...

Source file src/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go

Documentation: github.com/coreos/go-systemd/v22/internal/dlopen

     1  // Copyright 2016 CoreOS, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package dlopen provides some convenience functions to dlopen a library and
    16  // get its symbols.
    17  package dlopen
    18  
    19  // #cgo LDFLAGS: -ldl
    20  // #include <stdlib.h>
    21  // #include <dlfcn.h>
    22  import "C"
    23  import (
    24  	"errors"
    25  	"fmt"
    26  	"unsafe"
    27  )
    28  
    29  var ErrSoNotFound = errors.New("unable to open a handle to the library")
    30  
    31  // LibHandle represents an open handle to a library (.so)
    32  type LibHandle struct {
    33  	Handle  unsafe.Pointer
    34  	Libname string
    35  }
    36  
    37  // GetHandle tries to get a handle to a library (.so), attempting to access it
    38  // by the names specified in libs and returning the first that is successfully
    39  // opened. Callers are responsible for closing the handler. If no library can
    40  // be successfully opened, an error is returned.
    41  func GetHandle(libs []string) (*LibHandle, error) {
    42  	for _, name := range libs {
    43  		libname := C.CString(name)
    44  		defer C.free(unsafe.Pointer(libname))
    45  		handle := C.dlopen(libname, C.RTLD_LAZY)
    46  		if handle != nil {
    47  			h := &LibHandle{
    48  				Handle:  handle,
    49  				Libname: name,
    50  			}
    51  			return h, nil
    52  		}
    53  	}
    54  	return nil, ErrSoNotFound
    55  }
    56  
    57  // GetSymbolPointer takes a symbol name and returns a pointer to the symbol.
    58  func (l *LibHandle) GetSymbolPointer(symbol string) (unsafe.Pointer, error) {
    59  	sym := C.CString(symbol)
    60  	defer C.free(unsafe.Pointer(sym))
    61  
    62  	C.dlerror()
    63  	p := C.dlsym(l.Handle, sym)
    64  	e := C.dlerror()
    65  	if e != nil {
    66  		return nil, fmt.Errorf("error resolving symbol %q: %v", symbol, errors.New(C.GoString(e)))
    67  	}
    68  
    69  	return p, nil
    70  }
    71  
    72  // Close closes a LibHandle.
    73  func (l *LibHandle) Close() error {
    74  	C.dlerror()
    75  	C.dlclose(l.Handle)
    76  	e := C.dlerror()
    77  	if e != nil {
    78  		return fmt.Errorf("error closing %v: %v", l.Libname, errors.New(C.GoString(e)))
    79  	}
    80  
    81  	return nil
    82  }
    83  

View as plain text