]> Cypherpunks repositories - gostls13.git/commitdiff
add exec example to http triv.go.
authorRuss Cox <rsc@golang.org>
Mon, 8 Jun 2009 21:03:21 +0000 (14:03 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 8 Jun 2009 21:03:21 +0000 (14:03 -0700)
fix darwin interrupt bug (race with SIGCHLD).

R=gri
DELTA=46  (40 added, 0 deleted, 6 changed)
OCL=30052
CL=30057

src/lib/http/triv.go
src/lib/runtime/darwin/thread.c

index 8528984904fea02f60147e9840f3f184c34b377e..fc950176977461c937091ea3436ae3e1b031e1fc 100644 (file)
@@ -110,6 +110,33 @@ func (ch Chan) ServeHTTP(c *http.Conn, req *http.Request) {
        io.WriteString(c, fmt.Sprintf("channel send #%d\n", <-ch));
 }
 
+// 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(r, c);
+       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 main() {
        flag.Parse();
 
@@ -123,6 +150,7 @@ func main() {
        http.Handle("/args", http.HandlerFunc(ArgServer));
        http.Handle("/go/hello", http.HandlerFunc(HelloServer));
        http.Handle("/chan", ChanCreate());
+       http.Handle("/date", http.HandlerFunc(DateServer));
        err := http.ListenAndServe(":12345", nil);
        if err != nil {
                log.Crash("ListenAndServe: ", err)
index 79267085eda7fb1f415f660aa0ec898c83a69ff7..e5b5b9b8a0be1b12c729b0d2068d25abbb568176 100644 (file)
@@ -322,6 +322,8 @@ enum
 
        Tmach_semdestroy = 3419,
        Rmach_semdestroy = Tmach_semdestroy + Reply,
+
+       KERN_ABORTED = 14,
 };
 
 typedef struct Tmach_semcreateMsg Tmach_semcreateMsg;
@@ -372,8 +374,11 @@ mach_semcreate(void)
        m.tx.policy = 0;        // 0 = SYNC_POLICY_FIFO
        m.tx.value = 0;
 
-       if((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0)
+       while((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0){
+               if(r == KERN_ABORTED)   // interrupted
+                       continue;
                macherror(r, "semaphore_create");
+       }
        if(m.rx.body.msgh_descriptor_count != 1)
                unimplemented("mach_semcreate desc count");
        return m.rx.semaphore.name;
@@ -397,8 +402,9 @@ mach_semdestroy(uint32 sem)
        m.tx.semaphore.disposition = MACH_MSG_TYPE_MOVE_SEND;
        m.tx.semaphore.type = 0;
 
-       if((r = machcall(&m.tx.h, sizeof m, 0)) != 0)
+       while((r = machcall(&m.tx.h, sizeof m, 0)) != 0){
                macherror(r, "semaphore_destroy");
+       }
 }
 
 // The other calls have simple system call traps in sys.s
@@ -412,8 +418,11 @@ mach_semacquire(uint32 sem)
 {
        int32 r;
 
-       if((r = mach_semaphore_wait(sem)) != 0)
+       while((r = mach_semaphore_wait(sem)) != 0) {
+               if(r == KERN_ABORTED)   // interrupted
+                       continue;
                macherror(r, "semaphore_wait");
+       }
 }
 
 void
@@ -421,7 +430,10 @@ mach_semrelease(uint32 sem)
 {
        int32 r;
 
-       if((r = mach_semaphore_signal(sem)) != 0)
+       while((r = mach_semaphore_signal(sem)) != 0) {
+               if(r == KERN_ABORTED)   // interrupted
+                       continue;
                macherror(r, "semaphore_signal");
+       }
 }