compat

package module
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2025 License: MIT Imports: 13 Imported by: 0

README

compat

Build Last Commit Codecov Release go.mod Go Report Card Go Reference Known Vulnerabilities Keep a Changelog LICENSE

Overview

compat is a pure-Go library providing unified access to file and device metadata, atomic file operations, process priority, etc. on all major operating systems, include Andoid, iOS, Linux, macOS, Windows, and many others.

Usage

The documentation is available at https://pkg.go.dev/github.com/rasa/compat

Stat

Here's an example of calling compat.Stat():

package main

import (
  "fmt"
  "github.com/rasa/compat"
)

func main() {
  fi, err := compat.Stat(os.Executable())
  if err != nil {
    fmt.Println(err)
    return
  }
        // Same functions as os.Stat() and os.Lstat():
  fmt.Printf("Name()    =%v\n", fi.Name())     // base name of the file
  fmt.Printf("Size()    =%v\n", fi.Size())     // length in bytes
  fmt.Printf("Mode()    =0o%o\n", fi.Mode())   // file mode bits
  fmt.Printf("ModTime() =%v\n", fi.ModTime())  // last modified
  fmt.Printf("IsDir()   =%v\n", fi.IsDir())    // is a directory
  fmt.Printf("Sys()     =%+v\n", fi.Sys())     // underlying data source
        // New functions provided by this compat library:
  fmt.Printf("PartID()  =%v\n", fi.PartitionID()) // partition (device) ID
  fmt.Printf("FileID()  =%v\n", fi.FileID())   // file (inode) ID
  fmt.Printf("Links()   =%v\n", fi.Links())    // number of hard links
  fmt.Printf("ATime()   =%v\n", fi.ATime())    // last accessed
  fmt.Printf("BTime()   =%v\n", fi.BTime())    // created (birthed)
  fmt.Printf("CTime()   =%v\n", fi.CTime())    // status/metadata changed
  fmt.Printf("MTime()   =%v\n", fi.MTime())    // alias for ModTime
  fmt.Printf("UID()     =%v\n", fi.UID())      // user ID
  fmt.Printf("GID()     =%v\n", fi.GID())      // group ID
}

which, on Linux, produced:

Name()    =cmd
Size()    =1597624
Mode()    =0o775
ModTime() =2025-05-08 22:11:01.353744514 -0700 PDT
IsDir()   =false
Sys()     =&{Dev:64512 Ino:56893266 Nlink:1 Mode:33277 Uid:1000 Gid:1000 X__pad0:0 Rdev:0 Size:1597624 Blksize:4096 Blocks:3128 Atim:{Sec:1746767461 Nsec:354744521} Mtim:{Sec:1746767461 Nsec:353744514} Ctim:{Sec:1746767461 Nsec:353744514} X__unused:[0 0 0]}
PartID()  =64512
FileID()  =56893266
Links()   =1
ATime()   =2025-05-08 22:11:01.354744521 -0700 PDT
BTime()   =0001-01-01 00:00:00 +0000 UTC
CTime()   =2025-05-08 22:11:01.353744514 -0700 PDT
MTime()   =2025-05-08 22:11:01.353744514 -0700 PDT
UID()     =1000
GID()     =1000

Installing

To install compat, use go get:

go get github.com/rasa/compat

FileInfo Functions

The Stat() and Lstat() functions return a FileInfo object. The table below lists the operating system support for each of the FileInfo functions:

OS PartitionID()/
FileID()*
Links()* ATime()* BTime()* CTime()* UID()* /
GID()*
AIX
Android
Dragonfly ✖️
FreeBSD
Illumos ✖️
iOS
Js/
WASM
Linux
macOS
NetBSD
OpenBSD ✖️
Plan9 ☑️
Solaris ✖️
Wasip1/
WASM
Windows ✅†

* Support will depend on the underlying file system. See Comparison of file systems for details. † Uses the same logic as in Cygwin/MSYS2 to map Windows SIDs to UIDs/GIDs.

✅ fully supported.
☑️ the UID() and GID() values are 64-bit hashes of the user and group names.
✖️ not implemented (but it appears the OS supports it, so we could add support).
❌ not implemented (as it appears the OS doesn't support it).

Other Functions

All other functions provided by this library are fully supported by all the above operating systems.

Contributing

Please feel free to submit issues, fork the repository and send pull requests!

License

This project is MIT licensed.

Documentation

Overview

package compat is a pure-Go library providing unified access to file and device metadata, atomic file operations, process priority, etc. on all major operating systems, include Windows, Linux, macOS, Android, iOS, and many others.

Index

Constants

View Source
const (
	// CreatePerm is the FileMode used by Create().
	CreatePerm os.FileMode = 0o666
	// CreateTempPerm is the FileMode used by CreateTemp().
	CreateTempPerm os.FileMode = 0o600
	// MkdirTempPerm is the FileMode used by MkdirTemp()..
	MkdirTempPerm os.FileMode = 0o700

	O_RDONLY = os.O_RDONLY // open the file read-only.
	O_WRONLY = os.O_WRONLY // open the file write-only.
	O_RDWR   = os.O_RDWR   // open the file read-write.
	// The remaining values may be or'ed in to control behavior.
	O_APPEND = os.O_APPEND // append data to the file when writing.
	O_CREATE = os.O_CREATE // create a new file if none exists.
	O_EXCL   = os.O_EXCL   // used with O_CREATE, file must not exist.
	O_SYNC   = os.O_SYNC   // open for synchronous I/O.
	O_TRUNC  = os.O_TRUNC  // truncate regular writable file when opened.
	// O_DELETE added by this library.
	O_DELETE = 0x40000000 // delete file on close

	ModeDir        = fs.ModeDir        // d: is a directory
	ModeAppend     = fs.ModeAppend     // a: append-only
	ModeExclusive  = fs.ModeExclusive  // l: exclusive use
	ModeTemporary  = fs.ModeTemporary  // T: temporary file; Plan 9 only
	ModeSymlink    = fs.ModeSymlink    // L: symbolic link
	ModeDevice     = fs.ModeDevice     // D: device file
	ModeNamedPipe  = fs.ModeNamedPipe  // p: named pipe (FIFO)
	ModeSocket     = fs.ModeSocket     // S: Unix domain socket
	ModeSetuid     = fs.ModeSetuid     // u: setuid
	ModeSetgid     = fs.ModeSetgid     // g: setgid
	ModeCharDevice = fs.ModeCharDevice // c: Unix character device, when ModeDevice is set
	ModeSticky     = fs.ModeSticky     // t: sticky
	ModeIrregular  = fs.ModeIrregular  // ?: non-regular file; nothing else is known about this file

	// Mask for the type bits. For regular files, none will be set.
	ModeType = fs.ModeType

	ModePerm = fs.ModePerm // Unix permission bits, 0o777
)
View Source
const (
	// MaxNice is the maximum value returned by Nice().
	MaxNice = 19
	// MinNice is the minimum value returned by Nice().
	MinNice = -20
)
View Source
const (
	IsAIX       = runtime.GOOS == _aix
	IsAndroid   = runtime.GOOS == _android
	IsDarwin    = runtime.GOOS == _darwin
	IsDragonfly = runtime.GOOS == _dragonfly
	IsFreeBSD   = runtime.GOOS == _freebsd
	IsIllumos   = runtime.GOOS == _illumos
	IsIOS       = runtime.GOOS == _ios
	IsJS        = runtime.GOOS == _js
	IsLinux     = runtime.GOOS == _linux
	IsNetBSD    = runtime.GOOS == _netbsd
	IsOpenBSD   = runtime.GOOS == _openbsd
	IsPlan9     = runtime.GOOS == _plan9
	IsSolaris   = runtime.GOOS == _solaris
	IsWasip1    = runtime.GOOS == _wasip1
	IsWindows   = runtime.GOOS == _windows
)
View Source
const (
	Is386      = runtime.GOARCH == _386
	IsAmd64    = runtime.GOARCH == _amd64
	IsArm      = runtime.GOARCH == _arm
	IsArm64    = runtime.GOARCH == _arm64
	IsLoong64  = runtime.GOARCH == _loong64
	IsMips     = runtime.GOARCH == _mips
	IsMips64   = runtime.GOARCH == _mips64
	IsMips64le = runtime.GOARCH == _mips64le
	IsMipsle   = runtime.GOARCH == _mipsle
	IsPpc64    = runtime.GOARCH == _ppc64
	IsPpc64le  = runtime.GOARCH == _ppc64le
	IsRiscv64  = runtime.GOARCH == _riscv64
	IsS390x    = runtime.GOARCH == _s390x
	IsWasm     = runtime.GOARCH == _wasm
)

Variables

This section is empty.

Functions

func BuildBits added in v0.4.1

func BuildBits() int

BuildBits returns the number of bits in an integer on the build target. For 386, arm, mips, and mipsle, it's 32. For all other targets, it's 64.

func CPUBits added in v0.4.1

func CPUBits() (int, error)

CPUBits returns the number of bits in an integer on the CPU. Currently, on plan9, and wasm, zero is returned.

func Chmod added in v0.4.1

func Chmod(name string, mode os.FileMode) error

Chmod changes the mode of the named file to mode. If the file is a symbolic link, it changes the mode of the link's target. If there is an error, it will be of type [*PathError].

A different subset of the mode bits are used, depending on the operating system.

On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and ModeSticky are used.

On Windows, the mode's permission bits are used to set the appropriate ACL entries.

In addition, the 0o200 bit (owner writable) is used to control whether the file's read-only attribute is set or cleared. For compatibility with Go 1.12 and earlier, use a non-zero mode.

On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive, and ModeTemporary are used.

func Create added in v0.4.1

func Create(name string) (*os.File, error)

Create creates or truncates the named file. If the file already exists, it is truncated. If the file does not exist, it is created with mode 0o666 (before umask). If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. The directory containing the file must already exist. If there is an error, it will be of type [*PathError].

func CreateEx added in v0.4.1

func CreateEx(name string, perm os.FileMode, flag int) (*os.File, error)

CreateEx creates or truncates the named file. It creates the named file with specified flag (O_RDONLY etc.). If the file already exists, it is truncated. If the file does not exist, it is create using the perm's permission bits (before umask). If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. The directory containing the file must already exist. If there is an error, it will be of type [*PathError].

func CreateTemp added in v0.4.1

func CreateTemp(dir, pattern string) (*os.File, error)

CreateTemp creates a new temporary file in the directory dir, opens the file for reading and writing, and returns the resulting file. The filename is generated by taking pattern and adding a random string to the end. If pattern includes a "*", the random string replaces the last "*". The file is created with mode 0o600 (before umask). If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by [TempDir]. Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file. The caller can use the file's Name method to find the pathname of the file. It is the caller's responsibility to remove the file when it is no longer needed.

func CreateTempEx added in v0.4.1

func CreateTempEx(dir, pattern string, flag int) (*os.File, error)

CreateTempEx creates a new temporary file in the directory dir, opens the file for reading and writing, and returns the resulting file. It creates the named file with specified flag (O_RDONLY etc.). The filename is generated by taking pattern and adding a random string to the end. If pattern includes a "*", the random string replaces the last "*". The file is created with mode 0o600 (before umask). If dir is the empty string, CreateTempEx uses the default directory for temporary files, as returned by [TempDir]. Multiple programs or goroutines calling CreateTempEx simultaneously will not choose the same file. The caller can use the file's Name method to find the pathname of the file. It is the caller's responsibility to remove the file when it is no longer needed.

func GetUmask added in v0.4.1

func GetUmask() int

GetUmask returns the current umask value. On Plan9 and Wasip1, the function always returns zero.

func IsAdmin deprecated added in v0.3.0

func IsAdmin() (bool, error)

IsAdmin returns true if the user is root, or has Windows administrator rights.

Deprecated: Use IsRoot() instead.

func IsRoot added in v0.4.2

func IsRoot() (bool, error)

IsRoot returns true if the user is root, or has Windows administrator rights.

func IsWSL added in v0.3.0

func IsWSL() bool

IsWSL returns true if running under Windows Subsytem for Linux (WSL), otherwise false.

func Mkdir added in v0.4.1

func Mkdir(name string, perm os.FileMode) error

Mkdir creates a new directory with the specified name and perm's permission bits (before umask). If there is an error, it will be of type [*PathError].

func MkdirAll added in v0.4.1

func MkdirAll(path string, perm os.FileMode) error

MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The perm's permission bits (before umask) are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.

func MkdirTemp added in v0.4.1

func MkdirTemp(dir, pattern string) (string, error)

MkdirTemp creates a new temporary directory in the directory dir and returns the pathname of the new directory. The new directory's name is generated by adding a random string to the end of pattern. If pattern includes a "*", the random string replaces the last "*" instead. The directory is created with mode 0o700 (before umask). If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir. Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory. It is the caller's responsibility to remove the directory when it is no longer needed.

func Nice added in v0.2.0

func Nice() (int, error)

Nice gets the CPU process priority. The return value is in a range from -20 (least nice), to 19 (most nice), even on non-Unix systems such as Windows, plan9, etc. If not supported by the operating system, -1 is returned.

func OpenFile added in v0.4.1

func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)

OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with specified flag (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag is passed, it is created with perm's permission bits (before umask); the containing directory must exist. If successful, methods on the returned File can be used for I/O. If there is an error, it will be of type [*PathError].

func Rename added in v0.4.2

func Rename(source, destination string) error

Rename atomically replaces the destination file or directory with the source. It is guaranteed to either replace the target file entirely, or not change either file.

func Renice added in v0.2.0

func Renice(nice int) error

Renice sets the CPU process priority. The nice parameter can range from -20 (least nice), to 19 (most nice), even on non-Unix systems such as Windows, plan9, etc.

func ReplaceFile deprecated added in v0.4.2

func ReplaceFile(source, destination string) error

ReplaceFile atomically replaces the destination file or directory with the source. It is guaranteed to either replace the target file entirely, or not change either file.

Deprecated: Use Rename() instead.

func SameFile

func SameFile(fi1, fi2 FileInfo) bool

SameFile reports whether fi1 and fi2 describe the same file. For example, on Unix this means that the Partition and inode fields of the two underlying structures are identical; on other systems the decision may be based on the path names. SamePartition only applies to results returned by this package's Stat. It returns false in other cases.

func SameFiles

func SameFiles(name1, name2 string) bool

SameFiles reports whether name1 and name2 are the same file. The function follow symlinks.

func SamePartition added in v0.4.0

func SamePartition(fi1, fi2 FileInfo) bool

SamePartition reports whether fi1 and fi2 describe files on the same Partition. For example, on Unix this means that the Partition fields of the two underlying structures are identical; on other systems the decision may be based on the path names. SamePartition only applies to results returned by this package's Stat. It returns false in other cases.

func SamePartitions added in v0.4.0

func SamePartitions(name1, name2 string) bool

SamePartitions reports whether name1 and name2 are files on the same Partition. The function follow symlinks.

func Supports

func Supports(function SupportedType) bool

Supports returns whether function is supported by the operating system.

func Umask added in v0.4.1

func Umask(newMask int) int

Umask sets the umask to umask, and returns the previous value. On Windows, the initial umask value is 022 octal, and can be changed by setting environmental variable UMASK, to an octal value. For example: `set UMASK=022` . Leading zeros and 'o's are allowed, and ignored. On Plan9 and Wasip1, the function does nothing, and always returns zero.

func WriteFile added in v0.4.1

func WriteFile(name string, data []byte, perm os.FileMode) error

WriteFile writes data to the named file, creating it if necessary. If the file does not exist, WriteFile creates it using perm's permissions bits (before umask); otherwise WriteFile truncates it before writing, without changing permissions. Since WriteFile requires multiple system calls to complete, a failure mid-operation can leave the file in a partially written state.

func WriteFileAtomic added in v0.4.2

func WriteFileAtomic(filename string, data []byte, opts ...Option) (err error)

WriteFileAtomic atomically writes the contents of data to the specified filepath. If an error occurs, the target file is guaranteed to be either fully written, or not written at all. WriteFileAtomic overwrites any file that exists at the location (but only if the write fully succeeds, otherwise the existing file is unmodified). Additional option arguments can be used to change the default configuration for the target file.

func WriteFileEx added in v0.4.1

func WriteFileEx(name string, data []byte, perm os.FileMode, flag int) error

WriteFileEx writes data to the named file, creating it if necessary. It creates or opens the named file with specified flag (O_RDONLY etc.). If the file does not exist, WriteFileEx creates it with perm's permissions bits (before umask); otherwise WriteFile truncates or appends, without changing permissions. Since WriteFile requires multiple system calls to complete, a failure mid-operation can leave the file in a partially written state.

func WriteReaderAtomic added in v0.4.2

func WriteReaderAtomic(filename string, r io.Reader, opts ...Option) (err error)

WriteReaderAtomic atomically writes the contents of r to the specified filepath. If an error occurs, the target file is guaranteed to be either fully written, or not written at all. WriteReaderAtomic overwrites any file that exists at the location (but only if the write fully succeeds, otherwise the existing file is unmodified). Additional option arguments can be used to change the default configuration for the target file.

Types

type FileInfo

type FileInfo interface {
	Name() string        // base name of the file
	Size() int64         // length in bytes for regular files; system-dependent for others
	Mode() os.FileMode   // file mode bits
	ModTime() time.Time  // last modified time
	IsDir() bool         // abbreviation for Mode().IsDir()
	Sys() any            // underlying data source
	PartitionID() uint64 // unique disk partition ID
	FileID() uint64      // unique file ID (on a specific partition)
	Links() uint64       // number of hard links, or 0 if unsupported
	ATime() time.Time    // last accessed time, or 0 if unsupported
	BTime() time.Time    // created (birthed) time, or 0 if unsupported
	CTime() time.Time    // status/metadata changed time, or 0 if unsupported
	MTime() time.Time    // last modified time (alias)
	UID() uint64         // user ID, or 0 if unsupported
	GID() uint64         // group ID, or 0 if unsupported
}

A FileInfo describes a file and is returned by Stat. See https://github.com/golang/go/blob/ad7a6f81/src/io/fs/fs.go#L158

func Lstat

func Lstat(name string) (FileInfo, error)

Lstat returns a FileInfo describing the named file. If the file is a symbolic link, the returned FileInfo describes the symbolic link. Lstat makes no attempt to follow the link. If there is an error, it will be of type [*PathError].

On Windows, if the file is a reparse point that is a surrogate for another named entity (such as a symbolic link or mounted folder), the returned FileInfo describes the reparse point, and makes no attempt to resolve it.

func Stat

func Stat(name string) (FileInfo, error)

Stat returns a FileInfo describing the named file. If there is an error, it will be of type [*PathError].

type FileOptions added in v0.4.2

type FileOptions struct {
	// contains filtered or unexported fields
}

FileOptions define the behavior of `WriteReaderAtomic()`, etc.

type InvalidNiceError added in v0.2.0

type InvalidNiceError struct {
	// contains filtered or unexported fields
}

InvalidNiceError is returned when the niceness value passed by the user is invalid.

func (*InvalidNiceError) Error added in v0.2.0

func (e *InvalidNiceError) Error() string

type NiceError added in v0.2.0

type NiceError struct {
	// contains filtered or unexported fields
}

NiceError is returned when system call failed.

func (*NiceError) Error added in v0.2.0

func (e *NiceError) Error() string

type Option added in v0.4.2

type Option func(*FileOptions)

Option functions modify FileOptions.

func DefaultFileMode added in v0.4.2

func DefaultFileMode(mode os.FileMode) Option

DefaultFileMode sets the default file mode instead of using the `os.CreateTemp()` default of `0600`.

func FileMode added in v0.4.2

func FileMode(mode os.FileMode) Option

FileMode sets the file mode to the desired value and has precedence over all other options.

func KeepFileMode added in v0.4.2

func KeepFileMode(keep bool) Option

KeepFileMode preserves the file mode of an existing file instead of using the default value.

type ReniceError added in v0.2.0

type ReniceError struct {
	// contains filtered or unexported fields
}

ReniceError is returned when the system failed to set the OS's niceness level.

func (*ReniceError) Error added in v0.2.0

func (e *ReniceError) Error() string

type SupportedType added in v0.2.0

type SupportedType uint

SupportedType defines a bitmask that identifies if the OS supports specific fields, or not.

const (
	// Links defines if FileInfo's Links() function is supported by the OS.
	// Links() returns the number of hard links to the file.
	Links SupportedType = 1 << iota
	// ATime defines if FileInfo's ATime() function is supported by the OS.
	// ATime() returns the time the file was last accessed.
	ATime
	// BTime defines if FileInfo's BTime() function is supported by the OS.
	// BTime() returns the time the file was created (or "birthed").
	BTime
	// CTime defines if FileInfo's CTime() function is supported by the OS.
	// CTime() returns the time the file's status/metadata was last changed.
	CTime
	// UID defines if FileInfo's UID() function is supported by the OS.
	// UID() returns the user ID of the file's owner.
	UID
	// GID defines if FileInfo's GID() function is supported by the OS.
	// GID() returns the group ID of the file's group.
	GID
	// UnknownID is returned when the UID or GID could not be determined.
	UnknownID = ^uint64(0)
)

Directories

Path Synopsis
cmd
demo command
demo is a sample application that runs functions provided by this library.
demo is a sample application that runs functions provided by this library.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL