From cd80000d8d0e3804761407e94e7919bf613566b7 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 8 Jun 2009 14:03:21 -0700 Subject: [PATCH] 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 --- src/lib/http/triv.go | 28 ++++++++++++++++++++++++++++ src/lib/runtime/darwin/thread.c | 20 ++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) 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"); + } } -- 2.48.1