github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/redirection.go (about) 1 package lang 2 3 import ( 4 "crypto/md5" 5 "fmt" 6 "strings" 7 8 "github.com/lmorg/murex/lang/types" 9 ) 10 11 func parseRedirection(p *Process) { 12 //p.NamedPipeOut = "out" 13 //p.NamedPipeErr = "err" 14 15 for _, name := range p.namedPipes { 16 switch { 17 case len(name) > 5 && name[:5] == "test_": 18 if p.NamedPipeTest == "" { 19 testEnabled, err := p.Config.Get("test", "enabled", types.Boolean) 20 if err == nil && testEnabled.(bool) { 21 p.NamedPipeTest = name[5:] 22 } 23 } else { 24 pipeErr(p, "you specified test multiple times") 25 } 26 27 case len(name) > 6 && name[:6] == "state_": 28 if p.NamedPipeTest == "" { 29 testEnabled, err := p.Config.Get("test", "enabled", types.Boolean) 30 if err == nil && testEnabled.(bool) { 31 p.testState = append(p.testState, name[6:]) 32 } 33 } 34 35 case len(name) > 4 && name[:4] == "env:": 36 p.Exec.Env = append(p.Exec.Env, name[4:]) 37 38 case len(name) > 4 && name[:4] == "fid:": 39 varName := name[4:] 40 err := p.Variables.Set(p, varName, p.Id, types.Integer) 41 if err != nil { 42 ShellProcess.Stderr.Writeln([]byte( 43 fmt.Sprintf("Cannot write variable '%s': %s", varName, err.Error()), 44 )) 45 } 46 47 case len(name) > 4 && name[:4] == "pid:": 48 varName := name[4:] 49 p.Exec.Callback = func(pid int) { 50 err := p.Variables.Set(p, varName, pid, types.Integer) 51 if err != nil { 52 ShellProcess.Stderr.Writeln([]byte( 53 fmt.Sprintf("Cannot write variable '%s': %s", varName, err.Error()), 54 )) 55 } 56 } 57 58 case name[0] == '!': 59 if p.NamedPipeErr == "" { 60 p.NamedPipeErr = name[1:] 61 } else { 62 pipeErr(p, "you specified stderr multiple times") 63 } 64 65 case strings.Contains(name, ":"): 66 err := parseRedirectionTemp(p, name) 67 if err != nil { 68 pipeErr(p, err.Error()) 69 } 70 71 default: 72 if p.NamedPipeOut == "" { 73 p.NamedPipeOut = name 74 } else { 75 pipeErr(p, "you specified stdout multiple times") 76 } 77 } 78 } 79 } 80 81 func parseRedirectionTemp(p *Process, namedPipe string) error { 82 split := strings.SplitN(namedPipe, ":", 2) 83 if len(split) != 2 { 84 return fmt.Errorf("invalid format used: '%s'", namedPipe) 85 } 86 87 name := fmt.Sprintf("tmp:%d/%.3x", p.Id, md5.Sum([]byte(namedPipe))) 88 89 err := GlobalPipes.CreatePipe(name, split[0], split[1]) 90 if err != nil { 91 return err 92 } 93 94 p.NamedPipeOut = name 95 96 return nil 97 } 98 99 func pipeErr(p *Process, msg string) { 100 p.Stderr.Writeln([]byte("Invalid usage of named pipes: " + msg)) 101 }