// +build linux package runner import ( "os" "os/exec" "syscall" "unsafe" ) // ByteCount is a type byte count const. type ByteCount uint64 // ByteCount values. const ( Byte ByteCount = 1 Kilobyte ByteCount = 1024 * Byte Megabyte ByteCount = 1024 * Kilobyte Gigabyte ByteCount = 1024 * Megabyte ) // prlimit invokes the system's prlimit call. Copied from Go source tree. // // Note: this needs either the CAP_SYS_RESOURCE capability, or the invoking // process needs to have the same functional user and group as the pid being // modified. // // see: man 2 prlimit func prlimit(pid int, res int, newv, old *syscall.Rlimit) error { _, _, err := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, uintptr(pid), uintptr(res), uintptr(unsafe.Pointer(newv)), uintptr(unsafe.Pointer(old)), 0, 0) if err != 0 { return err } return nil } // Rlimit is a Chrome command line option to set the soft rlimit value for res // on a running Chrome process. // // Note: uses Linux prlimit system call, and is invoked after the child process // has been started. // // see: man 2 prlimit func Rlimit(res int, cur, max uint64) CommandLineOption { return ProcessOpt(func(p *os.Process) error { return prlimit(p.Pid, syscall.RLIMIT_AS, &syscall.Rlimit{ Cur: cur, Max: max, }, nil) }) } // LimitMemory is a Chrome command line option to set the soft memory limit for // a running Chrome process. // // Note: uses Linux prlimit system call, and is invoked after the child // process has been started. func LimitMemory(mem ByteCount) CommandLineOption { return Rlimit(syscall.RLIMIT_AS, uint64(mem), uint64(mem)) } // LimitCoreDump is a Chrome command line option to set the soft core dump // limit for a running Chrome process. // // Note: uses Linux prlimit system call, and is invoked after the child // process has been started. func LimitCoreDump(sz ByteCount) CommandLineOption { return Rlimit(syscall.RLIMIT_CORE, uint64(sz), uint64(sz)) } // ForceKill is a Chrome command line option that forces Chrome to be killed // when the parent is killed. // // Note: sets exec.Cmd.SysProcAttr.Setpgid = true (only for Linux) func ForceKill(m map[string]interface{}) error { return CmdOpt(func(c *exec.Cmd) error { if c.SysProcAttr == nil { c.SysProcAttr = new(syscall.SysProcAttr) } c.SysProcAttr.Pdeathsig = syscall.SIGKILL return nil })(m) }