Beispiel #1
0
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
}
Beispiel #2
0
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)
}
Beispiel #3
0
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)
}
Beispiel #4
0
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))
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
	}
}
Beispiel #7
0
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
}
Beispiel #8
0
// 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}
}
Beispiel #9
0
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)
	}
}
Beispiel #10
0
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
}
Beispiel #12
0
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
}
Beispiel #13
0
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
}
Beispiel #14
0
// 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;
}
Beispiel #15
0
// 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
}
Beispiel #16
0
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)
}
Beispiel #17
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))
	}
}
Beispiel #18
0
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;
}
Beispiel #19
0
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)
}
Beispiel #20
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
}
Beispiel #21
0
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");
}
Beispiel #22
0
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
}
Beispiel #23
0
// 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
}
Beispiel #24
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)
}
Beispiel #25
0
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")
}
Beispiel #26
0
// 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
}
Beispiel #27
0
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
}
Beispiel #28
0
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("-----")
}