in sandbox/sandbox.go [323:368]
func runInGvisor() {
const binPath = "/tmpfs/play"
if _, err := io.WriteString(os.Stdout, containedStartMessage); err != nil {
log.Fatalf("writing to stdout: %v", err)
}
slurp, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("reading stdin in contained mode: %v", err)
}
nl := bytes.IndexByte(slurp, '\n')
if nl == -1 {
log.Fatalf("no newline found in input")
}
metaJSON, bin := slurp[:nl], slurp[nl+1:]
if err := ioutil.WriteFile(binPath, bin, 0755); err != nil {
log.Fatalf("writing contained binary: %v", err)
}
defer os.Remove(binPath) // not that it matters much, this container will be nuked
var meta processMeta
if err := json.NewDecoder(bytes.NewReader(metaJSON)).Decode(&meta); err != nil {
log.Fatalf("error decoding JSON meta: %v", err)
}
if _, err := os.Stderr.Write(containedStderrHeader); err != nil {
log.Fatalf("writing header to stderr: %v", err)
}
cmd := exec.Command(binPath)
cmd.Args = append(cmd.Args, meta.Args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
log.Fatalf("cmd.Start(): %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), runTimeout-500*time.Millisecond)
defer cancel()
if err = internal.WaitOrStop(ctx, cmd, os.Interrupt, 250*time.Millisecond); err != nil {
if errors.Is(err, context.DeadlineExceeded) {
fmt.Fprintln(os.Stderr, "timeout running program")
}
}
os.Exit(errExitCode(err))
return
}