summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-06-08 14:03:21 -0700
committerRuss Cox <rsc@golang.org>2009-06-08 14:03:21 -0700
commit7bdf177771262cf082129218f72b3e89a59eec65 (patch)
tree49a9b6287ffa031432c5e020116888a0a5b76b78 /src/lib
parenta617d5a9814ef223b039c82960fd510fd2cd3d53 (diff)
downloadgolang-7bdf177771262cf082129218f72b3e89a59eec65.tar.gz
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
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/http/triv.go28
-rw-r--r--src/lib/runtime/darwin/thread.c20
2 files changed, 44 insertions, 4 deletions
diff --git a/src/lib/http/triv.go b/src/lib/http/triv.go
index 852898490..fc9501769 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 79267085e..e5b5b9b8a 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");
+ }
}