// Returns nil on device error, missing entry on sysattr error func (self Device) SysAttrs(sysAttrs ...string) map[string]string { udev := C.udev_new() defer C.udev_unref(udev) cSysPath := C.CString(self.SysPath) defer C.free(unsafe.Pointer(cSysPath)) udev_device := C.udev_device_new_from_syspath(udev, cSysPath) if udev_device == nil { return nil } defer C.udev_device_unref(udev_device) // get out := make(map[string]string) for _, sysAttr := range sysAttrs { cSysAttr := C.CString(sysAttr) defer C.free(unsafe.Pointer(cSysAttr)) cValue := C.udev_device_get_sysattr_value(udev_device, cSysAttr) if cValue == nil { continue } out[sysAttr] = C.GoString(cValue) } return out }
// Lock locks a udev context func (u *Udev) lock() { u.once.Do(func() { u.ptr = C.udev_new() runtime.SetFinalizer(u, udevUnref) }) u.m.Lock() }
/* * Filter by match fields: * * Subsystem */ func Enumerate(match Device) ([]Device, error) { udev := C.udev_new() defer C.udev_unref(udev) udev_enumerate := C.udev_enumerate_new(udev) defer C.udev_enumerate_unref(udev_enumerate) if match.Subsystem != "" { // libudev strdup's the string cSubsystem := C.CString(match.Subsystem) defer C.free(unsafe.Pointer(cSubsystem)) if C.udev_enumerate_add_match_subsystem(udev_enumerate, cSubsystem) < 0 { return nil, Error{"udev_enumerate_add_match_subsystem"} } } if C.udev_enumerate_scan_devices(udev_enumerate) < 0 { return nil, Error{"udev_enumerate_scan_devices"} } // list var devices []Device udev_list_entry := C.udev_enumerate_get_list_entry(udev_enumerate) for ; udev_list_entry != nil; udev_list_entry = C.udev_list_entry_get_next(udev_list_entry) { udev_device := C.udev_device_new_from_syspath(udev, C.udev_list_entry_get_name(udev_list_entry)) if udev_device == nil { return nil, Error{"udev_device_new_from_syspath"} } defer C.udev_device_unref(udev_device) var device Device if err := device.fromUdev(udev_device); err != nil { return nil, err } else { devices = append(devices, device) } } return devices, nil }
func MonitorUdev(subsystem string) (*Monitor, error) { cName := C.CString("udev") defer C.free(unsafe.Pointer(cName)) udev := C.udev_new() udev_monitor := C.udev_monitor_new_from_netlink(udev, cName) if udev_monitor == nil { C.udev_unref(udev) return nil, Error{"udev_monitor_new_from_netlink"} } if subsystem != "" { cSubsystem := C.CString(subsystem) defer C.free(unsafe.Pointer(cSubsystem)) if C.udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, cSubsystem, nil) < 0 { C.udev_monitor_unref(udev_monitor) C.udev_unref(udev) return nil, Error{"udev_monitor_filter_add_match_subsystem_devtype"} } } if C.udev_monitor_enable_receiving(udev_monitor) < 0 { C.udev_monitor_unref(udev_monitor) C.udev_unref(udev) return nil, Error{"udev_monitor_enable_receiving"} } // set blocking if fd := C.udev_monitor_get_fd(udev_monitor); fd < 0 { C.udev_monitor_unref(udev_monitor) C.udev_unref(udev) return nil, Error{"udev_monitor_get_fd"} } else if err := syscall.SetNonblock(int(fd), false); err != nil { C.udev_monitor_unref(udev_monitor) C.udev_unref(udev) return nil, err } return &Monitor{udev, udev_monitor}, nil }
func (self Device) ParentWithSubsystemDevType(subsystem string, devtype string) (device Device, err error) { udev := C.udev_new() defer C.udev_unref(udev) cSysPath := C.CString(self.SysPath) defer C.free(unsafe.Pointer(cSysPath)) udev_device := C.udev_device_new_from_syspath(udev, cSysPath) if udev_device == nil { return device, Error{"udev_device_new_from_syspath"} } defer C.udev_device_unref(udev_device) // parent cSubsystem := C.CString(subsystem) defer C.free(unsafe.Pointer(cSubsystem)) var cDevType *C.char if devtype != "" { cDevType = C.CString(devtype) defer C.free(unsafe.Pointer(cDevType)) } udev_parent := C.udev_device_get_parent_with_subsystem_devtype(udev_device, cSubsystem, cDevType) if udev_parent == nil { return device, Error{"udev_device_get_parent"} } // lifetime tied to udev_device // return if err := device.fromUdev(udev_parent); err != nil { return device, err } return device, nil }
func NewUdev() Udev { var u = C.udev_new() return Udev{u} }
func enumerate() ([]DeviceDescription, error) { var result []DeviceDescription udev := C.udev_new() if udev == nil { return nil, errors.New("Udev connection failed!") } enumerate := C.udev_enumerate_new(udev) if enumerate == nil { return nil, errors.New("Unix: udev_enumerate_new() returned: 0") } var devices *C.struct_udev_list_entry C.udev_enumerate_add_match_subsystem(enumerate, C.CString("tty")) C.udev_enumerate_scan_devices(enumerate) devices = C.udev_enumerate_get_list_entry(enumerate) for devices != nil { syspath := C.udev_list_entry_get_name(devices) udev_device := C.udev_device_new_from_syspath(udev, syspath) if udev_device != nil { var dev DeviceDescription s := C.GoString(C.udev_device_get_devnode(udev_device)) for _, mask := range devNamesMask { if strings.Contains(s, mask) { dev.Description = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_MODEL_FROM_DATABASE"))) dev.Revision = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_REVISION"))) dev.Bus = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_BUS"))) dev.Driver = C.GoString(C.udev_device_get_property_value( udev_device, C.CString(eqBusDrvMap[dev.Bus]))) dev.LocationInfo = strings.Replace(C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_MODEL_ENC"))), "\\x20", " ", -1) dev.Manufacturer = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_VENDOR_FROM_DATABASE"))) dev.SubSystem = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("SUBSYSTEM"))) dev.SystemPath = C.GoString(C.udev_device_get_syspath(udev_device)) dev.ShortName = C.GoString(C.udev_device_get_property_value( udev_device, C.CString("DEVNAME"))) dev.Name = dev.ShortName dev.FriendlyName = fmt.Sprintf("%s (%s)", dev.Description, dev.ShortName) var v []byte var err error if v, err = hex.DecodeString(C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_VENDOR_ID")))); err == nil && len(v) == 2 { dev.VendorID = (uint16)(v[0])<<8 + (uint16)(v[1]) } if v, err = hex.DecodeString(C.GoString(C.udev_device_get_property_value( udev_device, C.CString("ID_MODEL_ID")))); err == nil && len(v) == 2 { dev.ProductID = (uint16)(v[0])<<8 + (uint16)(v[1]) } result = append(result, dev) } } } devices = C.udev_list_entry_get_next(devices) } C.udev_enumerate_unref(enumerate) return result, nil }