After commit c018f5fd29 Fenrir is being switched over to go. If you do not want to be part of the testing process, please switch to master.
This commit is contained in:
1 parent
c018f5fd29
commit
0e50de4c76
1047 files changed
+58364
-63747
No files matched your search
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package control
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
)
|
||||
|
||||
func (s *Server) endpoint_snapshot() []endpoint {
|
||||
s.endpointsMu.RLock()
|
||||
defer s.endpointsMu.RUnlock()
|
||||
return slices.Clone(s.endpoints)
|
||||
}
|
||||
|
||||
// Every default instance has a private endpoint. The first available instance
|
||||
// also serves the shared path, and a survivor claims it after that owner exits.
|
||||
func (s *Server) claim_main() bool {
|
||||
if s.options.SocketFile != "" || s.ctx.Err() != nil {
|
||||
return false
|
||||
}
|
||||
s.endpointsMu.Lock()
|
||||
defer s.endpointsMu.Unlock()
|
||||
for _, endpoint := range s.endpoints {
|
||||
if endpoint.path == s.main_path() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
endpoint, err := listen(s.main_path())
|
||||
if err != nil {
|
||||
return false // Active readers and unrelated paths are preserved.
|
||||
}
|
||||
if s.ctx.Err() != nil {
|
||||
endpoint.listener.Close()
|
||||
if info, err := os.Lstat(endpoint.path); err == nil && os.SameFile(info, endpoint.info) {
|
||||
_ = os.Remove(endpoint.path)
|
||||
}
|
||||
return false
|
||||
}
|
||||
s.endpoints = append(s.endpoints, endpoint)
|
||||
s.workers.Go(func() { s.accept(endpoint) })
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Server) private_path(data instance) string {
|
||||
path := filepath.Join(filepath.Dir(s.main_path()), fmt.Sprintf("fenrirscreenreader-%d.sock", data.PID))
|
||||
if slices.Contains(data.SocketFiles, path) {
|
||||
return path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Select a terminal only when it is an ancestor of the caller. Outside a
|
||||
// terminal instance, prefer TTY; a single same-user terminal is unambiguous.
|
||||
// Never silently send a command to an arbitrary terminal in a multi-reader session.
|
||||
func (s *Server) route_target(pid, uid int) (string, error) {
|
||||
instances := s.instances()
|
||||
var terminals, consoles []instance
|
||||
for _, data := range instances {
|
||||
if s.private_path(data) == "" {
|
||||
continue
|
||||
}
|
||||
if data.ScreenDriver == "vcsaDriver" && (data.uid == 0 || data.uid == uid) {
|
||||
consoles = append(consoles, data)
|
||||
} else if data.ScreenDriver == "ptyDriver" && (data.uid == uid || uid == 0) {
|
||||
terminals = append(terminals, data)
|
||||
}
|
||||
}
|
||||
seen := map[int]bool{}
|
||||
for ancestor := pid; ancestor > 1 && !seen[ancestor]; ancestor = parent_pid(ancestor) {
|
||||
seen[ancestor] = true
|
||||
for _, data := range terminals {
|
||||
if data.PID == ancestor {
|
||||
return s.destination(data)
|
||||
}
|
||||
}
|
||||
for _, data := range consoles {
|
||||
if data.PID == ancestor {
|
||||
return s.destination(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(consoles) == 1 {
|
||||
return s.destination(consoles[0])
|
||||
}
|
||||
if len(consoles) == 0 && len(terminals) == 1 {
|
||||
return s.destination(terminals[0])
|
||||
}
|
||||
if len(consoles) == 0 && len(terminals) == 0 {
|
||||
// The application applies its normal authorization to the shared owner.
|
||||
return "", nil
|
||||
}
|
||||
return "", fmt.Errorf("caller does not identify a unique reader; use its private socket")
|
||||
}
|
||||
|
||||
func (s *Server) destination(data instance) (string, error) {
|
||||
if data.PID == os.Getpid() {
|
||||
return "", nil
|
||||
}
|
||||
if !data.ConnectionHandoff {
|
||||
return "", fmt.Errorf("reader %d cannot accept a connection handoff", data.PID)
|
||||
}
|
||||
path := s.private_path(data)
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil || info.Mode()&os.ModeSocket == 0 {
|
||||
return "", fmt.Errorf("reader %d private socket is unavailable", data.PID)
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
Reference in new issue
Block a user