]> Cypherpunks repositories - gostls13.git/commitdiff
- godoc periodic sync for Linux and Darwin
authorRobert Griesemer <gri@golang.org>
Tue, 9 Jun 2009 01:09:33 +0000 (18:09 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 9 Jun 2009 01:09:33 +0000 (18:09 -0700)
- support debug/sync (if automatic sync is enabled in the first place)
- removed debug/restart feature

R=rsc
DELTA=97  (37 added, 27 deleted, 33 changed)
OCL=30068
CL=30079

usr/gri/pretty/godoc.go

index 275fa060e075672f5b673e8d25baefb953055a87..97e18952f119725e6bd6c7fb1c0384237f85b444 100644 (file)
@@ -79,14 +79,13 @@ var (
        verbose = flag.Bool("v", false, "verbose mode");
 
        // file system roots
-       launchdir string;       // directory from which godoc was launched
        goroot string;
        pkgroot = flag.String("pkgroot", "src/lib", "root package source directory (if unrooted, relative to goroot)");
        tmplroot = flag.String("tmplroot", "usr/gri/pretty", "root template directory (if unrooted, relative to goroot)");
 
-       // workspace control
-       p4binary = flag.String("p4", "/usr/local/scripts/p4", "p4 binary");
-       syncSleep = flag.Int("sync", 0, "p4 sync interval in minutes; disabled if <= 0");
+       // periodic sync
+       syncCmd = flag.String("sync", "", "sync command; disabled if empty");
+       syncMin = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0");
        syncTime timeStamp;  // time of last p4 sync
 
        // layout control
@@ -589,36 +588,59 @@ func loggingHandler(h http.Handler) http.Handler {
 }
 
 
-func p4sync() bool {
-       if *verbose {
-               log.Stderrf("p4 sync");
+func exec(c *http.Conn, args []string) bool {
+       r, w, err := os.Pipe();
+       if err != nil {
+               log.Stderrf("os.Pipe(): %v\n", err);
+               return false;
        }
-       args := []string{*p4binary, "sync"};
-       var fds []*os.File;
+
+       bin := args[0];
+       fds := []*os.File{nil, w, w};
        if *verbose {
-               fds = []*os.File{os.Stdin, os.Stdout, os.Stderr};
+               log.Stderrf("executing %v", args);
        }
-       pid, err := os.ForkExec(*p4binary, args, os.Environ(), "", fds);
+       pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds);
+       defer r.Close();
+       w.Close();
        if err != nil {
-               log.Stderrf("os.ForkExec(%s): %v", *p4binary, err);
+               log.Stderrf("os.ForkExec(%q): %v\n", bin, err);
                return false;
        }
-       os.Wait(pid, 0);
-       syncTime.set();
+
+       var buf io.ByteBuffer;
+       io.Copy(r, &buf);
+       wait, err := os.Wait(pid, 0);
+       if err != nil {
+               os.Stderr.Write(buf.Data());
+               log.Stderrf("os.Wait(%d, 0): %v\n", pid, err);
+               return false;
+       }
+       if !wait.Exited() || wait.ExitStatus() != 0 {
+               os.Stderr.Write(buf.Data());
+               log.Stderrf("executing %v failed (exit status = %d)", args, wait.ExitStatus());
+               return false;
+       }
+
+       if *verbose {
+               os.Stderr.Write(buf.Data());
+       }
+       if c != nil {
+               c.SetHeader("content-type", "text/plain; charset=utf-8");
+               c.Write(buf.Data());
+       }
+
        return true;
 }
 
 
-func restartGodoc(c *http.Conn, r *http.Request) {
-       binary := os.Args[0];
-       fds := []*os.File{os.Stdin, os.Stdout, os.Stderr};
-       pid, err := os.ForkExec(binary, os.Args, os.Environ(), launchdir, fds);
-       if err != nil {
-               log.Stderrf("os.ForkExec(%s): %v", binary, err);
-               return;  // do not terminate
+func sync(c *http.Conn, r *http.Request) {
+       args := []string{"/bin/sh", "-c", *syncCmd};
+       if !exec(c, args) {
+               *syncMin = 0;  // disable sync
+               return;
        }
-       log.Stderrf("restarted %s, pid = %d\n", binary, pid);
-       os.Exit(0);
+       syncTime.set();
 }
 
 
@@ -647,12 +669,6 @@ func main() {
                }
        }
 
-       var err os.Error;
-       if launchdir, err = os.Getwd(); err != nil {
-               log.Stderrf("unable to determine current working directory - restart may fail");
-               launchdir = "";
-       }
-
        if err := os.Chdir(goroot); err != nil {
                log.Exitf("chdir %s: %v", goroot, err);
        }
@@ -671,36 +687,30 @@ func main() {
                }
 
                http.Handle(Pkg, http.HandlerFunc(servePkg));
-               if syscall.OS != "darwin" {
-                       http.Handle("/debug/restart", http.HandlerFunc(restartGodoc));
-               } else {
-                       log.Stderrf("warning: debug/restart disabled (running on darwin)\n");
+               if *syncCmd != "" {
+                       http.Handle("/debug/sync", http.HandlerFunc(sync));
                }
                http.Handle("/", http.HandlerFunc(serveFile));
 
                // The server may have been restarted; always wait 1sec to
                // give the forking server a chance to shut down and release
-               // the http port. (This is necessary because under OS X Exec
-               // won't work if there are more than one thread running.)
+               // the http port.
                time.Sleep(1e9);
 
-               // Start p4 sync goroutine, if enabled.
-               if syscall.OS != "darwin" {
-                       if *syncSleep > 0 {
-                               go func() {
-                                       if *verbose {
-                                               log.Stderrf("p4 sync every %dmin", *syncSleep);
-                                       }
-                                       for p4sync() {
-                                               time.Sleep(int64(*syncSleep) * (60 * 1e9));
-                                       }
-                                       if *verbose {
-                                               log.Stderrf("periodic p4 sync stopped");
-                                       }
-                               }();
-                       }
-               } else {
-                       log.Stderrf("warning: sync disabled (running on darwin)\n");
+               // Start sync goroutine, if enabled.
+               if *syncCmd != "" && *syncMin > 0 {
+                       go func() {
+                               if *verbose {
+                                       log.Stderrf("sync every %dmin", *syncMin);
+                               }
+                               for *syncMin > 0 {
+                                       sync(nil, nil);
+                                       time.Sleep(int64(*syncMin) * (60 * 1e9));
+                               }
+                               if *verbose {
+                                       log.Stderrf("periodic sync stopped");
+                               }
+                       }();
                }
 
                if err := http.ListenAndServe(*httpaddr, handler); err != nil {