コード例 #1
0
ファイル: loopback_test.go プロジェクト: eliq/go-fuse
func TestFSync(t *testing.T) {
	tc := NewTestCase(t)
	defer tc.Cleanup()

	contents := []byte{1, 2, 3}
	if err := ioutil.WriteFile(tc.origFile, []byte(contents), 0700); err != nil {
		t.Fatalf("WriteFile failed: %v", err)
	}

	f, err := os.OpenFile(tc.mountFile, os.O_WRONLY, 0)
	if err != nil {
		t.Fatalf("OpenFile(%q): %v", tc.mountFile, err)
	}
	defer f.Close()

	if _, err := f.WriteString("hello there"); err != nil {
		t.Fatalf("WriteString failed: %v", err)
	}

	// How to really test fsync ?
	err = syscall.Fsync(int(f.Fd()))
	if err != nil {
		t.Errorf("fsync returned: %v", err)
	}
}
コード例 #2
0
ファイル: serve_test.go プロジェクト: djbarber/ipfs-hack
func TestCreate(t *testing.T) {
	t.Parallel()
	f := &create1{}
	mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
	if err != nil {
		t.Fatal(err)
	}
	defer mnt.Close()

	// uniform umask needed to make os.Create's 0666 into something
	// reproducible
	defer syscall.Umask(syscall.Umask(0022))
	ff, err := os.Create(mnt.Dir + "/foo")
	if err != nil {
		t.Fatalf("create1 WriteFile: %v", err)
	}
	defer ff.Close()

	err = syscall.Fsync(int(ff.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}

	if f.f.RecordedFsync() == (fuse.FsyncRequest{}) {
		t.Errorf("never received expected fsync call")
	}

	ff.Close()
}
コード例 #3
0
ファイル: fuse_test.go プロジェクト: rsrsps/fuse
func (w *write) test(path string, t *testing.T) {
	log.Printf("pre-write Create")
	f, err := os.Create(path)
	if err != nil {
		t.Fatalf("Create: %v", err)
	}
	log.Printf("pre-write Write")
	n, err := f.Write([]byte(hi))
	if err != nil {
		t.Fatalf("Write: %v", err)
	}
	if n != len(hi) {
		t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
	}

	err = syscall.Fsync(int(f.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}
	if !<-w.seen.fsync {
		t.Errorf("never received expected fsync call")
	}

	log.Printf("pre-write Close")
	err = f.Close()
	if err != nil {
		t.Fatalf("Close: %v", err)
	}
	log.Printf("post-write Close")
	if got := string(gather(w.seen.data)); got != hi {
		t.Errorf("writeAll = %q, want %q", got, hi)
	}
}
コード例 #4
0
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "%s", Help)
		os.Exit(1)
	}
	flag.Parse()

	dir, err := os.Getwd()
	if err != nil {
		fatal.Fatalln(err)
	}

	// "To flush all open files on a volume, call FlushFileBuffers with a handle to the volume.
	// The caller must have administrative privileges. For more information, see Running with Special Privileges."
	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx
	fp := filepath.VolumeName(dir)
	file, err := os.Open(fp)
	if err != nil {
		fatal.Fatalln(err)
	}

	err = syscall.Fsync(syscall.Handle(file.Fd()))
	if err != nil {
		fatal.Fatalln(err)
	}
}
コード例 #5
0
ファイル: file.go プロジェクト: louisyoo/gocryptfs
func (f *file) Fsync(flags int) (code fuse.Status) {
	f.fdLock.Lock()
	r := fuse.ToStatus(syscall.Fsync(int(f.fd.Fd())))
	f.fdLock.Unlock()

	return r
}
コード例 #6
0
ファイル: files.go プロジェクト: y-okubo/go-fuse
func (f *loopbackFile) Fsync(flags int) (code fuse.Status) {
	f.lock.Lock()
	r := fuse.ToStatus(syscall.Fsync(int(f.File.Fd())))
	f.lock.Unlock()

	return r
}
コード例 #7
0
ファイル: fsync.go プロジェクト: sternix/commands
func main() {
	var rval int = sysexits.OK

	args := os.Args
	if len(args) < 2 {
		usage()
	}

	for _, f := range args[1:] {
		if fd, err := syscall.Open(f, syscall.O_RDONLY, 0777); err != nil {
			log.Printf("open %s: %v\n", f, err)
			if rval == sysexits.OK {
				rval = sysexits.NOINPUT
			}
			continue
		} else {
			if errf := syscall.Fsync(fd); errf != nil {
				log.Printf("fsync %s:%v\n", f, errf)
				if rval == sysexits.OK {
					rval = sysexits.OSERR
				}
			}
			syscall.Close(fd)
		}
	}
	os.Exit(rval)
}
コード例 #8
0
ファイル: snapshot.go プロジェクト: johnvilsack/golang-stuff
// Save the snapshot to a file
func (ss *Snapshot) save() error {
	// Write machine state to temporary buffer.

	// open file
	file, err := os.OpenFile(ss.Path, os.O_CREATE|os.O_WRONLY, 0600)

	if err != nil {
		return err
	}

	defer file.Close()

	b, err := json.Marshal(ss)

	// Generate checksum.
	checksum := crc32.ChecksumIEEE(b)

	// Write snapshot with checksum.
	if _, err = fmt.Fprintf(file, "%08x\n", checksum); err != nil {
		return err
	}

	if _, err = file.Write(b); err != nil {
		return err
	}

	// force the change writting to disk
	syscall.Fsync(int(file.Fd()))
	return err
}
コード例 #9
0
ファイル: main.go プロジェクト: pandemicsyn/bertin
func ObjDeleteHandler(writer http.ResponseWriter, request *http.Request, vars map[string]string, config ServerConfig) {
	hash_dir := ObjHashDir(vars, config)

	if os.MkdirAll(hash_dir, 0770) != nil {
		ErrorResponse(writer, 500)
		return
	}
	file_name := fmt.Sprintf("%s/%s.ts", hash_dir, request.Header.Get("X-Timestamp"))
	data_file := PrimaryFile(hash_dir)
	temp_file, err := ioutil.TempFile(ObjTempDir(vars, config), "PUT")
	if err != nil {
		ErrorResponse(writer, 500)
		return
	}
	defer temp_file.Close()
	metadata := make(map[string]interface{})
	metadata["X-Timestamp"] = request.Header.Get("X-Timestamp")
	metadata["name"] = fmt.Sprintf("/%s/%s/%s", vars["account"], vars["container"], vars["obj"])
	WriteMetadata(int(temp_file.Fd()), metadata)

	syscall.Fsync(int(temp_file.Fd()))
	syscall.Rename(temp_file.Name(), file_name)
	UpdateContainer("DELETE", metadata, request, vars)
	go CleanupHashDir(hash_dir)
	go InvalidateHash(hash_dir)
	if !strings.HasSuffix(data_file, ".data") {
		ErrorResponse(writer, 404)
	} else {
		ErrorResponse(writer, 204)
	}
}
コード例 #10
0
ファイル: node.go プロジェクト: rizki96/kakigoori
func (f *AzukiFile) Fsync(flags int) (code fuse.Status) {
	f.lock.Lock()
	r := fuse.ToStatus(syscall.Fsync(int(f.File.Fd())))
	f.lock.Unlock()
	go event.Notify(event.Fsync, f.File.Name())
	return r
}
コード例 #11
0
ファイル: snapshot.go プロジェクト: JamesTryand/go-raft
// Save the snapshot to a file
func (ss *Snapshot) Save() error {
	// Write machine state to temporary buffer.
	var b bytes.Buffer

	if _, err := fmt.Fprintf(&b, "%v", 2); err != nil {
		return err
	}

	// Generate checksum.
	checksum := crc32.ChecksumIEEE(b.Bytes())

	// open file
	file, err := os.OpenFile(ss.path, os.O_CREATE|os.O_WRONLY, 0600)

	if err != nil {
		return err
	}

	defer file.Close()

	// Write snapshot with checksum.
	if _, err = fmt.Fprintf(file, "%08x\n%v\n%v\n", checksum, ss.lastIndex,
		ss.lastTerm); err != nil {
		return err
	}

	if _, err = file.Write(ss.state); err != nil {
		return err
	}

	// force the change writting to disk
	syscall.Fsync(int(file.Fd()))
	return err
}
コード例 #12
0
ファイル: file_posix.go プロジェクト: achanda/go
// Sync commits the current contents of the file to stable storage.
// Typically, this means flushing the file system's in-memory copy
// of recently written data to disk.
func (f *File) Sync() error {
	if err := f.checkValid("sync"); err != nil {
		return err
	}
	if e := syscall.Fsync(f.fd); e != nil {
		return &PathError{"sync", f.name, e}
	}
	return nil
}
コード例 #13
0
ファイル: file_posix.go プロジェクト: korli/go
// Sync commits the current contents of the file to stable storage.
// Typically, this means flushing the file system's in-memory copy
// of recently written data to disk.
func (f *File) Sync() error {
	if f == nil {
		return ErrInvalid
	}
	if e := syscall.Fsync(f.fd); e != nil {
		return NewSyscallError("fsync", e)
	}
	return nil
}
コード例 #14
0
// Sync commits the current contents of the file to stable storage.
// Typically, this means flushing the file system's in-memory copy
// of recently written data to disk.
func (file *File) Sync() (err Error) {
	if file == nil {
		return EINVAL
	}
	if e := syscall.Fsync(file.fd); e != 0 {
		return NewSyscallError("fsync", e)
	}
	return nil
}
コード例 #15
0
ファイル: file_posix.go プロジェクト: ds2dev/gcc
// Sync commits the current contents of the file to stable storage.
// Typically, this means flushing the file system's in-memory copy
// of recently written data to disk.
func (f *File) Sync() (err error) {
	if f == nil {
		return syscall.EINVAL
	}
	if e := syscall.Fsync(f.fd); e != nil {
		return NewSyscallError("fsync", e)
	}
	return nil
}
コード例 #16
0
ファイル: objectfile.go プロジェクト: hironobu-s/swiftfs
func (o *ObjectFile) Fsync(flags int) (code fuse.Status) {
	log.Debugf("[objectfile] Fsync %s", o.name)

	o.lock.Lock()
	r := fuse.ToStatus(syscall.Fsync(int(o.localfile.Fd())))
	o.lock.Unlock()

	return r
}
コード例 #17
0
ファイル: main.go プロジェクト: pandemicsyn/bertin
func ObjPutHandler(writer http.ResponseWriter, request *http.Request, vars map[string]string, config ServerConfig) {
	out_headers := writer.Header()
	hash_dir := ObjHashDir(vars, config)

	if os.MkdirAll(hash_dir, 0770) != nil || os.MkdirAll(ObjTempDir(vars, config), 0770) != nil {
		ErrorResponse(writer, 500)
		return
	}
	file_name := fmt.Sprintf("%s/%s.data", hash_dir, request.Header.Get("X-Timestamp"))
	temp_file, err := ioutil.TempFile(ObjTempDir(vars, config), "PUT")
	if err != nil {
		ErrorResponse(writer, 500)
		return
	}
	defer temp_file.Close()
	metadata := make(map[string]interface{})
	metadata["name"] = fmt.Sprintf("/%s/%s/%s", vars["account"], vars["container"], vars["obj"])
	metadata["X-Timestamp"] = request.Header.Get("X-Timestamp")
	metadata["Content-Type"] = request.Header.Get("Content-Type")
	var chunk [65536]byte
	total_size := uint64(0)
	hash := md5.New()
	for {
		read_len, err := request.Body.Read(chunk[0:len(chunk)])
		if err != nil || read_len <= 0 {
			break
		}
		total_size += uint64(read_len)
		hash.Write(chunk[0:read_len])
		temp_file.Write(chunk[0:read_len])
	}
	metadata["Content-Length"] = strconv.FormatUint(total_size, 10)
	metadata["ETag"] = fmt.Sprintf("%x", hash.Sum(nil))
	request_etag := request.Header.Get("ETag")
	if request_etag != "" && request_etag != metadata["ETag"].(string) {
		ErrorResponse(writer, 422)
		return
	}
	for key := range request.Header {
		if strings.HasPrefix(key, "X-Object-") {
			metadata[key] = request.Header.Get(key)
		}
	}
	out_headers.Set("ETag", metadata["ETag"].(string))
	WriteMetadata(int(temp_file.Fd()), metadata)

	syscall.Fsync(int(temp_file.Fd()))
	syscall.Rename(temp_file.Name(), file_name)
	UpdateContainer("PUT", metadata, request, vars)
	go CleanupHashDir(hash_dir)
	go InvalidateHash(hash_dir)
	ErrorResponse(writer, 201)
}
コード例 #18
0
ファイル: swaplabel.go プロジェクト: qeedquan/misc_utilities
func main() {
	log.SetFlags(0)
	log.SetPrefix("swaplabel: ")

	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		usage()
	}
	device := flag.Arg(0)

	f, err := os.OpenFile(device, os.O_RDWR, 0644)
	ck(err)
	defer f.Close()

	_, err = f.Seek(SWAP_MAGIC_OFFSET, io.SeekStart)
	ck(err)

	var magic [SWAP_MAGIC_LENGTH]byte
	_, err = io.ReadAtLeast(f, magic[:], len(magic))
	ck(err)

	if string(magic[:]) != SWAP_MAGIC1 && string(magic[:]) != SWAP_MAGIC2 {
		log.Fatalf("%s: is not a swap partition", device)
	}

	_, err = f.Seek(SWAP_LABEL_OFFSET, io.SeekStart)
	ck(err)

	if *label == "" {
		var buf [SWAP_LABEL_LENGTH]byte
		_, err = io.ReadAtLeast(f, buf[:], len(buf))
		ck(err)

		for i := range buf {
			if i == SWAP_LABEL_LENGTH-1 && buf[i] != 0 {
				log.Fatal("invalid label")
			}
		}
		fmt.Println(strings.TrimRight(string(buf[:]), "\x00"))
	} else {
		if len(*label)+1 > SWAP_LABEL_LENGTH {
			log.Fatal("label too long")
		}
		_, err = f.Write([]byte(*label + "\x00"))
		ck(err)
	}

	syscall.Fsync(int(f.Fd()))
}
コード例 #19
0
ファイル: loopback_test.go プロジェクト: rvijax/camlistore
func (me *testCase) testFSync() {
	me.tester.Log("Testing fsync.")
	me.writeOrigFile()

	f, err := os.OpenFile(me.mountFile, os.O_WRONLY, 0)
	_, err = f.WriteString("hello there")
	CheckSuccess(err)

	// How to really test fsync ?
	errNo := syscall.Fsync(f.Fd())
	if errNo != 0 {
		me.tester.Errorf("fsync returned %v", errNo)
	}
	f.Close()
}
コード例 #20
0
ファイル: mkswap.go プロジェクト: qeedquan/misc_utilities
func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() != 1 {
		usage()
	}

	f, err := os.OpenFile(flag.Arg(0), os.O_RDWR, 0644)
	ck(err)
	defer f.Close()

	fi, err := f.Stat()
	ck(err)

	pagesize := syscall.Getpagesize()
	pages := fi.Size()/int64(pagesize) - 1

	var swap [8192]byte
	put4(swap[0:], 1)
	put4(swap[4:], uint32(pages))
	seek(f, 1024)
	uuid := createUUID()
	copy(swap[4*3:], uuid)
	if *label != "" {
		i := 0
		for ; i < len(*label) && i < 16; i++ {
			swap[7*4+i] = (*label)[i]
		}
		if i < 16 {
			swap[7*4+i] = 0
		}
	}
	write(f, swap[:129*4])
	seek(f, int64(pagesize)-10)
	write(f, []byte("SWAPSPACE2"))

	syscall.Fsync(int(f.Fd()))
	f.Close()

	var str string
	if *label != "" {
		str = fmt.Sprintf(", LABEL=%s", *label)
	}
	fmt.Printf("Swapspace size: %dk%s, UUID=%s\n",
		pages*(int64(pagesize)/1024), str, showUUID(uuid))
}
コード例 #21
0
ファイル: tree.go プロジェクト: klizhentas/acbuild
// Write renders the ACI with the provided key in the treestore
// Write, to avoid having a rendered ACI with old stale files, requires that
// the destination directory doesn't exist (usually Remove should be called
// before Write)
func (ts *TreeStore) Write(key string, s *Store) error {
	treepath := filepath.Join(ts.path, key)
	fi, _ := os.Stat(treepath)
	if fi != nil {
		return fmt.Errorf("treestore: path %s already exists", treepath)
	}
	imageID, err := types.NewHash(key)
	if err != nil {
		return fmt.Errorf("treestore: cannot convert key to imageID: %v", err)
	}
	if err := os.MkdirAll(treepath, 0755); err != nil {
		return fmt.Errorf("treestore: cannot create treestore directory %s: %v", treepath, err)
	}
	err = aci.RenderACIWithImageID(*imageID, treepath, s)
	if err != nil {
		return fmt.Errorf("treestore: cannot render aci: %v", err)
	}
	hash, err := ts.Hash(key)
	if err != nil {
		return fmt.Errorf("treestore: cannot calculate tree hash: %v", err)
	}
	err = ioutil.WriteFile(filepath.Join(treepath, hashfilename), []byte(hash), 0644)
	if err != nil {
		return fmt.Errorf("treestore: cannot write hash file: %v", err)
	}
	// before creating the "rendered" flag file we need to ensure that all data is fsynced
	dfd, err := syscall.Open(treepath, syscall.O_RDONLY, 0)
	if err != nil {
		return err
	}
	defer syscall.Close(dfd)
	if err := sys.Syncfs(dfd); err != nil {
		return fmt.Errorf("treestore: failed to sync data: %v", err)
	}
	// Create rendered file
	f, err := os.Create(filepath.Join(treepath, renderedfilename))
	if err != nil {
		return fmt.Errorf("treestore: failed to write rendered file: %v", err)
	}
	f.Close()

	if err := syscall.Fsync(dfd); err != nil {
		return fmt.Errorf("treestore: failed to sync tree store directory: %v", err)
	}
	return nil
}
コード例 #22
0
func TestFSync(t *testing.T) {
	me := NewTestCase(t)
	defer me.Cleanup()

	t.Log("Testing fsync.")
	me.writeOrigFile()

	f, err := os.OpenFile(me.mountFile, os.O_WRONLY, 0)
	_, err = f.WriteString("hello there")
	CheckSuccess(err)

	// How to really test fsync ?
	errNo := syscall.Fsync(f.Fd())
	if errNo != 0 {
		t.Errorf("fsync returned %v", errNo)
	}
	f.Close()
}
コード例 #23
0
ファイル: fuse_test.go プロジェクト: rsrsps/fuse
func (f *create1) test(path string, t *testing.T) {
	ff, err := os.Create(path + "/foo")
	if err != nil {
		t.Errorf("create1 WriteFile: %v", err)
		return
	}

	err = syscall.Fsync(int(ff.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}

	if !<-f.f.seen.fsync {
		t.Errorf("never received expected fsync call")
	}

	ff.Close()
}
コード例 #24
0
ファイル: loopback_test.go プロジェクト: niltonkummer/go-fuse
func TestFSync(t *testing.T) {
	tc := NewTestCase(t)
	defer tc.Cleanup()

	contents := []byte{1, 2, 3}
	err := ioutil.WriteFile(tc.origFile, []byte(contents), 0700)
	CheckSuccess(err)

	f, err := os.OpenFile(tc.mountFile, os.O_WRONLY, 0)
	_, err = f.WriteString("hello there")
	CheckSuccess(err)

	// How to really test fsync ?
	err = syscall.Fsync(int(f.Fd()))
	if err != nil {
		t.Errorf("fsync returned: %v", err)
	}
	f.Close()
}
コード例 #25
0
ファイル: fuse_test.go プロジェクト: kdevroede/camlistore
func (f *create1) test(path string, t *testing.T) {
	// uniform umask needed to make os.Create's 0666 into something
	// reproducible
	defer syscall.Umask(syscall.Umask(0022))
	ff, err := os.Create(path + "/foo")
	if err != nil {
		t.Errorf("create1 WriteFile: %v", err)
		return
	}

	err = syscall.Fsync(int(ff.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}

	if !<-f.f.seen.fsync {
		t.Errorf("never received expected fsync call")
	}

	ff.Close()
}
コード例 #26
0
ファイル: serve_test.go プロジェクト: djbarber/ipfs-hack
func TestWrite(t *testing.T) {
	t.Parallel()
	w := &write{}
	mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
	if err != nil {
		t.Fatal(err)
	}
	defer mnt.Close()

	f, err := os.Create(mnt.Dir + "/child")
	if err != nil {
		t.Fatalf("Create: %v", err)
	}
	defer f.Close()
	n, err := f.Write([]byte(hi))
	if err != nil {
		t.Fatalf("Write: %v", err)
	}
	if n != len(hi) {
		t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
	}

	err = syscall.Fsync(int(f.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}
	if w.RecordedFsync() == (fuse.FsyncRequest{}) {
		t.Errorf("never received expected fsync call")
	}

	err = f.Close()
	if err != nil {
		t.Fatalf("Close: %v", err)
	}

	if got := string(w.RecordedWriteData()); got != hi {
		t.Errorf("write = %q, want %q", got, hi)
	}
}
コード例 #27
0
ファイル: fuse_test.go プロジェクト: JayBlaze420/camlistore
func (f *create1) test(path string, t *testing.T) {
	f.name = ""
	ff, err := os.Create(path + "/foo")
	if err != nil {
		t.Errorf("create1 WriteFile: %v", err)
		return
	}

	err = syscall.Fsync(int(ff.Fd()))
	if err != nil {
		t.Fatalf("Fsync = %v", err)
	}

	if !f.f.gotfsync {
		t.Errorf("never received expected fsync call")
	}

	ff.Close()
	if f.name != "foo" {
		t.Errorf("create1 name=%q want foo", f.name)
	}
}
コード例 #28
0
ファイル: fsync.go プロジェクト: qeedquan/misc_utilities
func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		usage()
	}

	for _, name := range flag.Args() {
		f, err := os.OpenFile(name, syscall.O_RDONLY|syscall.O_NOATIME|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0644)
		if ek(err) {
			continue
		}

		if *dflag {
			err = syscall.Fdatasync(int(f.Fd()))
		} else {
			err = syscall.Fsync(int(f.Fd()))
		}
		ek(err)
		ek(f.Close())
	}
	os.Exit(status)
}
コード例 #29
0
ファイル: fsyncbench.go プロジェクト: ncw/fsyncbench
func main() {
	flag.Parse()
	out, err := ioutil.TempFile("", "fsyncbench")
	if err != nil {
		log.Fatal(err)
	}
	err = os.Remove(out.Name())
	if err != nil {
		log.Fatal(err)
	}
	fd := int(out.Fd())

	buf := []byte{'A'}
	N := *pN
	duration := time.Duration(0)
	for i := 0; i < N; i++ {
		_, err = out.Write(buf)
		if err != nil {
			log.Fatal(err)
		}
		start := time.Now()
		err = syscall.Fsync(fd)
		end := time.Now()
		duration += end.Sub(start)
		if err != nil {
			log.Fatal(err)
		}
	}

	log.Printf("That took %s for %d fsyncs", duration, N)
	log.Printf("That took %s per fsync", duration/time.Duration(N))

	err = out.Close()
	if err != nil {
		log.Fatal(err)
	}
}
コード例 #30
0
ファイル: utils_test.go プロジェクト: c0der007/llgo
func runFunction(m *llgo.Module, name string) (output []string, err error) {
	addExterns(m)
	err = addRuntime(m)
	if err != nil {
		return
	}

	err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		return
	}

	engine, err := llvm.NewJITCompiler(m.Module, 0)
	if err != nil {
		return
	}
	defer engine.Dispose()

	fn := engine.FindFunction(name)
	if fn.IsNil() {
		err = fmt.Errorf("Couldn't find function '%s'", name)
		return
	}

	// Redirect stdout to a pipe.
	pipe_fds := make([]int, 2)
	err = syscall.Pipe(pipe_fds)
	if err != nil {
		return
	}
	defer syscall.Close(pipe_fds[0])
	defer syscall.Close(pipe_fds[1])
	old_stdout, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Close(old_stdout)
	err = syscall.Dup2(pipe_fds[1], syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Dup2(old_stdout, syscall.Stdout)

	c := make(chan string)
	go readPipe(pipe_fds[0], c)

	exec_args := []llvm.GenericValue{}
	engine.RunStaticConstructors()
	engine.RunFunction(fn, exec_args)
	defer engine.RunStaticDestructors()

	// Call fflush to flush stdio (printf), then sync and close the write
	// end of the pipe.
	fflush := engine.FindFunction("fflush")
	ptr0 := unsafe.Pointer(uintptr(0))
	exec_args = []llvm.GenericValue{llvm.NewGenericValueFromPointer(ptr0)}
	engine.RunFunction(fflush, exec_args)
	syscall.Fsync(pipe_fds[1])
	syscall.Close(pipe_fds[1])
	syscall.Close(syscall.Stdout)

	output_str := <-c
	output = strings.Split(strings.TrimSpace(output_str), "\n")
	return
}