diff options
Diffstat (limited to 'internal/sys')
| -rw-r--r-- | internal/sys/hsu.go | 87 |
1 files changed, 33 insertions, 54 deletions
diff --git a/internal/sys/hsu.go b/internal/sys/hsu.go index 2be12d1e..39fb4f18 100644 --- a/internal/sys/hsu.go +++ b/internal/sys/hsu.go @@ -17,69 +17,48 @@ import ( // Hsu caches responses from cmd/hsu. type Hsu struct { - uidOnce sync.Once - uidCopy map[int]struct { - uid int - err error - } - uidMu sync.RWMutex + idOnce sync.Once + idErr error + id int } var ErrHsuAccess = errors.New("current user is not in the hsurc file") func (h *Hsu) Uid(identity int) (int, error) { - h.uidOnce.Do(func() { - h.uidCopy = make(map[int]struct { - uid int - err error - }) - }) - - { - h.uidMu.RLock() - u, ok := h.uidCopy[identity] - h.uidMu.RUnlock() - if ok { - return u.uid, u.err - } - } + h.idOnce.Do(func() { + h.id = -1 + hsuPath := internal.MustHsuPath() - h.uidMu.Lock() - defer h.uidMu.Unlock() + cmd := exec.Command(hsuPath) + cmd.Path = hsuPath + cmd.Stderr = os.Stderr // pass through fatal messages + cmd.Env = make([]string, 0) + cmd.Dir = container.FHSRoot + var ( + p []byte + exitError *exec.ExitError + ) - u := struct { - uid int - err error - }{} - defer func() { h.uidCopy[identity] = u }() - - u.uid = -1 - hsuPath := internal.MustHsuPath() - - cmd := exec.Command(hsuPath) - cmd.Path = hsuPath - cmd.Stderr = os.Stderr // pass through fatal messages - cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(identity)} - cmd.Dir = container.FHSRoot - var ( - p []byte - exitError *exec.ExitError - ) - - const step = "obtain uid from hsu" - if p, u.err = cmd.Output(); u.err == nil { - u.uid, u.err = strconv.Atoi(string(p)) - if u.err != nil { - u.err = &hst.AppError{Step: step, Err: u.err, Msg: "invalid uid string from hsu"} + const step = "obtain uid from hsu" + if p, h.idErr = cmd.Output(); h.idErr == nil { + h.id, h.idErr = strconv.Atoi(string(p)) + if h.idErr != nil { + h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"} + } + } else if errors.As(h.idErr, &exitError) && exitError != nil && exitError.ExitCode() == 1 { + // hsu prints an error message in this case + h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess} + } else if os.IsNotExist(h.idErr) { + h.idErr = &hst.AppError{Step: step, Err: os.ErrNotExist, + Msg: fmt.Sprintf("the setuid helper is missing: %s", hsuPath)} } - } else if errors.As(u.err, &exitError) && exitError != nil && exitError.ExitCode() == 1 { - // hsu prints an error message in this case - u.err = &hst.AppError{Step: step, Err: ErrHsuAccess} - } else if os.IsNotExist(u.err) { - u.err = &hst.AppError{Step: step, Err: os.ErrNotExist, - Msg: fmt.Sprintf("the setuid helper is missing: %s", hsuPath)} + }) + + uid := -1 + if h.id >= 0 { + uid = 1000000 + h.id*10000 + identity } - return u.uid, u.err + return uid, h.idErr } // MustUid calls [State.Uid] and terminates on error. |
