starainrt d93a851d1b
feat: 完善 staros 系统能力并更新 wincmd 发布版依赖
- 重构 sysconf 为文档模型 INI Parser 与 Config Framework
- 强化 hosts 解析、插入校验、写回与异常输入处理
- 完善 StarCmd 生命周期、等待 API、流式输出与 IO 重定向
- 扩展跨平台文件时间、文件锁、内存、进程与网络能力
- 将 Windows 进程适配更新到 b612.me/wincmd v0.1.0
- 移除本地 wincmd/win32api replace,改用发布版依赖
- 将最低 Go 版本提升到 1.18
- 补充 hosts、sysconf、FileLock、StarCmd 与平台适配回归测试
2026-06-09 18:10:19 +08:00
2021-07-07 10:39:07 +08:00
2022-01-04 14:18:38 +08:00
2022-01-04 14:18:38 +08:00
2022-01-04 14:18:38 +08:00
2022-01-04 14:18:38 +08:00
2020-02-11 10:53:25 +08:00
2021-06-04 10:44:53 +08:00

staros

staros is a cgo-free Go package for small cross-platform OS utilities.

The package keeps compatibility with existing APIs, but platform-dependent functions should prefer explicit error-returning variants where available. Unsupported platform implementations return ERR_UNSUPPORTED instead of silently pretending to work.

Go Version

go.mod declares go 1.18. This release targets Go 1.18 or newer and no longer promises Go 1.16/1.17 compatibility. The release gate includes the current local Go toolchain plus cross-platform compile checks.

Platform Support

Area Linux Windows Darwin
Basic path checks: Exists, IsFile, IsFolder Supported Supported Supported
File locks: FileLock flock Win32 lock API flock
File timestamps: GetFileCreationTime, GetFileAccessTime, SetFileTimesE ctime/access/modtime via x/sys/unix creation/access/modtime via x/sys/windows birth/access/modtime via stdlib/syscall
Memory: Memory /proc and syscall.Sysinfo Win32 GlobalMemoryStatusEx vm_stat and sysctl
Disk: DiskUsageE Statfs GetDiskFreeSpaceExW Statfs
OS identity: IsRoot, Whoami Supported IsRoot supported, Whoami returns ERR_UNSUPPORTED Supported
CPU usage: CpuUsage, CpuUsageByPid /proc/stat and /proc/<pid>/stat Stub returns 0 Stub returns 0
Process query: FindProcess* /proc backed wincmd backed basic fields Returns ERR_UNSUPPORTED
Process launch: Command, CommandContext, Start Supported Supported Supported
Process lifecycle: ReleaseE Starts through normal lifecycle with Setsid Starts through normal lifecycle Returns ERR_UNSUPPORTED
Process detach: DetachE Start-before-Start only, then Process.Release Start-before-Start only, then Process.Release Returns ERR_UNSUPPORTED
Run as user: SetRunUserE, DaemonWithUser Supported Returns ERR_UNSUPPORTED Returns ERR_UNSUPPORTED
Keep capabilities: SetKeepCaps, StarCmd.SetKeepCaps Package helper uses Linux prctl; command helper preserves current caps via AmbientCaps Returns ERR_UNSUPPORTED Returns ERR_UNSUPPORTED
Network adapters/speeds/connections /proc/net backed IP Helper adapter counters and TCP/UDP owner-pid tables; no Unix socket/inode fields Returns ERR_UNSUPPORTED
Beep PC speaker or terminal bell fallback Win32 Beep osascript or terminal bell fallback

API Semantics

  • ERR_UNSUPPORTED means the symbol exists for build compatibility but the current OS implementation is intentionally unavailable.
  • ReleaseE preserves StarCmd lifecycle observation: Stopped() still closes after the process exits and ExitCode() is populated when available. The historical misspelled Stoped() method remains as a deprecated compatibility alias.
  • DetachE is a true detached start path and must be called before Start; calling it after Start returns an already-started error to avoid racing Process.Release() with the internal Wait().
  • Wait, WaitContext, and WaitTimeout provide explicit lifecycle wait helpers that return the final process wait error. Stopped() remains available when callers only need a close signal.
  • On Linux, the package-level SetKeepCaps() helper applies prctl(PR_SET_KEEPCAPS) to the current process. StarCmd.SetKeepCaps() is different: it snapshots the current capability set and configures the child command's SysProcAttr.AmbientCaps before Start.
  • StdoutChan, StderrChan, and OutputChan provide best-effort streaming observation for future output chunks. They close with Stopped() and do not replace the existing full-output capture methods.
  • RedirectStdout, RedirectStderr, RedirectOutput, and RedirectStdin configure process IO before Start. File helpers such as RedirectStdoutFile and RedirectStdinFile open the file and close it after the process reaches its final state.
  • WriteStdinE and WriteStdinStringE write raw stdin data without appending a newline. WriteStdinLineE and the legacy WriteCmdE append one newline.
  • Legacy methods that do not return errors are kept for compatibility; prefer the *E variants for new code.

sysconf Migration

The sysconf package now uses a document-backed INI model instead of the old SysConf struct shape. This is a breaking API change: callers should migrate to NewIni, NewLinuxConf, Document, Section, and Entry directly instead of relying on a field-compatible wrapper.

Minimal migration rules:

  • Replace parser setup through SysConf fields with constructors: use sysconf.NewIni() for sectioned INI files, or sysconf.NewLinuxConf(equal) for flat Linux-style config files.
  • Replace direct segment/key data mutation with section methods: ini.Section(name), ini.Set(section, key, value), sec.Set, sec.SetAll, sec.AddValue, sec.Delete, and ini.DeleteSection.
  • Replace single-value assumptions with duplicate-aware reads where needed: ini.Get/sec.Get returns the first value, while ini.GetAll/sec.GetAll returns all repeated keys.
  • Replace manual struct binding with ini.Unmarshal(&dst) and ini.Marshal(src) using seg and key tags.
  • Use ini.Build() or ini.Save(path) for write-back. Unchanged parsed lines keep their original formatting, while changed entries are rebuilt from the new model.

Example:

ini := sysconf.NewIni()
if err := ini.Parse(data); err != nil {
	return err
}

app := ini.Section("app")
if app == nil {
	app = ini.AddSection("app")
}
_ = app.SetInt("port", 9090, "")
_ = app.SetAll("feature", []string{"stable", "audit"}, "")

out := ini.Build()

INI parser capabilities:

  • NewIni() parses common sectioned INI files with = and : key/value delimiters, # and ; comments, section header comments, quoted values, no-value keys, duplicate keys, duplicate sections, and backslash line continuation.
  • Inline comments require whitespace before the comment marker, so values such as URLs or fragments containing # are not truncated accidentally.
  • NewIniWithProfiles(...), StrictINIProfile(), and LinuxConfProfile(equal) let callers pin parser behavior for strict sectioned INI or flat Linux-style config files without mutating parser fields ad hoc.
  • Document.Strict can be enabled when callers want malformed input to return a ParseError with line and column information instead of preserving unknown lines as raw content.
  • Write-back is lossless for unchanged parsed lines. Changed values that would otherwise be misread as comments, leading/trailing whitespace, tabs, or newlines are emitted as quoted values.

Config framework capabilities:

  • sysconf.NewConfig(), sysconf.LoadConfig(&dst, files, ...), and sysconf.LoadConfigSources(&dst, sources, ...) load one or more INI sources in order; later sources override earlier values for the same section/key.
  • sysconf.RequiredFile(path) and sysconf.OptionalFile(path) declare whether a missing file should fail loading or be skipped. sysconf.BytesSource(name, data) and sysconf.StringSource(name, data) support in-memory overlays for tests, generated defaults, and embedded configs.
  • Config exposes direct access and write-back helpers: Get, GetAll, error-returning typed getters such as GetIntE / GetBoolE / GetDurationE, Has, Set, SetAll, Delete, Build, Save, and SaveAtomic.
  • Struct binding uses seg, key, default, env, split, and required tags. Nested structs inherit their parent seg tag, while env:"-" disables environment overrides for a field.
  • Environment overrides are opt-in through WithEnvPrefix / WithEnvLookup; generated names normalize section and key names to uppercase underscore form, such as APP_SERVER_PORT.
  • Binding supports strings, bools, signed/unsigned integers, floats, time.Duration, encoding.TextUnmarshaler, slices, arrays, and map[string]T for scalar T.
  • Repeated INI keys bind naturally to slices. When a single value should expand into multiple collection items, add an explicit split tag such as split:",", split:"|", or split:"csv".
  • Config.SetStruct(src) writes a config struct back into the current document, using repeated keys for slices/arrays and sorted key=value repeated entries for maps.
  • sysconf.DescribeConfig(src) exports struct tag metadata as ConfigFieldInfo records, and sysconf.SampleConfig(src) builds a sample INI from defaults, current struct values, required placeholders, or type zero values without mutating the source struct.
  • Config.SectionNames(), Config.Keys(section), Config.Flatten(), and Config.FlattenEntries() expose sorted section/key discovery, duplicate-aware flattened values, and structured section/key/value entries for diagnostics, tests, and lightweight config export.
  • ConfigError and ConfigSourceError include structured metadata and unwrap their underlying parse, file, or conversion errors for errors.Is / errors.As.
  • A config struct can implement Validate() error; validation runs after defaults, file values, env overrides, required checks, and type binding.

Example:

type AppConfig struct {
	App struct {
		Name    string        `key:"name" required:"true"`
		Port    int           `key:"port" default:"8080"`
		Timeout time.Duration `key:"timeout" default:"5s"`
		Tags    []string      `key:"tag" env:"APP_TAGS"`
	} `seg:"app"`
}

var cfg AppConfig
_, err := sysconf.LoadConfigSources(&cfg, []sysconf.ConfigSource{
	sysconf.RequiredFile("/etc/app.ini"),
	sysconf.OptionalFile("/etc/app.local.ini"),
}, sysconf.WithEnvPrefix("APP"))

The current framework is intentionally local-file focused. It does not include hot reload, remote configuration centers, secret managers, or a schema DSL.

Scope

This package is intentionally small and cgo-free. Functionality that duplicates broad system inventory packages should stay frozen unless it improves cross-platform semantics, error observability, or compatibility for existing callers.

Description
No description provided
Readme 215 KiB
v1.2.0 Latest
2026-06-09 18:11:13 +08:00
Languages
Go 100%