Fixed a bug with shared sockets.
This commit is contained in:
1 parent
7d82105d1d
commit
c842a1e3db
4 files changed
+179
-15
No files matched your search
@@ -72,7 +72,7 @@ func child_command(mode string) *exec.Cmd {
|
||||
func run_reader_process(mode string) {
|
||||
encoder := json.NewEncoder(os.Stdout)
|
||||
directory := os.Getenv("FENRIR_CONTROL_DIRECTORY")
|
||||
server, err := Open(context.Background(), Options{Directory: directory, RegistryDirectory: filepath.Join(directory, "registry"), TerminalMode: mode == "terminal"})
|
||||
server, err := Open(context.Background(), Options{Directory: directory, RegistryDirectory: filepath.Join(directory, "registry"), TerminalMode: mode == "terminal", WindowID: os.Getenv("WINDOWID")})
|
||||
if err != nil {
|
||||
_ = encoder.Encode(processReply{Error: err.Error()})
|
||||
return
|
||||
@@ -239,7 +239,7 @@ func TestReadersCoexistInBothStartupOrdersAndSurviveOwnerExit(t *testing.T) {
|
||||
privatePath := filepath.Join(options.Directory, fmt.Sprintf("fenrirscreenreader-%d.sock", reader.pid))
|
||||
check_receipt(t, second.send(t, privatePath, "COMMAND SAY private"), reader.pid, "COMMAND SAY private")
|
||||
}
|
||||
// No descendant terminal: a legacy caller belongs to the TTY reader.
|
||||
// An unrelated caller must not fall through to the console reader.
|
||||
client := child_command("client")
|
||||
client.Env = append(client.Env, "FENRIR_CONTROL_PATH="+mainPath, "FENRIR_CONTROL_TEXT=COMMAND SAY legacy")
|
||||
data, err := client.Output()
|
||||
@@ -250,7 +250,9 @@ func TestReadersCoexistInBothStartupOrdersAndSurviveOwnerExit(t *testing.T) {
|
||||
if err := json.Unmarshal(data, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check_receipt(t, reply, tty.pid, "COMMAND SAY legacy")
|
||||
if !strings.Contains(reply.Response, "unique reader") {
|
||||
t.Fatal("unidentified caller reached a reader", reply)
|
||||
}
|
||||
owner.stop(t)
|
||||
wait_main_owner(t, observer, 2, owner.pid)
|
||||
for _, reader := range []*readerProcess{tty, first, second} {
|
||||
@@ -328,3 +330,89 @@ func TestTerminalReadersRejectAmbiguityAndRecoverAfterOwnerFailure(t *testing.T)
|
||||
check_receipt(t, reader.send(t, mainPath, "COMMAND SAY recovered"), reader.pid, "COMMAND SAY recovered")
|
||||
}
|
||||
}
|
||||
|
||||
// Screen reattachment and Codex's app-server can leave the caller outside the
|
||||
// reader's descendant tree. The connecting process retains its X11 identity.
|
||||
func TestWindowRoutingWithoutReaderAncestor(t *testing.T) {
|
||||
for _, consoleFirst := range []bool{true, false} {
|
||||
name := "terminal-first"
|
||||
if consoleFirst {
|
||||
name = "console-first"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
options := private_options(t)
|
||||
observer := &Server{ctx: context.Background(), options: options}
|
||||
mainPath := observer.main_path()
|
||||
t.Setenv("DISPLAY", ":fixture")
|
||||
t.Setenv("WINDOWID", "42")
|
||||
var terminal *readerProcess
|
||||
if consoleFirst {
|
||||
start_reader_process(t, options.Directory, "tty")
|
||||
}
|
||||
terminal = start_reader_process(t, options.Directory, "terminal")
|
||||
if !consoleFirst {
|
||||
start_reader_process(t, options.Directory, "tty")
|
||||
}
|
||||
// This client is a sibling, not a child, of the terminal reader.
|
||||
text := "command application codex"
|
||||
check_receipt(t, external_request(t, mainPath, text), terminal.pid, text)
|
||||
t.Setenv("WINDOWID", "43")
|
||||
second := start_reader_process(t, options.Directory, "terminal")
|
||||
check_receipt(t, external_request(t, mainPath, text), second.pid, text)
|
||||
t.Setenv("WINDOWID", "42")
|
||||
check_receipt(t, external_request(t, mainPath, text), terminal.pid, text)
|
||||
// Even a sole terminal on a different display is not a match.
|
||||
t.Setenv("DISPLAY", ":other")
|
||||
if reply := external_request(t, mainPath, text); !strings.Contains(reply.Response, "unique reader") {
|
||||
t.Fatal("cross-display routing", reply)
|
||||
}
|
||||
t.Setenv("DISPLAY", ":fixture")
|
||||
t.Setenv("WINDOWID", "unknown")
|
||||
if reply := external_request(t, mainPath, text); !strings.Contains(reply.Response, "unique reader") {
|
||||
t.Fatal("unknown window routed", reply)
|
||||
}
|
||||
t.Setenv("WINDOWID", "")
|
||||
if reply := external_request(t, mainPath, text); !strings.Contains(reply.Response, "unique reader") {
|
||||
t.Fatal("unidentified background caller routed", reply)
|
||||
}
|
||||
t.Setenv("WINDOWID", "42")
|
||||
start_reader_process(t, options.Directory, "terminal")
|
||||
if reply := external_request(t, mainPath, text); !strings.Contains(reply.Response, "unique reader") {
|
||||
t.Fatal("duplicate window routed arbitrarily", reply)
|
||||
}
|
||||
// Discovery remains usable when routing is ambiguous.
|
||||
if reply := external_request(t, mainPath, "ls"); !strings.Contains(reply.Response, "pid=") {
|
||||
t.Fatal("discovery failed", reply)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsoleIdentityAndUnknownCallers(t *testing.T) {
|
||||
options := private_options(t)
|
||||
console := instance{PID: os.Getpid(), uid: os.Geteuid(), ScreenDriver: "vcsaDriver"}
|
||||
server := &Server{ctx: context.Background(), options: options}
|
||||
for _, trial := range []struct {
|
||||
name string
|
||||
identity processIdentity
|
||||
consoles []instance
|
||||
valid bool
|
||||
}{
|
||||
{"console", processIdentity{console: true}, []instance{console}, true},
|
||||
{"console ignores stale window", processIdentity{console: true, window: "42", display: ":fixture"}, []instance{console}, true},
|
||||
{"multiple consoles", processIdentity{console: true}, []instance{console, console}, false},
|
||||
{"no console", processIdentity{console: true}, nil, false},
|
||||
{"background", processIdentity{}, []instance{console}, false},
|
||||
{"unknown window", processIdentity{window: "42", display: ":fixture"}, []instance{console}, false},
|
||||
} {
|
||||
t.Run(trial.name, func(t *testing.T) {
|
||||
_, err := server.route_identity(trial.identity, os.Geteuid(), nil, trial.consoles)
|
||||
if (err == nil) != trial.valid {
|
||||
t.Fatal("unexpected routing", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
if got := process_identity(os.Getpid(), os.Geteuid()+1); got != (processIdentity{}) {
|
||||
t.Fatal("read identity of a different UID", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user