func compile(w *World) *bytes.Buffer { ioutil.WriteFile(TEMPPATH+".go", []byte(w.source()), 0644) err := new(bytes.Buffer) re, e, _ := os.Pipe() os.ForkExec( bin+"/"+arch+"g", []string{bin + "/" + arch + "g", "-o", TEMPPATH + ".6", TEMPPATH + ".go"}, os.Environ(), "", []*os.File{nil, e, nil}) e.Close() io.Copy(err, re) if err.Len() > 0 { return err } re, e, _ = os.Pipe() os.ForkExec( bin+"/"+arch+"l", []string{bin + "/" + arch + "l", "-o", TEMPPATH + "", TEMPPATH + ".6"}, os.Environ(), "", []*os.File{nil, e, nil}) e.Close() io.Copy(err, re) return err }
func main() { if len(os.Args) < 2 { fmt.Printf("Usage: %s <script file>\n", os.Args[0]) return } namehash_hash := md5.New() io.WriteString(namehash_hash, os.Args[1]) namehash := hex.EncodeToString(namehash_hash.Sum()) tempfile := temp_dir() + "/" + namehash readpipe, writepipe, _ := os.Pipe() stdfiles := [](*os.File){readpipe, os.Stdout, os.Stderr} syscall.Umask(0077) srcfile, err := os.Open(os.Args[1], os.O_RDONLY, 0) if err != nil { fmt.Println(err) os.Exit(1) } srcinfo, _ := srcfile.Stat() outfile, err := os.Open(tempfile+".ld", os.O_RDONLY, 0) var outinfo (*os.FileInfo) if err == nil { outinfo, _ = outfile.Stat() outfile.Close() } if err != nil || outinfo.Mtime_ns < srcinfo.Mtime_ns { //fmt.Printf("Compiling...") cpid, cerr := os.ForkExec(GOBIN+"8g", []string{GOBIN + "8g", "-o", tempfile + ".cd", "/dev/stdin"}, nil, "", stdfiles) src := textproto.NewReader(bufio.NewReader(srcfile)) firstline := true for { s, err := src.ReadLine() if err != nil { break } if (len(s) > 0) && (s[0] == '#') && firstline { continue } firstline = false writepipe.WriteString(s + "\n") } writepipe.Close() srcfile.Close() stage_check(cpid, cerr, "compile") lpid, err := os.ForkExec(GOBIN+"8l", []string{GOBIN + "8l", "-o", tempfile + ".ld", tempfile + ".cd"}, nil, "", stdfiles) stage_check(lpid, err, "link") os.Chmod(tempfile+".ld", 0700) //fmt.Println("done.") } else { //fmt.Println("Running cached.") } err = os.Exec(tempfile+".ld", os.Args[1:], nil) fmt.Println(err) os.Exit(1) }
func git_from_net(url string) string { var args [3]string args[0] = "git" args[1] = "clone" args[2] = url var fds []*os.File = new([3]*os.File) fds[0] = os.Stdin fds[1] = os.Stdout fds[2] = os.Stderr _, str := path.Split(url) name := strings.Split(str, ".", -1)[0] var git_path string switch os.Getenv("GOOS") { case "darwin": git_path = "/usr/local/git/bin/git" break case "linux": git_path = "/opt/local/bin/git" break } /* Replace this with git's full path, or use a shell, and then call git in the args */ pid, err := os.ForkExec(git_path, &args, os.Envs, os.Getenv("GOROOT")+"/src/pkg/", fds) if err != nil { log.Exit(err) } os.Wait(pid, 0) return string(os.Getenv("GOROOT") + "/src/pkg/" + name) }
func startProc(path, args interface{}) interface{} { p, ok := path.(string) if !ok { TypeError("string", path) } argv := make([]string, ListLen(args)) for cur, i := args, 0; cur != EMPTY_LIST; cur, i = Cdr(cur), i+1 { x := Car(cur) s, ok := x.(string) if !ok { TypeError("string", x) } argv[i] = s } inr, inw, err := os.Pipe() if err != nil { SystemError(err) } outr, outw, err := os.Pipe() if err != nil { SystemError(err) } _, err = os.ForkExec(p, argv, os.Envs, "", []*os.File{inr, outw, os.Stderr}) if err != nil { SystemError(err) } return Cons(NewOutput(inw), NewInput(outr)) }
func Keyspace(servers string) (*KeyspaceProxy, os.Error) { serverList := strings.Split(servers, " ", -1) argv := make([]string, len(serverList)+1) argv[0] = scriptPath for idx, server := range serverList { argv[idx+1] = server } stdinRead, stdinWrite, err := os.Pipe() if err != nil { return nil, err } stdoutRead, stdoutWrite, err := os.Pipe() if err != nil { return nil, err } stderrRead, stderrWrite, err := os.Pipe() if err != nil { return nil, err } fd := []*os.File{stdinRead, stdoutWrite, stderrWrite} pid, err := os.ForkExec(scriptPath, argv, os.Environ(), "", fd) if err != nil { return nil, err } return &KeyspaceProxy{ Servers: servers, pid: pid, stdin: stdinWrite, stdout: stdoutRead, stderr: stderrRead, lock: &sync.Mutex{}, }, nil }
// exec a program, redirecting output func DateServer(c *http.Conn, req *http.Request) { c.SetHeader("content-type", "text/plain; charset=utf-8") r, w, err := os.Pipe() if err != nil { fmt.Fprintf(c, "pipe: %s\n", err) return } pid, err := os.ForkExec("/bin/date", []string{"date"}, os.Environ(), "", []*os.File{nil, w, w}) defer r.Close() w.Close() if err != nil { fmt.Fprintf(c, "fork/exec: %s\n", err) return } io.Copy(c, r) wait, err := os.Wait(pid, 0) if err != nil { fmt.Fprintf(c, "wait: %s\n", err) return } if !wait.Exited() || wait.ExitStatus() != 0 { fmt.Fprintf(c, "date: %v\n", wait) return } }
func run() (*bytes.Buffer, *bytes.Buffer) { out := new(bytes.Buffer) err := new(bytes.Buffer) re, e, _ := os.Pipe() ro, o, _ := os.Pipe() os.ForkExec( TEMPPATH, []string{TEMPPATH}, os.Environ(), "", []*os.File{nil, o, e}) e.Close() io.Copy(err, re) if err.Len() > 0 { return nil, err } o.Close() io.Copy(out, ro) return out, err }
// Return the output from running the given command func GetOutput(args []string) (output string, error os.Error) { read_pipe, write_pipe, err := os.Pipe() if err != nil { goto Error } defer read_pipe.Close() pid, err := os.ForkExec(args[0], args, os.Environ(), ".", []*os.File{nil, write_pipe, nil}) if err != nil { write_pipe.Close() goto Error } _, err = os.Wait(pid, 0) write_pipe.Close() if err != nil { goto Error } buffer := &bytes.Buffer{} _, err = io.Copy(buffer, read_pipe) if err != nil { goto Error } output = buffer.String() return output, nil Error: return "", &CommandError{args[0], args} }
func SpawnMonitor(argv0 string, argv []string, envv []string, dir string, fd []*File) os.Error { pid,err: = os.ForkExec(argv0, argv, envv, dir, fd) (pid int, err Error) if err != nil { return err } for ;os.Kill(pid, 0) == 0;{ _=time.Sleep(10000) } }
func runSystemCommand(argv []string, dir string) string { lookedPath, _ := exec.LookPath(argv[0]) r, w, _ := os.Pipe() pid, _ := os.ForkExec(lookedPath, argv, nil, dir, []*os.File{nil, w, w}) w.Close() os.Wait(pid, 0) var b bytes.Buffer io.Copy(&b, r) return b.String() }
// Run starts the named binary running with // arguments argv and environment envv. // It returns a pointer to a new Cmd representing // the command or an error. // // The parameters stdin, stdout, and stderr // specify how to handle standard input, output, and error. // The choices are DevNull (connect to /dev/null), // PassThrough (connect to the current process's standard stream), // Pipe (connect to an operating system pipe), and // MergeWithStdout (only for standard error; use the same // file descriptor as was used for standard output). // If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr) // of the returned Cmd is the other end of the pipe. // Otherwise the field in Cmd is nil. func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (p *Cmd, err os.Error) { p = new(Cmd) var fd [3]*os.File if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil { goto Error } if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil { goto Error } if stderr == MergeWithStdout { fd[2] = fd[1] } else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil { goto Error } // Run command. p.Pid, err = os.ForkExec(name, argv, envv, dir, fd[0:]) if err != nil { goto Error } if fd[0] != os.Stdin { fd[0].Close() } if fd[1] != os.Stdout { fd[1].Close() } if fd[2] != os.Stderr && fd[2] != fd[1] { fd[2].Close() } return p, nil Error: if fd[0] != os.Stdin && fd[0] != nil { fd[0].Close() } if fd[1] != os.Stdout && fd[1] != nil { fd[1].Close() } if fd[2] != os.Stderr && fd[2] != nil && fd[2] != fd[1] { fd[2].Close() } if p.Stdin != nil { p.Stdin.Close() } if p.Stdout != nil { p.Stdout.Close() } if p.Stderr != nil { p.Stderr.Close() } return nil, err }
func tryRunServer() os.Error { path, err := exec.LookPath("gocode") if err != nil { return err } args := []string{"gocode", "-s", "-sock", *sock, "-addr", *addr} _, err = os.ForkExec(path, args, os.Environ(), "", []*os.File{nil, nil, nil}) if err != nil { return err } return nil }
func UnmountFuse(mountpoint string) (err os.Error) { var pid int fmt.Println("Unmounting", mountpoint, "...") for i := 0; i < len(paths); i++ { var args []string = []string{paths[i], "-u", mountpoint} pid, err = os.ForkExec(paths[i], args, []string{}, "", []*os.File{os.Stdin, os.Stdout, os.Stderr}) if err == nil { os.Wait(pid, 0) return err } } return err }
// run runs the command argv, feeding in stdin on standard input. // It returns the output to standard output and standard error. // ok indicates whether the command exited successfully. func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) { cmd, err := exec.LookPath(argv[0]); if err != nil { fatal("exec %s: %s", argv[0], err); } r0, w0, err := os.Pipe(); if err != nil { fatal("%s", err); } r1, w1, err := os.Pipe(); if err != nil { fatal("%s", err); } r2, w2, err := os.Pipe(); if err != nil { fatal("%s", err); } pid, err := os.ForkExec(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2}); if err != nil { fatal("%s", err); } r0.Close(); w1.Close(); w2.Close(); c := make(chan bool); go func() { w0.Write(stdin); w0.Close(); c <- true; }(); var xstdout []byte; // TODO(rsc): delete after 6g can take address of out parameter go func() { xstdout, _ = io.ReadAll(r1); r1.Close(); c <- true; }(); stderr, _ = io.ReadAll(r2); r2.Close(); <-c; <-c; stdout = xstdout; w, err := os.Wait(pid, 0); if err != nil { fatal("%s", err); } ok = w.Exited() && w.ExitStatus() == 0; return; }
// run runs the command argv, feeding in stdin on standard input. // It returns the output to standard output and standard error. // ok indicates whether the command exited successfully. func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) { cmd, err := exec.LookPath(argv[0]) if err != nil { fatal("exec %s: %s", argv[0], err) } r0, w0, err := os.Pipe() if err != nil { fatal("%s", err) } r1, w1, err := os.Pipe() if err != nil { fatal("%s", err) } r2, w2, err := os.Pipe() if err != nil { fatal("%s", err) } pid, err := os.ForkExec(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2}) if err != nil { fatal("%s", err) } r0.Close() w1.Close() w2.Close() c := make(chan bool) go func() { w0.Write(stdin) w0.Close() c <- true }() var xstdout []byte // TODO(rsc): delete after 6g can take address of out parameter go func() { xstdout, _ = ioutil.ReadAll(r1) r1.Close() c <- true }() stderr, _ = ioutil.ReadAll(r2) r2.Close() <-c <-c stdout = xstdout w, err := os.Wait(pid, 0) if err != nil { fatal("%s", err) } ok = w.Exited() && w.ExitStatus() == 0 return }
func main() { checkArgs() output, absError := abspath(*outputDir) if absError != nil { showErrorAndQuit(absError.String(), -1) } programPath, programError := getProgramPath() if programError != nil { showErrorAndQuit(programError.String(), -1) } erlPath, pathError := exec.LookPath("erl") if pathError != nil { showErrorAndQuit("Can't find erl program", -1) } head := []string{erlPath, "-run", "efene", "main", *outputType, output} tail := []string{"-run", "init", "stop", "-noshell"} start := len(head) + flag.NArg() args := make([]string, len(head)+len(tail)+flag.NArg()) for i := 0; i < len(head); i++ { args[i] = head[i] } for i := len(head); i < len(head)+flag.NArg(); i++ { args[i], _ = abspath(flag.Arg(i - len(head))) } for i := start; i < start+len(tail); i++ { args[i] = tail[i-start] } if *verbose { fmt.Println("cd " + programPath) fmt.Print(erlPath + " ") printArray(args, true) } pid, error := os.ForkExec(erlPath, args, os.Environ(), programPath, []*os.File{os.Stdin, os.Stdout, os.Stderr}) if error != nil { showErrorAndQuit(error.String(), -1) } os.Wait(pid, 0) }
func exec(args []string, dir string) { p, error := os.ForkExec(args[0], args, os.Environ(), dir, []*os.File{os.Stdin, os.Stdout, os.Stderr}) if error != nil { fmt.Fprintf(os.Stderr, "Can't %s\n", error) os.Exit(1) } m, error := os.Wait(p, 0) if error != nil { fmt.Fprintf(os.Stderr, "Can't %s\n", error) os.Exit(1) } if m.WaitStatus != 0 { os.Exit(int(m.WaitStatus)) } }
func exec(c *http.Conn, args []string) (status int) { r, w, err := os.Pipe(); if err != nil { log.Stderrf("os.Pipe(): %v\n", err); return 2; } bin := args[0]; fds := []*os.File{nil, w, w}; if *verbose { log.Stderrf("executing %v", args); } pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds); defer r.Close(); w.Close(); if err != nil { log.Stderrf("os.ForkExec(%q): %v\n", bin, err); return 2; } var buf bytes.Buffer; io.Copy(&buf, r); wait, err := os.Wait(pid, 0); if err != nil { os.Stderr.Write(buf.Bytes()); log.Stderrf("os.Wait(%d, 0): %v\n", pid, err); return 2; } status = wait.ExitStatus(); if !wait.Exited() || status > 1 { os.Stderr.Write(buf.Bytes()); log.Stderrf("executing %v failed (exit status = %d)", args, status); return; } if *verbose { os.Stderr.Write(buf.Bytes()); } if c != nil { c.SetHeader("content-type", "text/plain; charset=utf-8"); c.Write(buf.Bytes()); } return; }
func build_pkg(dir string) { var args [3]string args[0] = "make" args[1] = dir + "/Makefile" args[2] = dir var fds []*os.File = new([3]*os.File) fds[0] = os.Stdin fds[1] = os.Stdout fds[2] = os.Stderr /* Replace this with git's full path, or use a shell, and then call git in the args */ pid, err := os.ForkExec("/usr/bin/make", &args, os.Envs, dir, fds) if err != nil { log.Exit(err) } os.Wait(pid, 0) }
func tryRunServer() os.Error { fds, err := makeFDs() if err != nil { return err } defer fds[0].Close() defer fds[1].Close() defer fds[2].Close() var path string path, err = exec.LookPath("gocode") if err != nil { return err } _, err = os.ForkExec(path, []string{"gocode", "-s"}, os.Environ(), "", fds) if err != nil { return err } return nil }
func daemonize(server *Server) { pid, err := os.ForkExec("lineupd", []string{}, []string{}, "/var/run", []*os.File{}); if err != nil { server.Logger().Logf("couldn't fork: %s\n", err); os.Exit(1); } server.Logger().Logf("%d->%d\n", os.Getpid(), pid); if (pid < 0) { os.Exit(1); } if (pid > 0) { os.Exit(0); } syscall.Setsid(); for i := 0; i < 3; i++ { syscall.Close(i); } for i := 0; i < 3; i++ { syscall.Open("/dev/null", os.O_RDWR, 0644); } syscall.Umask(027); syscall.Chdir("/var/run"); }
func get_output(args []string, input []byte) (std []byte, error []byte, e os.Error) { inpr, inpw, err := os.Pipe() if err != nil { return nil, nil, err } stdr, stdw, err := os.Pipe() if err != nil { return nil, nil, err } errr, errw, err := os.Pipe() if err != nil { return nil, nil, err } pid, err := os.ForkExec(args[0], args, os.Environ(), "", []*os.File{inpr, stdw, errw}) if err != nil { return nil, nil, err } inpw.Write(input) inpw.Close() stdw.Close() errw.Close() var b bytes.Buffer io.Copy(&b, stdr) std = b.Bytes() b.Reset() io.Copy(&b, errr) error = b.Bytes() inpr.Close() stdr.Close() errr.Close() os.Wait(pid, 0) return }
// executeCommand runs the specified tool with the supplied arguments (not // including the path to the tool itself), chdir'ing to the specified directory // first. It returns true if and only if the child process returns zero. func executeCommand(tool string, args []string, dir string) bool { fmt.Printf("%s %s\n", tool, strings.Join(args, " ")) var fullArgs vector.StringVector fullArgs.Push(tool) fullArgs.AppendVector(&args) pid, err := os.ForkExec( tool, fullArgs.Data(), os.Environ(), dir, []*os.File{os.Stdin, os.Stdout, os.Stderr}) if err != nil { panic(err) } waitMsg, err := os.Wait(pid, 0) if err != nil { panic(err) } return waitMsg.ExitStatus() == 0 }
func init_mysql() { r, w, err := os.Pipe() if err != nil { panic("%v", err) } fmt.Print("Initializing DB... ") pid, _ := os.ForkExec("/usr/bin/mysql", []string{"/usr/bin/mysql", "test_db"}, os.Environ(), "/versatile", []*os.File{r, os.Stdout, os.Stderr}) // fmt.Fprintln(w,"show tables;"); fmt.Fprintln(w, "DROP TABLE personne;") fmt.Fprintln(w, "DROP TABLE cars;") fmt.Fprintln(w, "CREATE TABLE `personne` ( `id` int(11) NOT NULL auto_increment, `nom` varchar(255) default NULL, age int(3) default NULL, PRIMARY KEY (`id`) );") fmt.Fprintln(w, "INSERT INTO `personne` VALUES (1,'toto',23);") fmt.Fprintln(w, "INSERT INTO `personne` VALUES (2,'titi',NULL);") fmt.Fprintln(w, "CREATE TABLE `cars` ( `id` int(11) NOT NULL auto_increment, `plate` varchar(255) default NULL, `model` varchar(255) default NULL, owner_id int(11) default NULL, PRIMARY KEY (`id`) );") fmt.Fprintln(w, "INSERT INTO `cars` VALUES (1,'123ABC12','Renault',1);") fmt.Fprintln(w, "INSERT INTO `cars` VALUES (2,'123CBA12','Traban',1);") w.Close() os.Wait(pid, 0) fmt.Println("Finished!") conn := gouda.OpenMysql("mysql://root:@localhost:3306/test_db") gouda.GetConnectionStore().RegisterConnection(&conn) }
func launchBrowser(addr string) { argv := make([]string, 0, 4) AppURL = "http://" + addr + "/" autoclose := true switch runtime.GOOS { case "linux": // Linux // - Check $PATH for chromium-browser paths := strings.Split(os.Getenv("PATH"), ":", -1) for _, base := range paths { binpath := path.Join(base, "chromium-browser") if _, err := os.Stat(binpath); err == nil { argv = append(argv, binpath, "--app="+AppURL) } } case "darwin": // Mac OS X // This is not ideal... Chrome can't do application mode if len(argv) == 0 { binpath := path.Join("/Applications", "Google Chrome.app") if _, err := os.Stat(binpath); err == nil { argv = append(argv, "/usr/bin/open", AppURL) autoclose = false } } } if len(argv) == 0 { log.Fatal("Unable to find Chrome or Chromium web browser") } pid, err := os.ForkExec(argv[0], argv, os.Environ(), "", []*os.File{nil, os.Stdout, os.Stderr}) if err != nil { log.Fatalf("Could not launch browser: %s\n", err) } log.Printf("Launching browser: %s (%d)\n", AppURL, pid) // Exit the application if we quit internally if autoclose { go func() { for q := false; !q; { select { //case q = <-gwa.quit: case sig := <-signal.Incoming: if usig, ok := sig.(signal.UnixSignal); ok { switch usig { // If we get ^C, we should exit case syscall.SIGINT: q = true // If we get ^z, we should stop case syscall.SIGTSTP: syscall.Kill(syscall.Getpid(), syscall.SIGSTOP) } } } } syscall.Kill(pid, syscall.SIGTERM) log.Printf("Killed browser (%d)\n", pid) }() } else { log.Printf("Press ^C to exit\n") for q := false; !q; { select { //case q = <-gwa.quit: case sig := <-signal.Incoming: if usig, ok := sig.(signal.UnixSignal); ok { switch usig { // If we get ^C, we should exit case syscall.SIGINT: q = true // If we get ^z, we should stop case syscall.SIGTSTP: syscall.Kill(syscall.Getpid(), syscall.SIGSTOP) } } } } } os.Wait(pid, 0) log.Println("Application exited") }
// ForkExec runs `cmd` in a child process, with all configuration options as // specified in `cx` and the listen fds `lf` in its initial set of fds. func (cx *Context) ForkExec(cmd string, lf []*os.File) (pid int, err os.Error) { // This is not easy to do, because Go does not give us a plain fork // function. Here's the trick: we fork/exec the same program currently // running in this process, then send configuration parameters to it over a // pipe. // // After the first exec, the child process will be running this program, // almost as if we had simply forked, but with a fresh address space. Once // the child reads the configuration data from its pipe, it has enough // information to set up the process environment and exec a second time, // starting the program we really want. if !hasProc() { return 0, os.NewError("doozer: Your OS doesn't have /proc") } var r run r.Context = *cx r.cmd = cmd var ir, iw, sr, sw *os.File sb := make([]byte, 4) // These pipe fds are already close-on-exec, which is what we want for iw // and sr. It's also okay for ir and sw, because we explicitly supply them // to os.ForkExec. ir, iw, err = os.Pipe() if err != nil { return } defer ir.Close() defer iw.Close() sr, sw, err = os.Pipe() if err != nil { return } defer sr.Close() defer sw.Close() // Boring, ugly code to set up the list of child fds. files := make([]*os.File, passListenFdsStart+len(lf)) files[0] = os.Stdin files[1] = os.Stdout files[2] = os.Stderr files[inputReadFd] = ir files[statusWriteFd] = sw copy(files[passListenFdsStart:], lf) // Boring, ugly code to set up the child environment vars. envv := vector.StringVector(os.Environ()) // See if we are giving it any listen fds. if lf != nil { envv.Push(fmt.Sprintf("LISTEN_FDS=%d", len(lf))) } // Okay, here we go... // Fork and exec the same program we're currently running. Give it `cookie` // as its only arg, telling it to behave as our helper program and run // function `execInChild`. pid, err = os.ForkExec("/proc/self/exe", []string{cookie}, envv, "", files) if err != nil { return 0, err } // Send it the configuration data. en := gob.NewEncoder(iw) err = en.Encode(&r) if err != nil { goto parenterror } // Be sure not to deadlock if the child is successful. sw.Close() // Check if the child had an error. var n int n, err = sr.Read(sb) if err != os.EOF || n != 0 { // got a full error code? if n == len(sb) { // decode it (big-endian) errno := 0 | // this 0 is to trick gofmt (int32(sb[0]) << 24) | (int32(sb[1]) << 16) | (int32(sb[2]) << 8) | (int32(sb[3]) << 0) err = &ChildError{os.Errno(errno)} } if err == nil { err = os.EPIPE } goto parenterror } // Read got EOF, so status pipe closed on exec, so exec succeeded. return pid, nil parenterror: // error of some sort after creating the child // make sure the child is well and truly dead syscall.Kill(pid, syscall.SIGKILL) // wait for it to exit, so we don't accumulate zombies var wstatus syscall.WaitStatus _, e1 := syscall.Wait4(pid, &wstatus, 0, nil) for e1 == syscall.EINTR { _, e1 = syscall.Wait4(pid, &wstatus, 0, nil) } return 0, err }
func runUpdateScript(scriptPath, oldPath, newPath string) (err os.Error) { _, err = os.ForkExec(scriptPath, []string{scriptPath, oldPath, newPath}, os.Envs, "", []*os.File{os.Stdin, os.Stdout, os.Stderr}) return }
func main() { flag.Usage = usage flag.Parse() if *helpShort || *helpLong || flag.NArg() == 0 { flag.Usage() os.Exit(1) } fds, err := parser.ParseFiles(flag.Args(), strings.Split(*importPath, ",", -1)) if err != nil { log.Exitf("Failed parsing: %v", err) } resolver.ResolveSymbols(fds) fmt.Println("-----") proto.MarshalText(os.Stdout, fds) fmt.Println("-----") // Find plugin. pluginPath := fullPath(*pluginBinary, strings.Split(os.Getenv("PATH"), ":", -1)) if pluginPath == "" { log.Exitf("Failed finding plugin binary %q", *pluginBinary) } // Start plugin subprocess. pluginIn, meOut, err := os.Pipe() if err != nil { log.Exitf("Failed creating pipe: %v", err) } meIn, pluginOut, err := os.Pipe() if err != nil { log.Exitf("Failed creating pipe: %v", err) } pid, err := os.ForkExec(pluginPath, nil, nil, "/", []*os.File{pluginIn, pluginOut, os.Stderr}) if err != nil { log.Exitf("Failed forking plugin: %v", err) } pluginIn.Close() pluginOut.Close() // Send request. cgRequest := &plugin.CodeGeneratorRequest{ FileToGenerate: flag.Args(), // TODO: proto_file should be topologically sorted (bottom-up) ProtoFile: fds.File, } buf, err := proto.Marshal(cgRequest) if err != nil { log.Exitf("Failed marshaling CG request: %v", err) } _, err = meOut.Write(buf) if err != nil { log.Exitf("Failed writing CG request: %v", err) } meOut.Close() w, err := os.Wait(pid, 0) if err != nil { log.Exitf("Failed waiting for plugin: %v", err) } if w.ExitStatus() != 0 { log.Exitf("Plugin exited with status %d", w.ExitStatus()) } // Read response. cgResponse := new(plugin.CodeGeneratorResponse) if buf, err = ioutil.ReadAll(meIn); err != nil { log.Exitf("Failed reading CG response: %v", err) } if err = proto.Unmarshal(buf, cgResponse); err != nil { log.Exitf("Failed unmarshaling CG response: %v", err) } // TODO: check cgResponse.Error // TODO: write files for _, f := range cgResponse.File { fmt.Printf("--[ %v ]--\n", proto.GetString(f.Name)) fmt.Println(proto.GetString(f.Content)) } fmt.Println("-----") }