X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=run.go;h=589889e3db6edbf62f51f626e5f9ed04394323fd;hb=3a29962a4bfcb0cf6cdfd112fb87f68751b0a0dc;hp=bb3604bf4ba29feb289bc834a66242c94b023782;hpb=c5123973b6ebfa2273f0ea3fa02aa35d329bae4d;p=goredo.git diff --git a/run.go b/run.go index bb3604b..589889e 100644 --- a/run.go +++ b/run.go @@ -21,7 +21,6 @@ package main import ( "bufio" - "encoding/hex" "errors" "flag" "fmt" @@ -29,13 +28,14 @@ import ( "os" "os/exec" "path" - "strconv" + "path/filepath" "strings" "sync" "syscall" "time" "go.cypherpunks.ru/recfile" + "go.cypherpunks.ru/tai64n" "golang.org/x/sys/unix" ) @@ -63,7 +63,8 @@ var ( StderrPrefix string Jobs sync.WaitGroup - flagTrace = flag.Bool("x", false, fmt.Sprintf("trace current target (sh -x) (set %s=1 for others too)", EnvTrace)) + flagTrace = flag.Bool("x", false, "trace (sh -x) current targets") + flagTraceAll = flag.Bool("xx", false, fmt.Sprintf("trace (sh -x) all targets (%s=1)", EnvTrace)) flagStderrKeep = flag.Bool("logs", false, fmt.Sprintf("keep job's stderr (%s=1)", EnvStderrKeep)) flagStderrSilent = flag.Bool("silent", false, fmt.Sprintf("do not print job's stderr (%s=1)", EnvStderrSilent)) ) @@ -102,16 +103,6 @@ func mkdirs(pth string) error { return os.MkdirAll(pth, os.FileMode(0777)) } -func tempsuffix() string { - return strconv.FormatInt((time.Now().UnixNano()+int64(os.Getpid()))&0xFFFFFFFF, 16) -} - -func tempfile(dir, prefix string) (*os.File, error) { - // It respects umask, unlike ioutil.TempFile - name := path.Join(dir, TmpPrefix+prefix+"."+tempsuffix()) - return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666)) -} - func isModified(cwd, redoDir, tgt string) (bool, string, error) { fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)) if err != nil { @@ -303,51 +294,35 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { var cmdName string var args []string if err = unix.Access(doFilePath, unix.X_OK); err == nil { - // Ordinary executable file cmdName = doFilePath args = make([]string, 0, 3) } else { - fd, err := os.Open(doFilePath) - if err != nil { - cleanup() - return TgtErr{tgtOrig, err} - } - buf := make([]byte, 512) - n, err := fd.Read(buf) - if err != nil { - cleanup() - return TgtErr{tgtOrig, err} - } - if n > 3 && string(buf[:3]) == "#!/" { - // Shebanged - t := string(buf[2:n]) - nlIdx := strings.Index(t, "\n") - if nlIdx == -1 { - cleanup() - return TgtErr{tgtOrig, errors.New("not fully read shebang")} - } - args = strings.Split(t[:nlIdx], " ") - cmdName, args = args[0], args[1:] + cmdName = "/bin/sh" + if traced { + args = append(args, "-ex") } else { - // Shell - cmdName = "/bin/sh" - if traced { - args = append(args, "-ex") - } else { - args = append(args, "-e") - } + args = append(args, "-e") } args = append(args, doFile) } // Temporary file for stdout - fdStdout, err := tempfile(cwd, tgt) + fdStdout, err := tempfile(cwdOrig, tgt) if err != nil { cleanup() return TgtErr{tgtOrig, err} } tmpPath := fdStdout.Name() + ".3" // and for $3 - args = append(args, tgt, basename, path.Base(tmpPath)) + tmpPathRel, err := filepath.Rel(cwd, tmpPath) + if err != nil { + panic(err) + } + args = append( + args, + path.Join(dirPrefix, tgt), + path.Join(dirPrefix, basename), + tmpPathRel, + ) cmd := exec.Command(cmdName, args...) cmd.Dir = cwd @@ -445,7 +420,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { go func() { scanner := bufio.NewScanner(stderr) var line string - ts := new(TAI64N) + ts := new(tai64n.TAI64N) for scanner.Scan() { line = scanner.Text() if strings.HasPrefix(line, childStderrPrefix) { @@ -454,9 +429,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { continue } if fdStderr != nil { - tai64nNow(ts) + tai64n.FromTime(time.Now(), ts) LogMutex.Lock() - fmt.Fprintf(fdStderr, "@%s %s\n", hex.EncodeToString(ts[:]), line) + fmt.Fprintf(fdStderr, "%s %s\n", ts.Encode(), line) LogMutex.Unlock() } if StderrSilent {