Documentation
¶
Overview ¶
Package proc provides platform-agnostic process management with safety guarantees.
It abstracts away OS-specific details for reliable process termination:
- Windows: Uses Job Objects to ensure child processes are killed when the parent exits.
- Linux: Uses Pdeathsig (SIGKILL) for the same guarantee.
Recommended Usage ¶
Use NewCmd to create a command with context-linked cancellation and then call Start to apply platform hygiene and launch the process:
cmd := proc.NewCmd(ctx, "worker", "--config", "prod.yaml")
cmd.Stdout = os.Stdout // configure before starting
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
cmd.Wait()
Legacy Usage ¶
If you must construct the command yourself (e.g. to set SysProcAttr), use exec.CommandContext directly and pass to Start:
cmd := exec.CommandContext(ctx, "ping", "google.com") _ = proc.Start(cmd) cmd.Wait()
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var StrictMode bool
StrictMode if true, will cause Start to return an error on unsupported platforms instead of just logging a warning. Default is false.
Functions ¶
func Monitor ¶ added in v0.3.0
Monitor polls the resource usage of cmd.Process at the given interval and sends each Metrics snapshot to the returned channel.
Monitor returns immediately. The sampling goroutine runs until:
- ctx is cancelled, or
- the channel's consumer stops reading (the channel is unbuffered).
The returned channel is closed when monitoring stops. Monitor returns an error only if the process has not been started yet (cmd.Process == nil).
Example:
cmd := proc.NewCmd(ctx, "worker", "--config", "prod.yaml")
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
ch, err := proc.Monitor(ctx, cmd.Cmd, time.Second)
if err != nil {
log.Fatal(err)
}
for m := range ch {
fmt.Printf("pid=%d cpu=%.1f%% mem=%d KB\n", m.PID, m.CPUPercent, m.MemRSS/1024)
}
func Start ¶
Start starts the specified command but ensures that the child process is killed if the parent process (this process) dies.
On Linux, it uses SysProcAttr.Pdeathsig (SIGKILL). On Windows, it uses Job Objects (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE).
On other platforms, it falls back to cmd.Start() and logs a warning, unless StrictMode is set to true, in which case it returns an error.
This is a safer alternative to cmd.Start() for long-running child processes.
Example ¶
package main
import (
"context"
"fmt"
"os/exec"
"time"
"github.com/aretw0/procio/proc"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
// Start a process. proc.Start wraps the standard exec.Cmd to provide
// platform-specific guarantees (Job Objects on Windows, Pdeathsig on Linux)
// that ensure child processes are terminated when the parent process exits.
cmd := exec.CommandContext(ctx, "echo", "hello proc")
// Start the process with hygiene guarantees.
if err := proc.Start(cmd); err != nil {
fmt.Println("Error starting process:", err)
return
}
// For the sake of the example, wait for completion
_ = cmd.Wait()
fmt.Println("Process completed")
}
Types ¶
type Cmd ¶ added in v0.4.1
Cmd is a type that wraps exec.Cmd to provide safe execution defaults. It ensures that platform hygiene attributes (Pdeathsig on Linux, Job Objects on Windows) are applied seamlessly when starting the process.
func NewCmd ¶ added in v0.2.0
NewCmd creates a new Cmd pre-configured with context-linked cancellation (exec.CommandContext semantics). It is the recommended entry point when the caller holds a context.
Unlike the standard library exec.CommandContext, methods like Start() and Run() on this returned Cmd will automatically apply platform safety mechanisms to prevent child process leaks.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/aretw0/procio/proc"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
// NewCmd combines exec.CommandContext with automatic platform hygiene.
// It is the recommended entry point: no need to import os/exec directly.
cmd := proc.NewCmd(ctx, "echo", "hello new cmd")
if err := cmd.Start(); err != nil {
fmt.Println("Error starting process:", err)
return
}
_ = cmd.Wait()
fmt.Println("Process started with NewCmd completed")
}
func (*Cmd) CombinedOutput ¶ added in v0.4.1
CombinedOutput runs the command and returns its combined standard output and standard error. It applies the same platform hygiene attributes as Start.
func (*Cmd) Output ¶ added in v0.4.1
Output runs the command and returns its standard output. It applies the same platform hygiene attributes as Start.
func (*Cmd) Run ¶ added in v0.4.1
Run starts the specified command and waits for it to complete. It applies the same platform hygiene attributes as Start.
func (*Cmd) Start ¶ added in v0.4.1
Start starts the specified command but ensures that the child process is killed if the parent process (this process) dies.
On Linux, it uses SysProcAttr.Pdeathsig (SIGKILL). On Windows, it uses Job Objects (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE).
On other platforms, it falls back to cmd.Start() and logs a warning, unless StrictMode is set to true, in which case it returns an error.
type Metrics ¶ added in v0.3.0
type Metrics struct {
// PID is the process ID this snapshot belongs to.
PID int
// CPUPercent is the estimated CPU usage percentage since the previous
// snapshot (0–100 per logical core; may exceed 100 on multi-core systems).
CPUPercent float64
// MemRSS is the Resident Set Size in bytes: the portion of memory
// currently held in RAM.
MemRSS int64
}
Metrics is a snapshot of resource usage for a running process.