From: Russ Cox Date: Mon, 8 Jun 2009 21:03:21 +0000 (-0700) Subject: add exec example to http triv.go. X-Git-Tag: weekly.2009-11-06~1427 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=cd80000d8d0e3804761407e94e7919bf613566b7;p=gostls13.git add exec example to http triv.go. fix darwin interrupt bug (race with SIGCHLD). R=gri DELTA=46 (40 added, 0 deleted, 6 changed) OCL=30052 CL=30057 --- diff --git a/src/lib/http/triv.go b/src/lib/http/triv.go index 8528984904..fc95017697 100644 --- a/src/lib/http/triv.go +++ b/src/lib/http/triv.go @@ -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) diff --git a/src/lib/runtime/darwin/thread.c b/src/lib/runtime/darwin/thread.c index 79267085ed..e5b5b9b8a0 100644 --- a/src/lib/runtime/darwin/thread.c +++ b/src/lib/runtime/darwin/thread.c @@ -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"); + } }