package internal import ( `bytes` `errors` `fmt` `os` "runtime" "strconv" "strings" `r00t2.io/sysutils/paths` ) // EnvListToMap splits a []string of env var keypairs to a map. func EnvListToMap(envs []string) (envMap map[string]string) { var kv []string var k, v string envMap = make(map[string]string) for _, ev := range envs { kv = strings.SplitN(ev, "=", 2) // I *think* SplitN does this for me, but... if len(kv) == 1 { kv = append(kv, "") } k = kv[0] v = kv[1] envMap[k] = v } return } // GetPathEnv returns a slice of the PATH variable's items. func GetPathEnv() (pathList []string, err error) { var pathVar string = GetPathEnvName() pathList = make([]string, 0) for _, p := range strings.Split(os.Getenv(pathVar), string(os.PathListSeparator)) { if err = paths.RealPath(&p); err != nil { return } pathList = append(pathList, p) } return } /* GetPidEnvMap will only work on *NIX-like systems with procfs. It gets the environment variables of a given process' PID. */ func GetPidEnvMap(pid uint32) (envMap map[string]string, err error) { var envBytes []byte var envList []string var envArr [][]byte var procPath string var exists bool envMap = make(map[string]string) procPath = fmt.Sprintf("/proc/%v/environ", pid) if exists, err = paths.RealPathExists(&procPath); err != nil { return } if !exists { err = errors.New(fmt.Sprintf("information for pid %v does not exist", pid)) return } if envBytes, err = os.ReadFile(procPath); err != nil { return } envArr = bytes.Split(envBytes, []byte{0x0}) envList = make([]string, len(envArr)) for idx, b := range envArr { envList[idx] = string(b) } envMap = EnvListToMap(envList) return } // GetPathEnvName gets the OS-specific path environment variable name. func GetPathEnvName() (envVarName string) { var ok bool if envVarName, ok = pathEnvVarName[runtime.GOOS]; !ok { // *NIX/the default. envVarName = "PATH" } return } // NativizeEnvMap returns a native-typed env map from a string version. func NativizeEnvMap(stringMap map[string]string) (envMap map[string]interface{}) { var pathVar string = GetPathEnvName() var err error envMap = make(map[string]interface{}) for k, v := range stringMap { // Check for PATH/Path - we handle this uniquely. if k == pathVar { if envMap[k], err = GetPathEnv(); err != nil { envMap[k] = v err = nil } continue } // It might be... // a float if reMaybeFloat.MatchString(v) { if envMap[k], err = strconv.ParseFloat(v, 64); err == nil { continue } err = nil } // an int if reMaybeInt.MatchString(v) { if envMap[k], err = strconv.Atoi(v); err == nil { continue } err = nil } // a uint if envMap[k], err = strconv.ParseUint(v, 10, 64); err == nil { continue } else { err = nil } // a boolean if envMap[k], err = strconv.ParseBool(v); err == nil { continue } else { err = nil } // ok so... guess it's a string, then. envMap[k] = v } return }