package kobject import ( "errors" "strconv" "strings" "unsafe" "hakurei.app/internal/uevent" ) // Event is a [uevent.Message] with known environment variables processed. type Event struct { // alloc_uevent_skb: action_string Action uevent.KobjectAction `json:"action"` // alloc_uevent_skb: devpath DevPath string `json:"devpath"` // Uninterpreted environment variable pairs. An entry missing a separator // gains the value "\x00". Env map[string]string `json:"env"` // SEQNUM value set by the kernel. Sequence uint64 `json:"seqnum"` // SYNTH_UUID value set on trigger, nil denotes a non-synthetic event. Synth *uevent.UUID `json:"synth_uuid,omitempty"` // SUBSYSTEM value set by the kernel. Subsystem string `json:"subsystem"` } // Populate populates e with the contents of a [uevent.Message]. // // The ACTION and DEVPATH environment variables are ignored and assumed to be // consistent with the header. func (e *Event) Populate(reportErr func(error), m *uevent.Message) { if reportErr == nil { reportErr = func(error) {} } *e = Event{ Action: m.Action, DevPath: m.DevPath, Env: make(map[string]string), } for _, s := range m.Env { k, v, ok := strings.Cut(s, "=") if !ok { if _, ok = e.Env[s]; !ok { e.Env[s] = "\x00" } continue } switch k { case "ACTION", "DEVPATH": continue case "SEQNUM": seq, err := strconv.ParseUint(v, 10, 64) if err != nil { if _e := errors.Unwrap(err); _e != nil { err = _e } reportErr(err) e.Env[k] = v continue } e.Sequence = seq case "SYNTH_UUID": var uuid uevent.UUID err := uuid.UnmarshalText(unsafe.Slice(unsafe.StringData(v), len(v))) if err != nil { reportErr(err) e.Env[k] = v continue } e.Synth = &uuid case "SUBSYSTEM": e.Subsystem = v default: e.Env[k] = v } } }