]> Cypherpunks.ru repositories - goredo.git/blobdiff - run.go
Up to date recfile
[goredo.git] / run.go
diff --git a/run.go b/run.go
index 1dc937dedb6313a469420fafe6137194ebda262e..af71b3b8b3b4c4b08d39082e295d2fa48316ed62 100644 (file)
--- a/run.go
+++ b/run.go
@@ -1,5 +1,5 @@
 /*
-goredo -- redo implementation on pure Go
+goredo -- djb's redo implementation on pure Go
 Copyright (C) 2020-2021 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
@@ -51,7 +51,7 @@ const (
 
        RedoDir    = ".redo"
        LockSuffix = ".lock"
-       DepSuffix  = ".dep"
+       DepSuffix  = ".rec"
        TmpPrefix  = ".redo."
        LogSuffix  = ".log"
 )
@@ -204,7 +204,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 +240,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 +293,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
@@ -316,7 +318,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 +334,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 +345,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 {
@@ -367,10 +373,6 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
        }
 
        // Preparing stderr
-       stderr, err := cmd.StderrPipe()
-       if err != nil {
-               panic(err)
-       }
        var fdStderr *os.File
        if StderrKeep {
                fdStderr, err = os.OpenFile(
@@ -396,6 +398,26 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                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)
                        lockRelease()
@@ -413,9 +435,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
@@ -473,7 +500,6 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                                if err == nil && !inode.Equals(inodePrev) {
                                        runErr.Err = errors.New("$1 was explicitly touched")
                                        errs <- runErr
-                                       fd.Close()
                                        return
                                }
                        }
@@ -543,7 +569,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                        }
                }
 
-               // Commit .dep
+               // Commit .rec
                if !NoSync {
                        err = fdDep.Sync()
                        if err != nil {