StderrPrefix string
Jobs sync.WaitGroup
- flagTrace = flag.Bool("x", false, "trace current target (sh -x) (set REDO_TRACE=1 for others too)")
- flagStderrKeep = flag.Bool("logs", false, "keep job's stderr (REDO_LOGS=1)")
- flagStderrSilent = flag.Bool("silent", false, "do not print job's stderr (REDO_SILENT=1)")
+ flagTrace = flag.Bool("x", false, fmt.Sprintf("trace current target (sh -x) (set %s=1 for others too)", 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))
)
type RunErr struct {
fdLock.Close()
return TgtErr{tgtOrig, err}
}
- trace(CDebug, "waiting: %s", tgtOrig)
Jobs.Add(1)
+ trace(CDebug, "waiting: %s", tgtOrig)
+ if FdStatus != nil {
+ FdStatus.Write([]byte{StatusWait})
+ }
go func() {
defer Jobs.Done()
trace(CLock, "LOCK_EX: %s", fdLock.Name())
unix.Flock(int(fdLock.Fd()), unix.LOCK_EX)
lockRelease()
trace(CDebug, "waiting done: %s", tgtOrig)
+ if FdStatus != nil {
+ FdStatus.Write([]byte{StatusWaited})
+ }
var depInfo *DepInfo
fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix))
if err != nil {
cleanup()
return TgtErr{tgtOrig, errors.New("no .do found")}
}
- if err = writeDep(fdDep, cwd, doFile); err != nil {
- cleanup()
- return TgtErr{tgtOrig, err}
- }
// Determine basename and DIRPREFIX
ents := strings.Split(cwd, "/")
cwd = path.Join(cwd, "..")
}
cwd = path.Clean(cwd)
+ doFilePath := path.Join(cwd, doFile)
basename := tgt
runErr := RunErr{Tgt: tgtOrig}
if strings.HasPrefix(doFile, "default.") {
basename = tgt[:len(tgt)-(len(doFile)-len("default.")-len(".do"))-1]
runErr.DoFile = doFile
}
+
+ if err = writeDep(fdDep, cwd, doFile); err != nil {
+ cleanup()
+ return TgtErr{tgtOrig, err}
+ }
trace(CWait, "%s", runErr.Name())
- doFile = path.Base(doFile)
// Prepare command line
var cmdName string
var args []string
- if err = unix.Access(path.Join(cwd, doFile), unix.X_OK); err == nil {
+ if err = unix.Access(doFilePath, unix.X_OK); err == nil {
// Ordinary executable file
- cmdName = doFile
+ cmdName = doFilePath
args = make([]string, 0, 3)
} else {
- fd, err := os.Open(path.Join(cwd, doFile))
+ fd, err := os.Open(doFilePath)
if err != nil {
cleanup()
return TgtErr{tgtOrig, err}
"%s=%s", EnvStderrPrefix, childStderrPrefix,
))
- cmd.ExtraFiles = append(cmd.ExtraFiles, fdDep)
fdNum := 0
+ cmd.ExtraFiles = append(cmd.ExtraFiles, fdDep)
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvDepFd, 3+fdNum))
fdNum++
+
+ if FdStatus == nil {
+ cmd.Env = append(cmd.Env, fmt.Sprintf("%s=NO", EnvStatusFd))
+ } else {
+ cmd.ExtraFiles = append(cmd.ExtraFiles, FdStatus)
+ cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvStatusFd, 3+fdNum))
+ fdNum++
+ }
+
if JSR == nil {
// infinite jobs
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=NO", EnvJSFd))
Jobs.Add(1)
go func() {
jsAcquire(shCtx)
+ if FdStatus != nil {
+ FdStatus.Write([]byte{StatusRun})
+ }
defer func() {
jsRelease(shCtx)
lockRelease()
os.Remove(fdStdout.Name())
os.Remove(tmpPath)
os.Remove(fdLock.Name())
+ if FdStatus != nil {
+ FdStatus.Write([]byte{StatusDone})
+ }
Jobs.Done()
}()
started := time.Now()
}
if fdStderr != nil {
tai64nNow(ts)
+ LogMutex.Lock()
fmt.Fprintf(fdStderr, "@%s %s\n", hex.EncodeToString(ts[:]), line)
+ LogMutex.Unlock()
}
if StderrSilent {
continue