From 558cf384ea0540bff82abd2d0c4d2963d69762dc Mon Sep 17 00:00:00 2001 From: brent s Date: Wed, 31 Mar 2021 15:18:42 -0400 Subject: [PATCH 1/4] quick TODO --- paths/TODO | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 paths/TODO diff --git a/paths/TODO b/paths/TODO new file mode 100644 index 0000000..ae16fb1 --- /dev/null +++ b/paths/TODO @@ -0,0 +1,8 @@ +https://golangcode.com/check-if-a-file-exists/ + +E.G. +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } From dec40965a1f60705102f8b21d3fafdb72bb8b0c4 Mon Sep 17 00:00:00 2001 From: brent s Date: Wed, 31 Mar 2021 17:18:06 -0400 Subject: [PATCH 2/4] do it better --- paths/TODO | 8 ---- paths/func.go | 109 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 78 insertions(+), 39 deletions(-) delete mode 100644 paths/TODO diff --git a/paths/TODO b/paths/TODO deleted file mode 100644 index ae16fb1..0000000 --- a/paths/TODO +++ /dev/null @@ -1,8 +0,0 @@ -https://golangcode.com/check-if-a-file-exists/ - -E.G. -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false - } diff --git a/paths/func.go b/paths/func.go index 5bcde7c..ba22790 100644 --- a/paths/func.go +++ b/paths/func.go @@ -19,8 +19,10 @@ package paths import ( + "bytes" "errors" "fmt" + "io/ioutil" "os" "os/user" "path/filepath" @@ -31,37 +33,75 @@ import ( var err error -func ExpandHome(path *string) error { +func ExpandHome(path *string) (err error) { // Props to this guy. // https://stackoverflow.com/a/43578461/733214 if len(*path) == 0 { return errors.New("empty path") } else if (*path)[0] != '~' { - return nil + return } // E(ffective)UID (e.g. chown'd user for SUID) /* - uid := strconv.Itoa(syscall.Geteuid()) - usr, err := user.LookupId(euid) + uid := strconv.Itoa(syscall.Geteuid()) + usr, err := user.LookupId(euid) */ // R(real)UID (invoking user) usr, err := user.Current() if err != nil { - return err + return } *path = filepath.Join(usr.HomeDir, (*path)[1:]) - return nil + return } -func GetPathEnv() ([]string, error) { - paths := []string{} +func GetPathEnv() (s []string, err error) { + s = make([]string, 0) for _, p := range strings.Split(os.Getenv("PATH"), ":") { if err = RealPath(&p); err != nil { - return nil, err + return } - paths = append(paths, p) + s = append(s, p) } - return paths, nil + + return +} + +func GetEnvPid(pid uint32) (env map[string]string, err error) { + + var envBytes []byte + var envArr [][]byte + var procPath string + var exists bool + + env = make(map[string]string) + + procPath = fmt.Sprintf("/proc/%v/environ", pid) + + if exists, err = RealPathExists(&procPath); err != nil { + return + } + if !exists { + err = errors.New(fmt.Sprintf("information for pid %v does not exist", pid)) + } + if envBytes, err = ioutil.ReadFile(procPath); err != nil { + return + } + + envArr = bytes.Split(envBytes, []byte{0x0}) + for _, b := range envArr { + // s := strings.TrimSpace(string(b)) + s := string(b) + e := strings.SplitN(s, "=", 2) + for _, i := range e { + if len(i) != 2 { + continue + } + env[string(i[0])] = string(i[1]) + } + } + + return } func MakeDirIfNotExist(path *string) error { @@ -97,31 +137,38 @@ func RealPath(path *string) error { return nil } -func RealPathExists(path *string) (bool, error) { - // I know it's hacky, but we use the bool as a sort of proto-state-machine thing. - // If err != nil and bool is true, the error occurred during path absolution. - // If err != nil and bool is false, the path does not exist. - err := RealPath(path) - if err != nil { - return true, err +func RealPathExists(path *string) (exists bool, err error) { + if err = RealPath(path); err != nil { + return } if _, err := os.Stat(*path); err != nil { - return false, err + if os.IsNotExist(err) { + exists = false + err = nil + } else { + return + } + } else { + exists = true } - return true, nil + + return } -func RealPathExistsStat(path *string) (bool, os.FileInfo, error) { - // Same deal as RealPathExists. - // If err != nil and bool is true, the error occurred during path absolution. - // If err != nil and bool is false, the path does not exist. - err := RealPath(path) - if err != nil { - return true, nil, err +func RealPathExistsStat(path *string) (exists bool, stat os.FileInfo, err error) { + if err = RealPath(path); err != nil { + return } - stat, err := os.Stat(*path) - if err != nil { - return false, nil, err + if stat, err = os.Stat(*path); err != nil { + if os.IsNotExist(err) { + exists = false + err = nil + } else { + return + } + } else { + exists = true } - return true, stat, nil + + return } From ede17f2eda2a00466131cb4cc73d60d2d8ed895c Mon Sep 17 00:00:00 2001 From: brent s Date: Wed, 31 Mar 2021 18:20:52 -0400 Subject: [PATCH 3/4] do it better and *make it work* --- paths/func.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paths/func.go b/paths/func.go index ba22790..b1b1e12 100644 --- a/paths/func.go +++ b/paths/func.go @@ -141,7 +141,7 @@ func RealPathExists(path *string) (exists bool, err error) { if err = RealPath(path); err != nil { return } - if _, err := os.Stat(*path); err != nil { + if _, err = os.Stat(*path); err != nil { if os.IsNotExist(err) { exists = false err = nil From fbf1049fd2857e864f71148290a34d5bcb729c69 Mon Sep 17 00:00:00 2001 From: brent s Date: Tue, 27 Apr 2021 04:37:17 -0400 Subject: [PATCH 4/4] adding equivalent of os.isatty --- terminal/funcs.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 terminal/funcs.go diff --git a/terminal/funcs.go b/terminal/funcs.go new file mode 100644 index 0000000..68b7119 --- /dev/null +++ b/terminal/funcs.go @@ -0,0 +1,40 @@ +/* + SysUtils - a library to assist with various system-related functions + Copyright (C) 2020 Brent Saner + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +package terminal + +import ( + "os" + "fmt" +) + +// IsShell returns true if the program is running inside an interactive shell (interactive invocation, sudo, etc.), and false if not (cron, ssh exec, pipe, etc.). +// Thanks to https://rosettacode.org/wiki/Check_output_device_is_a_terminal#Go +func IsShell() (interactive bool) { + + var stdoutStat os.FileInfo + + stdoutStat, _ = os.Stdout.Stat() + + if (stdoutStaf.Mode() & os.ModeCharDevice) != 0 { + interactive = True + } + + return +}