X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=main.go;h=634ca8fdff584f78140f35f4db8d178c58894d69;hb=b4eefdd675c9aef9ff8bd1089d031ee05733195b;hp=0b893dac172389ca199dcc70a08a2358d88c502e;hpb=b42c8c2dba5ea7667c32681338930969ed5c1cdb;p=goredo.git diff --git a/main.go b/main.go index 0b893da..634ca8f 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ /* goredo -- djb's redo implementation on pure Go -Copyright (C) 2020-2021 Sergey Matveev +Copyright (C) 2020-2023 Sergey Matveev 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 @@ -25,7 +25,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "os" "os/signal" @@ -55,12 +54,15 @@ const ( CmdNameRedoStamp = "redo-stamp" CmdNameRedoTargets = "redo-targets" CmdNameRedoWhichdo = "redo-whichdo" + CmdNameRedoDepFix = "redo-depfix" + CmdNameRedoInode = "redo-inode" ) var ( Cwd string BuildUUID string IsTopRedo bool // is it the top redo instance + UmaskCur int ) func mustSetenv(key string) { @@ -112,6 +114,7 @@ func main() { CmdNameRedoAffects, CmdNameRedoAlways, CmdNameRedoCleanup, + CmdNameRedoDepFix, CmdNameRedoDot, CmdNameRedoIfchange, CmdNameRedoIfcreate, @@ -132,16 +135,15 @@ func main() { } log.SetFlags(log.Lshortfile) + UmaskCur = syscall.Umask(0) + syscall.Umask(UmaskCur) + var err error Cwd, err = os.Getwd() if err != nil { log.Fatalln(err) } - NoColor = os.Getenv(EnvNoColor) != "" - NoSync = os.Getenv(EnvNoSync) == "1" - InodeTrust = os.Getenv(EnvInodeNoTrust) == "" - TopDir = os.Getenv(EnvTopDir) if TopDir == "" { TopDir = "/" @@ -198,16 +200,30 @@ func main() { } else if flagTrace != nil { traced = *flagTrace } + NoColor = os.Getenv(EnvNoColor) != "" + NoSync = os.Getenv(EnvNoSync) == "1" + StopIfMod = os.Getenv(EnvStopIfMod) == "1" + switch s := os.Getenv(EnvInodeTrust); s { + case "none": + InodeTrust = InodeTrustNone + case "", "ctime": + InodeTrust = InodeTrustCtime + case "mtime": + InodeTrust = InodeTrustMtime + default: + log.Fatalln("unknown", EnvInodeTrust, "value") + } + tracef(CDebug, "inode-trust: %s", InodeTrust) // Those are internal envs - FdOODTgts, err = ioutil.TempFile("", "ood-tgts") + FdOODTgts, err = os.CreateTemp("", "ood-tgts") if err != nil { log.Fatalln(err) } if err = os.Remove(FdOODTgts.Name()); err != nil { log.Fatalln(err) } - FdOODTgtsLock, err = ioutil.TempFile("", "ood-tgts.lock") + FdOODTgtsLock, err = os.CreateTemp("", "ood-tgts.lock") if err != nil { log.Fatalln(err) } @@ -218,17 +234,22 @@ func main() { if v := os.Getenv(EnvOODTgtsFd); v != "" { fd := mustParseFd(v, EnvOODTgtsFd) fdLock := mustParseFd(v, EnvOODTgtsLockFd) - if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_EX); err != nil { + flock := unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: io.SeekStart, + } + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLKW, &flock); err != nil { log.Fatalln(err) } if _, err = fd.Seek(0, io.SeekStart); err != nil { log.Fatalln(err) } - tgtsRaw, err := ioutil.ReadAll(bufio.NewReader(fd)) + tgtsRaw, err := io.ReadAll(bufio.NewReader(fd)) if err != nil { log.Fatalln(err) } - if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_UN); err != nil { + flock.Type = unix.F_UNLCK + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLK, &flock); err != nil { log.Fatalln(err) } OODTgts = map[string]struct{}{} @@ -318,7 +339,7 @@ CmdSwitch: } } case CmdNameRedoIfchange: - ok, err = ifchange(tgts, false, traced) + ok, err = ifchange(tgts, *flagForcedIfchange, traced) if err == nil { err = depsWrite(fdDep, tgts) } @@ -328,8 +349,8 @@ CmdSwitch: } for _, tgt := range tgts { tgtRel, err := filepath.Rel( - filepath.Join(Cwd, DirPrefix), - filepath.Join(Cwd, tgt), + path.Join(Cwd, DirPrefix), + path.Join(Cwd, tgt), ) if err != nil { break @@ -369,7 +390,7 @@ CmdSwitch: log.Fatalln("single target expected") } var fdTmp *os.File - fdTmp, err = ioutil.TempFile("", "whichdo") + fdTmp, err = os.CreateTemp("", "whichdo") if err != nil { break } @@ -480,6 +501,22 @@ CmdSwitch: for _, src := range srcs { fmt.Println(src) } + case CmdNameRedoDepFix: + err = depFix(Cwd) + case CmdNameRedoInode: + var inode *Inode + for _, tgt := range tgts { + inode, err = inodeFromFileByPath(tgt) + if err != nil { + break + } + err = recfileWrite(os.Stdout, append( + []recfile.Field{{Name: "Target", Value: tgt}}, + inode.RecfileFields()...)...) + if err != nil { + break + } + } default: log.Fatalln("unknown command", cmdName) }