Beispiel #1
0
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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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()))
}
Beispiel #6
0
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
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
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)
	}
}
Beispiel #11
0
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
	}
}
Beispiel #12
0
// 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
}
Beispiel #13
0
// 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
}
Beispiel #14
0
/*
* 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))
}
Beispiel #15
0
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)
}
Beispiel #16
0
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
}
Beispiel #17
0
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
}
Beispiel #18
0
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
	}
}
Beispiel #19
0
// 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
}