diff options
Diffstat (limited to 'internal/kobject/event.go')
| -rw-r--r-- | internal/kobject/event.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/internal/kobject/event.go b/internal/kobject/event.go new file mode 100644 index 00000000..33cb91b8 --- /dev/null +++ b/internal/kobject/event.go @@ -0,0 +1,90 @@ +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 + } + } +} |
