@ -25,6 +25,7 @@ import (
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"io"
"log"
"log"
"net/netip"
"net/netip"
"os"
"os"
@ -273,17 +274,24 @@ func beWindowsSubprocess() bool {
log . Printf ( "Error reading environment config: %v" , err )
log . Printf ( "Error reading environment config: %v" , err )
}
}
ctx , cancel := context . WithCancel ( context . Background ( ) )
go func ( ) {
go func ( ) {
b := make ( [ ] byte , 16 )
b := make ( [ ] byte , 16 )
for {
for {
_ , err := os . Stdin . Read ( b )
_ , err := os . Stdin . Read ( b )
if err == io . EOF {
// Parent wants us to shut down gracefully.
log . Printf ( "subproc received EOF from stdin" )
cancel ( )
return
}
if err != nil {
if err != nil {
log . Fatalf ( "stdin err (parent process died): %v" , err )
log . Fatalf ( "stdin err (parent process died): %v" , err )
}
}
}
}
} ( )
} ( )
err := startIPNServer ( c on te xt. Background ( ) , log . Printf , logid )
err := startIPNServer ( c tx, log . Printf , logid )
if err != nil {
if err != nil {
log . Fatalf ( "ipnserver: %v" , err )
log . Fatalf ( "ipnserver: %v" , err )
}
}
@ -367,6 +375,7 @@ func babysitProc(ctx context.Context, args []string, logf logger.Logf) {
var proc struct {
var proc struct {
mu sync . Mutex
mu sync . Mutex
p * os . Process
p * os . Process
wStdin * os . File
}
}
done := make ( chan struct { } )
done := make ( chan struct { } )
@ -378,15 +387,18 @@ func babysitProc(ctx context.Context, args []string, logf logger.Logf) {
case sig = <- interrupt :
case sig = <- interrupt :
logf ( "babysitProc: got signal: %v" , sig )
logf ( "babysitProc: got signal: %v" , sig )
close ( done )
close ( done )
proc . mu . Lock ( )
proc . p . Signal ( sig )
proc . mu . Unlock ( )
case <- ctx . Done ( ) :
case <- ctx . Done ( ) :
logf ( "babysitProc: context done" )
logf ( "babysitProc: context done" )
sig = os . Kill
close ( done )
close ( done )
}
proc . mu . Lock ( )
proc . mu . Lock ( )
proc . p . Signal ( sig )
// Closing wStdin gives the subprocess a chance to shut down cleanly,
// which is important for cleaning up DNS settings etc.
proc . wStdin . Close ( )
proc . mu . Unlock ( )
proc . mu . Unlock ( )
}
} ( )
} ( )
bo := backoff . NewBackoff ( "babysitProc" , logf , 30 * time . Second )
bo := backoff . NewBackoff ( "babysitProc" , logf , 30 * time . Second )
@ -448,6 +460,7 @@ func babysitProc(ctx context.Context, args []string, logf logger.Logf) {
} else {
} else {
proc . mu . Lock ( )
proc . mu . Lock ( )
proc . p = cmd . Process
proc . p = cmd . Process
proc . wStdin = wStdin
proc . mu . Unlock ( )
proc . mu . Unlock ( )
err = cmd . Wait ( )
err = cmd . Wait ( )