func TestDup(t *testing.T) { file, err := ioutil.TempFile("", "TestDup") if err != nil { t.Fatalf("Tempfile failed: %v", err) } defer os.Remove(file.Name()) defer file.Close() f := int(file.Fd()) newFd, err := unix.Dup(f) if err != nil { t.Fatalf("Dup: %v", err) } err = unix.Dup2(newFd, newFd+1) if err != nil { t.Fatalf("Dup2: %v", err) } b1 := []byte("Test123") b2 := make([]byte, 7) _, err = unix.Write(newFd+1, b1) if err != nil { t.Fatalf("Write to dup2 fd failed: %v", err) } _, err = unix.Seek(f, 0, 0) _, err = unix.Read(f, b2) if err != nil { t.Fatalf("Read back failed: %v", err) } if string(b1) != string(b2) { t.Errorf("Dup: stdout write not in file, expected %v, got %v", string(b1), string(b2)) } }
// hackDump returns the value dump as a string. func hackDump(v llvm.Value) (string, error) { // Open temp file. // TODO: Use an in-memory file instead of /tmp/x. fd, err := unix.Open("/tmp/x", unix.O_WRONLY|unix.O_TRUNC|unix.O_CREAT, 0644) if err != nil { return "", errutil.Err(err) } // Store original stderr. stderr, err := unix.Dup(2) if err != nil { return "", errutil.Err(err) } // Capture stderr and redirect its output to the temp file. err = unix.Dup2(fd, 2) if err != nil { return "", errutil.Err(err) } err = unix.Close(fd) if err != nil { return "", errutil.Err(err) } // Dump value. v.Dump() C.fflush_stderr() // Restore stderr. err = unix.Dup2(stderr, 2) if err != nil { return "", errutil.Err(err) } err = unix.Close(stderr) if err != nil { return "", errutil.Err(err) } // Return content of temp file. buf, err := ioutil.ReadFile("/tmp/x") if err != nil { return "", errutil.Err(err) } return string(buf), nil }
// redirectStderr to the file passed in func redirectStderr(f *os.File) { err := unix.Dup2(int(f.Fd()), int(os.Stderr.Fd())) if err != nil { log.Fatalf("Failed to redirect stderr to file: %v", err) } }
// Filter .. func Filter() error { /*if GCOn() == false { return fmt.Errorf("GC Debug flag not set") }*/ fmt.Println("filtering GC statements") current = os.Stderr r, w, err := os.Pipe() if err != nil { return err } rr, ww, err := os.Pipe() if err != nil { return err } // dup the Stderr File descriptor syscall.Dup2(int(w.Fd()), int(os.Stderr.Fd())) // Listen on os.Stderr for messages and pipe them to the new files below go func(fwd *os.File, rr *os.File) { fmt.Println("running the goroutine - os.Stderr listener") // Just copy everything from the new os.Stderr into the older one io.Copy(w, rr) }(w, rr) // move os.Stderr os.Stderr = ww go func() { fmt.Println("running the goroutine") scanner := bufio.NewScanner(r) for scanner.Scan() { line := scanner.Text() if line[0:2] == "gc" { var wall, cpu, hs string run := &GCRun{ Clock: Timing{}, CPU: CPU{}, Heap: Heap{}, } // gc 2 @1.289s 0%: 0.10+0.61+0.018+1.3+0.20 ms clock, 0.20+0.61+0+0.13/1.1/2.5+0.41 ms cpu, 4->4->1 MB, 4 MB goal, 4 P _, err := fmt.Sscanf(line, "gc %d @%fs %d%%: %s ms clock, %s ms cpu, %s MB, %d MB goal, %d P", &run.N, &run.Time, &run.Perc, &wall, &cpu, &hs, &run.Heap.Goal, &run.Procs) if err != nil { fmt.Print(err) } fmt.Sscanf(hs, "%d->%d->%d", &run.Heap.Start, &run.Heap.End, &run.Heap.Live) fmt.Sscanf(wall, "%f+%f+%f+%f+%f", &run.Clock.SweepTerm, &run.Clock.Scan, &run.Clock.Sync, &run.Clock.Mark, &run.Clock.MarkTerm) fmt.Sscanf(cpu, "%f+%f+%f+%f/%f/%f+%f", &run.CPU.SweepTerm, &run.CPU.Scan, &run.CPU.Sync, &run.CPU.Mark.Assist, &run.CPU.Mark.Background, &run.CPU.Mark.Idle, &run.CPU.MarkTerm) fmt.Println(run) } else { fmt.Println(line) } } }() return nil }
func syscallDup(oldfd int, newfd int) (err error) { return unix.Dup2(oldfd, newfd) }