X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=run.go;h=1c1b0d7759295786f9e1237975a5a8e18064bd1f;hb=c41fe0fbd726f397636b569161f286821e221885;hp=f6a9042d192dd9316239c99660b3db42a0b61f6d;hpb=16e534744c4a51dff41f8f1dc47ae7657125f5a1;p=goredo.git diff --git a/run.go b/run.go index f6a9042..1c1b0d7 100644 --- a/run.go +++ b/run.go @@ -35,7 +35,7 @@ import ( "time" "go.cypherpunks.ru/recfile" - "go.cypherpunks.ru/tai64n" + "go.cypherpunks.ru/tai64n/v2" "golang.org/x/sys/unix" ) @@ -51,7 +51,7 @@ const ( RedoDir = ".redo" LockSuffix = ".lock" - DepSuffix = ".dep" + DepSuffix = ".rec" TmpPrefix = ".redo." LogSuffix = ".log" ) @@ -67,6 +67,8 @@ var ( 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)) + + TracedAll bool ) type RunErr struct { @@ -87,7 +89,7 @@ func (e *RunErr) Name() string { if e.Finished == nil { return name } - return fmt.Sprintf("%s (%fsec)", name, e.Finished.Sub(*e.Started).Seconds()) + return fmt.Sprintf("%s (%.3fs)", name, e.Finished.Sub(*e.Started).Seconds()) } func (e RunErr) Error() string { @@ -204,7 +206,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)) if err != nil { if os.IsNotExist(err) { - err = errors.New("was not built: no .dep") + err = errors.New("was not built: no .rec") } goto Finish } @@ -240,12 +242,13 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { return nil } - // Start preparing .dep + // Start preparing .rec fdDep, err := tempfile(redoDir, tgt+DepSuffix) if err != nil { lockRelease() return TgtErr{tgtOrig, err} } + fdDepPath := fdDep.Name() cleanup := func() { lockRelease() fdDep.Close() @@ -292,6 +295,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cleanup() return TgtErr{tgtOrig, err} } + fdDep.Close() trace(CWait, "%s", runErr.Name()) // Prepare command line @@ -302,7 +306,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { args = make([]string, 0, 3) } else { cmdName = "/bin/sh" - if traced { + if traced || TracedAll { args = append(args, "-ex") } else { args = append(args, "-e") @@ -316,7 +320,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cleanup() return TgtErr{tgtOrig, err} } - tmpPath := fdStdout.Name() + ".3" // and for $3 + stdoutPath := fdStdout.Name() + fdStdout.Close() + tmpPath := stdoutPath + ".3" // and for $3 tmpPathRel, err := filepath.Rel(cwd, tmpPath) if err != nil { panic(err) @@ -330,7 +336,6 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cmd := exec.Command(cmdName, args...) cmd.Dir = cwd - cmd.Stdout = fdStdout // cmd.Stdin reads from /dev/null by default cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%d", EnvLevel, Level+1)) cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDirPrefix, dirPrefix)) @@ -342,8 +347,11 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { )) fdNum := 0 - cmd.ExtraFiles = append(cmd.ExtraFiles, fdDep) - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvDepFd, 3+fdNum)) + cmd.ExtraFiles = append(cmd.ExtraFiles, FdOODTgts) + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvOODTgtsFd, 3+fdNum)) + fdNum++ + cmd.ExtraFiles = append(cmd.ExtraFiles, FdOODTgtsLock) + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvOODTgtsLockFd, 3+fdNum)) fdNum++ if FdStatus == nil { @@ -354,23 +362,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { fdNum++ } - if JSR == nil { - // infinite jobs - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=NO", EnvJSFd)) - } else { - cmd.ExtraFiles = append(cmd.ExtraFiles, JSR) - cmd.ExtraFiles = append(cmd.ExtraFiles, JSW) - cmd.Env = append(cmd.Env, fmt.Sprintf( - "%s=%d,%d", EnvJSFd, 3+fdNum+0, 3+fdNum+1, - )) - fdNum += 2 - } - // Preparing stderr - stderr, err := cmd.StderrPipe() - if err != nil { - panic(err) - } var fdStderr *os.File if StderrKeep { fdStderr, err = os.OpenFile( @@ -392,12 +384,46 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { Jobs.Add(1) go func() { - jsAcquire(shCtx) + jsToken := jsAcquire(shCtx) + if JSR == nil { + // infinite jobs + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=NO", EnvJobs)) + } else { + cmd.ExtraFiles = append(cmd.ExtraFiles, JSR) + cmd.ExtraFiles = append(cmd.ExtraFiles, JSW) + cmd.Env = append(cmd.Env, fmt.Sprintf( + "%s=%s %s%d,%d", + MakeFlagsName, MakeFlags, MakeJSArg, 3+fdNum+0, 3+fdNum+1, + )) + fdNum += 2 + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvJSToken, jsToken)) + } + if FdStatus != nil { FdStatus.Write([]byte{StatusRun}) } + + started := time.Now() + runErr.Started = &started + fdStdout, err = os.OpenFile(stdoutPath, os.O_RDWR, os.FileMode(0666)) + if err != nil { + runErr.Err = err + errs <- runErr + return + } + cmd.Stdout = fdStdout + fdDep, err = os.OpenFile(fdDepPath, os.O_WRONLY|os.O_APPEND, os.FileMode(0666)) + if err != nil { + runErr.Err = err + errs <- runErr + return + } + cmd.ExtraFiles = append(cmd.ExtraFiles, fdDep) + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d", EnvDepFd, 3+fdNum)) + fdNum++ + defer func() { - jsRelease(shCtx) + jsRelease(shCtx, jsToken) lockRelease() fdDep.Close() fdStdout.Close() @@ -413,9 +439,14 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } Jobs.Done() }() - started := time.Now() - runErr.Started = &started - err := cmd.Start() + stderr, err := cmd.StderrPipe() + if err != nil { + runErr.Err = err + errs <- runErr + return + } + started = time.Now() + err = cmd.Start() if err != nil { runErr.Err = err errs <- runErr @@ -437,9 +468,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { continue } if fdStderr != nil { - tai64n.FromTime(time.Now(), ts) + ts.FromTime(time.Now()) LogMutex.Lock() - fmt.Fprintf(fdStderr, "%s %s\n", ts.Encode(), line) + fmt.Fprintln(fdStderr, tai64n.Encode(ts[:]), line) LogMutex.Unlock() } if StderrSilent { @@ -542,7 +573,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } } - // Commit .dep + // Commit .rec if !NoSync { err = fdDep.Sync() if err != nil {