Skip to content

Commit 1326bdb

Browse files
committed
Avoid treating stale self pidfiles as active
1 parent 148702d commit 1326bdb

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

cmd/nssh/status.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ func activeSessions() []sessionInfo {
9090
if err != nil {
9191
return nil
9292
}
93+
currentPID := os.Getpid()
9394
var out []sessionInfo
9495
for _, e := range entries {
9596
if e.IsDir() || !strings.HasSuffix(e.Name(), ".json") {
@@ -104,6 +105,11 @@ func activeSessions() []sessionInfo {
104105
if err := json.Unmarshal(data, &info); err != nil {
105106
continue
106107
}
108+
// A pidfile for our own PID is stale PID reuse; don't let replace kill us.
109+
if info.PID == currentPID {
110+
_ = os.Remove(path)
111+
continue
112+
}
107113
// Signal 0 is a permission/existence probe on POSIX.
108114
if err := syscall.Kill(info.PID, 0); err != nil {
109115
_ = os.Remove(path)

cmd/nssh/status_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"testing"
9+
"time"
10+
)
11+
12+
func TestActiveSessionsDropsStaleSelfPID(t *testing.T) {
13+
t.Setenv("XDG_STATE_HOME", t.TempDir())
14+
15+
dir := sessionsDir()
16+
if err := os.MkdirAll(dir, 0o755); err != nil {
17+
t.Fatal(err)
18+
}
19+
20+
path := filepath.Join(dir, fmt.Sprintf("%d.json", os.Getpid()))
21+
data, err := json.Marshal(sessionInfo{
22+
PID: os.Getpid(),
23+
Target: "devbox",
24+
Host: "devbox",
25+
Topic: "nssh_stale",
26+
Server: defaultServer,
27+
Started: time.Now().Add(-time.Hour),
28+
})
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
if err := os.WriteFile(path, data, 0o644); err != nil {
33+
t.Fatal(err)
34+
}
35+
36+
if sessions := activeSessions(); len(sessions) != 0 {
37+
t.Fatalf("activeSessions() = %d sessions, want 0", len(sessions))
38+
}
39+
if _, err := os.Stat(path); !os.IsNotExist(err) {
40+
t.Fatalf("stale self pidfile still exists: %v", err)
41+
}
42+
}

0 commit comments

Comments
 (0)