diff options
Diffstat (limited to 'sd_login/cgroup_systemd.go')
-rw-r--r-- | sd_login/cgroup_systemd.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/sd_login/cgroup_systemd.go b/sd_login/cgroup_systemd.go new file mode 100644 index 0000000..bbef9d3 --- /dev/null +++ b/sd_login/cgroup_systemd.go @@ -0,0 +1,107 @@ +// Copyright (C) 2016-2017 Luke Shumaker <lukeshu@sbcglobal.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sd_login + +import ( + "os" + "strconv" + "strings" +) + +// XXX: logind +func (cgroup _Cgroup) GetSession() Session { + unit := cgroup.GetUnit() + + session, ok := trimPrefixSuffix(unit, "session-", ".scope") + if !ok || !valid_session_name(session) { + return "" + } + + return Session(session) +} + +// XXX: who owns this, systemd or logind? elogind doesn't implement +// it, but idk +func (cgroup _Cgroup) GetOwnerUser() User { + slice := cgroup.GetSlice() + + uid_str, ok := trimPrefixSuffix(slice, "user-", ".slice") + if !ok { + return -1 + } + + uid, err := strconv.Atoi(uid_str) + if err != nil { + return -1 + } + + return User(uid) +} + +// XXX: machined +func (cgroup _Cgroup) GetMachine() Machine { + unit := cgroup.GetUnit() + if unit == "" { + return "" + } + + machine, err := os.Readlink("/run/systemd/machines/unit:" + unit) + if err != nil { + return "" + } + return Machine(machine) +} + +// XXX: systemd +func (cgroup _Cgroup) decodeUnit() string { + unit, _ := split2(string(cgroup), '/') + if len(unit) < 3 { + return "" + } + unit = cgUnescape(unit) + if valid_unit_name(unit)&(unit_name_plain|unit_name_instance) == 0 { + return "" + } + return unit +} + +func (cgroup _Cgroup) GetUnit() string { + unit := cgroup.MaybeSkipSlices().decodeUnit() + if strings.HasSuffix(unit, ".slice") { + return "" + } + return unit +} +func (cgroup _Cgroup) GetUserUnit() string { + return cgroup.MustSkipUserPrefix().GetUnit() +} +func (cgroup _Cgroup) GetSlice() string { + cg := string(cgroup) + n := 0 + for { + cg = strings.TrimLeft(cg, "/") + part, rest := split2(cg, '/') + if !valid_slice_name(part) { + if n == 0 { + return "-.slice" + } + return _Cgroup(cg).decodeUnit() + } + cg = rest + } +} +func (cgroup _Cgroup) GetUserSlice() string { + return cgroup.MustSkipUserPrefix().GetSlice() +} |