Low-level operating system primitives for Go programs.
The golang.org/x/sys repository holds supplemental Go packages for low-level interactions with the operating system. It provides access to system calls, OS-specific functionality, and CPU feature detection across different platforms.
This package is particularly useful for:
import (
"golang.org/x/sys/cpu" // CPU feature detection
"golang.org/x/sys/execabs" // Secure command execution
"golang.org/x/sys/plan9" // Plan 9 system calls
"golang.org/x/sys/unix" // Unix/Linux system calls
"golang.org/x/sys/windows" // Windows system calls
)The repository contains five main packages:
Import: golang.org/x/sys/cpu
Implements processor feature detection for various CPU architectures including x86/AMD64, ARM/ARM64, PowerPC, RISC-V, s390x, MIPS, and LoongArch.
Key Features:
Import: golang.org/x/sys/execabs
A drop-in replacement for os/exec that requires PATH lookups to find absolute paths, preventing execution of programs from the current directory.
Key Features:
Import: golang.org/x/sys/plan9
Provides low-level access to Plan 9 operating system primitives, including file operations, process management, and namespace manipulation using Plan 9's unique bind and mount semantics.
Key Features:
Import: golang.org/x/sys/unix
Provides low-level access to Unix and Linux system calls, supporting multiple Unix-like operating systems including Linux, FreeBSD, macOS, OpenBSD, NetBSD, and Solaris.
Key Features:
Import: golang.org/x/sys/windows
Contains an interface to the low-level Windows operating system primitives, wrapping the Windows API for Go programs.
Key Features:
The cpu package allows runtime detection of processor capabilities:
package main
import (
"fmt"
"golang.org/x/sys/cpu"
)
func main() {
if cpu.X86.HasAVX2 {
fmt.Println("AVX2 available - using optimized code path")
}
if cpu.ARM64.HasNEON {
fmt.Println("NEON available - using SIMD acceleration")
}
}Supported Architectures:
Learn more about CPU detection →
The execabs package provides secure alternatives to os/exec:
package main
import (
"log"
"golang.org/x/sys/execabs"
)
func main() {
// Secure: will not execute from current directory
cmd := execabs.Command("git", "status")
output, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(output))
}Security Benefits:
Learn more about secure execution →
The plan9 package provides access to Plan 9 operating system primitives:
package main
import (
"fmt"
"golang.org/x/sys/plan9"
)
func main() {
// Open file
fd, err := plan9.Open("/lib/namespace", plan9.O_RDONLY)
if err != nil {
panic(err)
}
defer plan9.Close(fd)
// Read with system call
buf := make([]byte, 1024)
n, err := plan9.Read(fd, buf)
if err != nil {
panic(err)
}
fmt.Printf("Read %d bytes\n", n)
}Major Capabilities:
Learn more about Plan 9 system calls →
The unix package provides comprehensive Unix/Linux system call access:
package main
import (
"fmt"
"golang.org/x/sys/unix"
)
func main() {
// Open file
fd, err := unix.Open("/etc/hosts", unix.O_RDONLY, 0)
if err != nil {
panic(err)
}
defer unix.Close(fd)
// Read with system call
buf := make([]byte, 1024)
n, err := unix.Read(fd, buf)
if err != nil {
panic(err)
}
fmt.Printf("Read %d bytes\n", n)
}Major Capabilities:
Learn more about Unix system calls →
The windows package provides comprehensive Windows API access:
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
// Get current user
token, err := windows.OpenCurrentProcessToken()
if err != nil {
panic(err)
}
defer token.Close()
user, err := token.GetTokenUser()
if err != nil {
panic(err)
}
account, domain, _, err := user.User.Sid.LookupAccount("")
if err != nil {
panic(err)
}
fmt.Printf("User: %s\\%s\n", domain, account)
}Major Capabilities:
Learn more about Windows system calls →
go get golang.org/x/sysUse build tags to write platform-specific code:
//go:build linux
// +build linux
package mypackage
import "golang.org/x/sys/unix"
func platformSpecific() {
// Linux-specific code using unix package
unix.Sync()
}//go:build windows
// +build windows
package mypackage
import "golang.org/x/sys/windows"
func platformSpecific() {
// Windows-specific code using windows package
windows.FlushFileBuffers(handle)
}Build cross-platform functionality using both packages:
package mypackage
import (
"runtime"
"golang.org/x/sys/plan9"
"golang.org/x/sys/unix"
"golang.org/x/sys/windows"
)
func GetProcessID() uint32 {
switch runtime.GOOS {
case "linux", "darwin", "freebsd":
return uint32(unix.Getpid())
case "windows":
return windows.GetCurrentProcessId()
case "plan9":
return uint32(plan9.Getpid())
default:
return 0
}
}IsBigEndianCacheLinePadErrNotFoundCommand, CommandContext, LookPathCmd, Error, ExitError (aliases)execabs instead of os/exec for security-critical applicationsBoth unix and windows packages use errno-style error handling:
fd, err := unix.Open(path, unix.O_RDONLY, 0)
if err != nil {
if err == unix.ENOENT {
// File not found
} else if err == unix.EACCES {
// Permission denied
}
return err
}
defer unix.Close(fd)Always use defer for cleanup:
// Unix
fd, err := unix.Open(path, unix.O_RDONLY, 0)
if err != nil {
return err
}
defer unix.Close(fd)
// Windows
handle, err := windows.CreateFile(...)
if err != nil {
return err
}
defer windows.CloseHandle(handle)// Go strings are already UTF-8
fd, err := unix.Open("/etc/hosts", unix.O_RDONLY, 0)// Convert to UTF-16
filename, err := windows.UTF16PtrFromString("C:\\test.txt")
if err != nil {
return err
}
handle, err := windows.CreateFile(filename, ...)Use Higher-Level Packages When Possible: Prefer os, net, and time packages for portable code
Platform-Specific Code: Use build tags to separate platform-specific implementations
Error Handling: Always check and handle errors from system calls
Resource Cleanup: Use defer to ensure handles and file descriptors are closed
Buffer Management: Pre-allocate buffers of appropriate size and reuse when possible
Security: Follow principle of least privilege for capabilities, tokens, and permissions
Testing: Test platform-specific code on actual target platforms
Documentation: Refer to OS documentation (man pages, MSDN) for detailed behavior
All major architectures: x86/AMD64, ARM/ARM64, PowerPC64, RISC-V, s390x, MIPS, LoongArch
The golang.org/x/sys packages are intended to replace the frozen syscall package from the standard library:
// Old (syscall package - frozen)
import "syscall"
fd, err := syscall.Open("/etc/hosts", syscall.O_RDONLY, 0)
// New (golang.org/x/sys/unix - actively maintained)
import "golang.org/x/sys/unix"
fd, err := unix.Open("/etc/hosts", unix.O_RDONLY, 0)Benefits of migration:
The golang.org/x/sys repository is part of the Go project:
Contributions must follow the Go contribution guidelines.
BSD-3-Clause License