func getUnitFileName() (unit string, err error) { libname := C.CString("libsystemd.so") defer C.free(unsafe.Pointer(libname)) handle := C.dlopen(libname, C.RTLD_LAZY) if handle == nil { err = fmt.Errorf("error opening libsystemd.so") return } defer func() { if r := C.dlclose(handle); r != 0 { err = fmt.Errorf("error closing libsystemd.so") } }() sym := C.CString("sd_pid_get_unit") defer C.free(unsafe.Pointer(sym)) sd_pid_get_unit := C.dlsym(handle, sym) if sd_pid_get_unit == nil { err = fmt.Errorf("error resolving sd_pid_get_unit function") return } var s string u := C.CString(s) defer C.free(unsafe.Pointer(u)) ret := C.my_sd_pid_get_unit(sd_pid_get_unit, 0, &u) if ret < 0 { err = fmt.Errorf("error calling sd_pid_get_unit: %v", syscall.Errno(-ret)) return } unit = C.GoString(u) return }
// Open opens the shared library identified by the given name // with the given flags. See man dlopen for the available flags // and its meaning. Note that the only difference with dlopen is that // if nor RTLD_LAZY nor RTLD_NOW are specified, Open defaults to // RTLD_NOW rather than returning an error. If the name argument // passed to name does not have extension, the default for the // platform will be appended to it (e.g. .so, .dylib, etc...). func Open(name string, flag int) (*DL, error) { if flag&RTLD_LAZY == 0 && flag&RTLD_NOW == 0 { flag |= RTLD_NOW } if name != "" && filepath.Ext(name) == "" { name = name + LibExt } s := C.CString(name) defer C.free(unsafe.Pointer(s)) mu.Lock() handle := C.dlopen(s, C.int(flag)) var err error if handle == nil { err = dlerror() } mu.Unlock() if err != nil { if runtime.GOOS == "linux" && name == "libc.so" { // In most distros libc.so is now a text file // and in order to dlopen() it the name libc.so.6 // must be used. return Open(name+".6", flag) } return nil, err } return &DL{ handle: handle, }, nil }
func getSlice() (slice string, err error) { libname := C.CString("libsystemd.so") defer C.free(unsafe.Pointer(libname)) handle := C.dlopen(libname, C.RTLD_LAZY) if handle == nil { err = fmt.Errorf("error opening libsystemd.so") return } defer func() { if r := C.dlclose(handle); r != 0 { err = fmt.Errorf("error closing libsystemd.so") } }() sym := C.CString("sd_pid_get_slice") defer C.free(unsafe.Pointer(sym)) sd_pid_get_slice := C.dlsym(handle, sym) if sd_pid_get_slice == nil { err = fmt.Errorf("error resolving sd_pid_get_slice function") return } var s string sl := C.CString(s) defer C.free(unsafe.Pointer(sl)) ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl) if ret < 0 { err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret)) return } slice = C.GoString(sl) return }
func Open(name string) *Library { library := &Library{} library.name = name cname := cstr(library.name) defer cname.free() library.ptr = C.dlopen(cname, C.RTLD_LOCAL+C.RTLD_LAZY) return library }
func Open(filename string /*, flag int*/) (uintptr, error) { ptr := C.CString(filename) defer C.free(unsafe.Pointer(ptr)) ret := C.dlopen(ptr /*C.int(flag)*/, C.RTLD_LAZY) if ret != nil { return uintptr(ret), nil } return uintptr(ret), errors.New(C.GoString(C.dlerror())) }
func Load(n string) (h unsafe.Pointer, e error) { cn := C.CString(n) //TODO(t): use bytePtrFromString()? defer C.free(unsafe.Pointer(cn)) h = C.dlopen(cn, C.int(lazy)) if h == nil { e = errors.New(n + " could not be loaded") } return }
func dlopen(lib string, flags uint) (uintptr, error) { n := C.CString(lib) defer C.free(unsafe.Pointer(n)) u := C.dlopen(n, (C.int)(flags)) if u == nil { err := errors.New(C.GoString(C.dlerror())) return 0, err } return uintptr(u), nil }
func Open(fname string, flags Flags) (Handle, error) { c_str := C.CString(fname) defer C.free(unsafe.Pointer(c_str)) h := C.dlopen(c_str, C.int(flags)) if h == nil { c_err := C.dlerror() return Handle{}, fmt.Errorf("dl: %s", C.GoString(c_err)) } return Handle{h}, nil }
func Open(path string, flags Flag) (uintptr, error) { cstr := C.CString(path) defer C.free(unsafe.Pointer(cstr)) lib := C.dlopen(cstr, C.int(flags)) if lib == nil { err := dlerror("dlopen") return 0, err } return uintptr(lib), nil }
func loadThySelf(t *testing.T, symbol string) { this_process := C.dlopen(nil, C.RTLD_NOW) if this_process == nil { t.Fatal("dlopen:", C.GoString(C.dlerror())) } defer C.dlclose(this_process) symbol_address := C.dlsym(this_process, C.CString(symbol)) if symbol_address == nil { t.Fatal("dlsym:", C.GoString(C.dlerror())) } else { t.Log(symbol, symbol_address) } }
func dlopen(filename string, flag int) (uintptr, error) { Cfilename := C.CString(filename) defer C.free(unsafe.Pointer(Cfilename)) Cflag := C.int(flag) Chandle, _ := C.dlopen(Cfilename, Cflag) if Chandle == nil { // error happened CErrString := C.dlerror() return 0, errors.New(C.GoString(CErrString)) } else { return uintptr(Chandle), nil } }
// Load attempts to load a dynamically-linked gssapi library from the path // specified by the supplied Options. func Load(o *Options) (*Lib, error) { if o == nil { o = &Options{} } // We get the error in a separate call, so we need to lock OS thread runtime.LockOSThread() defer runtime.UnlockOSThread() lib := &Lib{ Printers: o.Printers, } if o.Krb5Config != "" { err := os.Setenv("KRB5_CONFIG", o.Krb5Config) if err != nil { return nil, err } } if o.Krb5Ktname != "" { err := os.Setenv("KRB5_KTNAME", o.Krb5Ktname) if err != nil { return nil, err } } path := o.Path() lib.Debug(fmt.Sprintf("Loading %q", path)) lib_cs := C.CString(path) defer C.free(unsafe.Pointer(lib_cs)) // we don't use RTLD_FIRST, it might be the case that the GSSAPI lib // delegates symbols to other libs it links against (eg, Kerberos) lib.handle = C.dlopen(lib_cs, C.RTLD_NOW|C.RTLD_LOCAL) if lib.handle == nil { return nil, fmt.Errorf("%s", C.GoString(C.dlerror())) } err := lib.populateFunctions() if err != nil { lib.Unload() return nil, err } lib.initConstants() return lib, nil }
// 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 }
/* * loadThySelf() * Go doesn't support dynamic linking. However, it supports a C interface that supports * dynamic linking. And it supports symbol export allowing callbacks into go functions * using a C calling convention. So, Go supports dynamic linking. */ func loadThySelf(symbol string) *[0]byte { this_process := C.dlopen(nil, C.RTLD_NOW) if this_process == nil { panic(C.GoString(C.dlerror())) } symbol_address := C.dlsym(this_process, C.CString(symbol)) if symbol_address == nil { panic(C.GoString(C.dlerror())) } C.dlclose(this_process) return (*[0]byte)(unsafe.Pointer(symbol_address)) }
func loadThySelf(t *testing.T, symbol string) { this_process := C.dlopen(nil, C.RTLD_NOW) if this_process == nil { t.Error("dlopen:", C.GoString(C.dlerror())) return } defer C.dlclose(this_process) symbol_address := C.dlsym(this_process, C.CString(symbol)) if symbol_address == nil { t.Error("dlsym:", C.GoString(C.dlerror())) return } t.Log(symbol, symbol_address) C.call4029(symbol_address) }
func dlopen(path string, flags int) (lib unsafe.Pointer, err error) { var f = C.int(flags) var s *C.char if len(path) != 0 { s = C.CString(path) defer C.free(unsafe.Pointer(s)) } dlmtx.Lock() defer dlmtx.Unlock() if lib = C.dlopen(s, f); lib == nil { err = dlerror() } return }
func getHandle() (*libHandle, error) { for _, name := range []string{ "libacl.so.1", "libacl.so", } { 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 }
func isRunningFromUnitFile() (ret bool, err error) { libname := C.CString("libsystemd.so") defer C.free(unsafe.Pointer(libname)) handle := C.dlopen(libname, C.RTLD_LAZY) if handle == nil { // we can't open libsystemd.so so we assume systemd is not // installed and we're not running from a unit file ret = false return } defer func() { if r := C.dlclose(handle); r != 0 { err = fmt.Errorf("error closing libsystemd.so") } }() sd_pid_get_owner_uid := C.dlsym(handle, C.CString("sd_pid_get_owner_uid")) if sd_pid_get_owner_uid == nil { err = fmt.Errorf("error resolving sd_pid_get_owner_uid function") return } var uid C.uid_t errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid) // when we're running from a unit file, sd_pid_get_owner_uid returns // ENOENT (systemd <220) or ENXIO (systemd >=220) switch { case errno >= 0: ret = false return case syscall.Errno(-errno) == syscall.ENOENT || syscall.Errno(-errno) == syscall.ENXIO: ret = true return default: err = fmt.Errorf("error calling sd_pid_get_owner_uid: %v", syscall.Errno(-errno)) return } }
// getHandle tries to get a handle to a systemd library (.so), attempting to // access it by several different names 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() (*libHandle, error) { for _, name := range []string{ // systemd < 209 "libsystemd-login.so", "libsystemd-login.so.0", // systemd >= 209 merged libsystemd-login into libsystemd proper "libsystemd.so", "libsystemd.so.0", } { 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 }