예제 #1
0
파일: main.go 프로젝트: rjkroege/devdraw
func main() {
	// I assume that in is 0
	in2, err := syscall.Dup(0)
	if err != nil {
		log.Fatal("dupping 0", err)
	}

	out2, err := syscall.Dup(1)
	if err != nil {
		log.Fatal("dupping 1", err)
	}

	os.Stdin.Close()
	os.Stdout.Close()
	os.Stdout = os.NewFile(uintptr(2), "/dev/stdout")

	/* Connections to the application. */
	cin := os.NewFile(uintptr(in2), "fromapp")
	cout := os.NewFile(uintptr(out2), "toapp")

	modifyEnvironment()

	// Fire up a new devdraw here
	devdraw, err := drawfcall.New()
	if err != nil {
		log.Fatal("making a Conn", err)
	}

	// There is probably a nicer way to do this.
	// TODO(rjkroege): do it the nicer way.
	var app App
	app.o = cout
	app.i = cin

	json := NewJsonRecorder()

	for {
		// read crap from cin
		log.Print("about to read from host")
		inbuffy, err := drawfcall.ReadMsg(cin)
		log.Print("read from host")
		if err != nil {
			devdraw.Close()
			break
		}
		go marshalsxtx(inbuffy, &app, devdraw, json)
	}

	log.Print("waiting on completion")
	json.WaitToComplete()
}
예제 #2
0
파일: io.go 프로젝트: lunixbochs/usercorn
func (k *PosixKernel) Dup(oldFd co.Fd) uint64 {
	if newFd, err := syscall.Dup(int(oldFd)); err != nil {
		return Errno(err)
	} else {
		return uint64(newFd)
	}
}
예제 #3
0
func (t *FlushErrorTest) Dup() {
	var err error

	// Open the file.
	t.f1, err = os.OpenFile(path.Join(t.Dir, "foo"), os.O_WRONLY, 0)
	AssertEq(nil, err)

	fd1 := t.f1.Fd()

	// Use dup(2) to get another copy.
	fd2, err := syscall.Dup(int(fd1))
	AssertEq(nil, err)

	t.f2 = os.NewFile(uintptr(fd2), t.f1.Name())

	// Close by the first handle. On OS X, where the semantics of file handles
	// are different (cf. https://github.com/osxfuse/osxfuse/issues/199), this
	// does not result in an error.
	err = t.f1.Close()
	t.f1 = nil

	if isDarwin {
		AssertEq(nil, err)
	} else {
		ExpectThat(err, Error(HasSubstr("no such file")))
	}

	// Close by the second handle.
	err = t.f2.Close()
	t.f2 = nil

	ExpectThat(err, Error(HasSubstr("no such file")))
}
예제 #4
0
파일: fd_plan9.go 프로젝트: Harvey-OS/go
func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
	dfd, err := syscall.Dup(int(f.Fd()), -1)
	if err != nil {
		return nil, os.NewSyscallError("dup", err)
	}
	return os.NewFile(uintptr(dfd), s), nil
}
예제 #5
0
파일: disk.go 프로젝트: houndbee/pond
func (sf *StateFile) Lock(create bool) (*Lock, error) {
	sf.lockFdMutex.Lock()
	defer sf.lockFdMutex.Unlock()

	if sf.lockFd != nil {
		return &Lock{sf.lockFd}, nil
	}

	flags := os.O_RDWR
	if create {
		flags |= os.O_CREATE | os.O_EXCL
	}
	file, err := os.OpenFile(sf.Path, flags, 0600)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	fd := int(file.Fd())
	newFd, err := syscall.Dup(fd)
	if err != nil {
		return nil, err
	}
	if syscall.Flock(newFd, syscall.LOCK_EX|syscall.LOCK_NB) != nil {
		syscall.Close(newFd)
		return nil, nil
	}
	sf.lockFd = &newFd
	return &Lock{sf.lockFd}, nil
}
예제 #6
0
func CaptureStream(file *os.File) (*os.File, func(), error) {
	pipeR, pipeW, err := os.Pipe()
	if err != nil {
		return nil, nil, err
	}

	bkupFD, err := syscall.Dup(int(file.Fd()))
	if err != nil {
		pipeW.Close()
		pipeR.Close()
		return nil, nil, err
	}

	err = syscall.Dup2(int(pipeW.Fd()), int(file.Fd()))
	if err != nil {
		syscall.Close(bkupFD)
		pipeW.Close()
		pipeR.Close()
	}

	cleanFunc := func() {
		syscall.Dup2(bkupFD, int(file.Fd()))
		syscall.Close(bkupFD)
		pipeW.Close()
		pipeR.Close()
	}

	return pipeR, cleanFunc, nil
}
예제 #7
0
func mount(mountPoint string, opts *MountOptions, ready chan<- error) (fd int, err error) {
	f, err := openFUSEDevice()
	if err != nil {
		return 0, err
	}

	cmd := exec.Command(bin, "-o", strings.Join(opts.optionsStrings(), ","), "-o", fmt.Sprintf("iosize=%d", opts.MaxWrite), "3", mountPoint)
	cmd.ExtraFiles = []*os.File{f}
	cmd.Env = append(os.Environ(), "MOUNT_FUSEFS_CALL_BY_LIB=", "MOUNT_OSXFUSE_CALL_BY_LIB=",
		"MOUNT_OSXFUSE_DAEMON_PATH="+os.Args[0],
		"MOUNT_FUSEFS_DAEMON_PATH="+os.Args[0])

	var out, errOut bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &errOut

	if err := cmd.Start(); err != nil {
		f.Close()
		return 0, err
	}
	go func() {
		err := cmd.Wait()
		if err != nil {
			err = fmt.Errorf("mount_osxfusefs failed: %v. Stderr: %s, Stdout: %s", err, errOut.String(), out.String())
		}

		ready <- err
		close(ready)
	}()

	// The finalizer for f will close its fd so we return a dup.
	defer f.Close()
	return syscall.Dup(int(f.Fd()))
}
예제 #8
0
func TestSendErrorFromChild(t *testing.T) {
	pipe, err := NewSyncPipe()
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := pipe.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	childfd, err := syscall.Dup(int(pipe.Child().Fd()))
	if err != nil {
		t.Fatal(err)
	}
	childPipe, _ := NewSyncPipeFromFd(0, uintptr(childfd))

	pipe.CloseChild()
	pipe.SendToChild(nil)

	expected := "something bad happened"
	childPipe.ReportChildError(fmt.Errorf(expected))

	childError := pipe.ReadFromChild()
	if childError == nil {
		t.Fatal("expected an error to be returned but did not receive anything")
	}

	if childError.Error() != expected {
		t.Fatalf("expected %q but received error message %q", expected, childError.Error())
	}
}
예제 #9
0
파일: shm.go 프로젝트: jsgilmore/shm
// NewBufferFile maps a file to shared memory and returns a handle to the shared memory buffer
func NewBufferFile(file *os.File, size, prot int) (Buffer, error) {
	fi, err := file.Stat()
	if err != nil {
		return nil, err
	}
	sys := fi.Sys().(*syscall.Stat_t)
	if sys.Size != int64(size) {
		return nil, errWrongSize
	}

	// Dup to allow file parameter to be closed regardless
	fd, err := syscall.Dup(int(file.Fd()))
	if err != nil {
		return nil, err
	}
	const flags = syscall.MAP_SHARED
	b, err := syscall.Mmap(fd, 0, size, prot, flags)
	if err != nil {
		return nil, err
	}

	// localFile is nil because fd is from somewhere else
	buf := &sharedBuffer{os.NewFile(uintptr(fd), ""), nil, b, stackToKeep()}
	runtime.SetFinalizer(buf, (*sharedBuffer).finalize)

	return buf, nil
}
예제 #10
0
파일: topology.go 프로젝트: ficoos/godirect
// Get topology data using blkid APIs. In case of an error getting any of the
// topology properties the field will be set to 0
func getBlockDeviceTopology(file File) (DeviceTopology, error) {
	var res DeviceTopology

	probe := C.blkid_new_probe()
	if probe == nil {
		return res, fmt.Errorf("Could not probe device")
	}
	C.blkid_reset_probe(probe)

	fd, err := syscall.Dup(int(file.Fd()))
	if err != nil {
		return res, fmt.Errorf("Could not dup FD as part of device probing: %s", err)
	}

	rv := C.blkid_probe_set_device(probe, C.int(fd), 0, 0)
	if rv != 0 {
		syscall.Close(fd)
	}

	defer C.blkid_free_probe(probe)

	topology := C.blkid_probe_get_topology(probe)
	if topology == nil {
		return res, fmt.Errorf("Could not get topology for device")
	}

	res.AlignmentOffset = uint64(C.blkid_topology_get_alignment_offset(topology))
	res.MinimumIOSize = uint64(C.blkid_topology_get_minimum_io_size(topology))
	res.OptimalIOSize = uint64(C.blkid_topology_get_optimal_io_size(topology))
	res.LogicalSectorSize = uint64(C.blkid_topology_get_logical_sector_size(topology))
	res.PhysicalSectorSize = uint64(C.blkid_topology_get_physical_sector_size(topology))
	return res, nil
}
예제 #11
0
func dup(file *os.File, name string) (newfile *os.File, err error) {
	fd, err := syscall.Dup(int(file.Fd()))
	if err != nil {
		return nil, err
	}

	return os.NewFile(uintptr(fd), "<stdin>"), nil
}
예제 #12
0
// DupFd returns the integer Unix file descriptor duplicated from Listener.
// This method can't invoke simultaneously.
func (l *Listener) DupFd() (int, error) {
	f, err := l.fileListener.File()
	if err != nil {
		return 0, err
	}

	return syscall.Dup(int(f.Fd()))
}
예제 #13
0
파일: file.go 프로젝트: funkygao/govtil
func newFileFD(f *os.File) (*netFD, error) {
	syscall.ForkLock.RLock()
	fd, err := syscall.Dup(int(f.Fd()))
	if err != nil {
		syscall.ForkLock.RUnlock()
		return nil, os.NewSyscallError("dup", err)
	}
	syscall.CloseOnExec(fd)
	syscall.ForkLock.RUnlock()

	sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
	if err != nil {
		closesocket(fd)
		return nil, os.NewSyscallError("getsockopt", err)
	}

	family := syscall.AF_UNSPEC
	toAddr := sockaddrToTCP
	sa, _ := syscall.Getsockname(fd)
	switch sa.(type) {
	default:
		closesocket(fd)
		return nil, syscall.EINVAL
	case *syscall.SockaddrInet4:
		family = syscall.AF_INET
		if sotype == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUDP
		} else if sotype == syscall.SOCK_RAW {
			toAddr = sockaddrToIP
		}
	case *syscall.SockaddrInet6:
		family = syscall.AF_INET6
		if sotype == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUDP
		} else if sotype == syscall.SOCK_RAW {
			toAddr = sockaddrToIP
		}
	case *syscall.SockaddrUnix:
		family = syscall.AF_UNIX
		toAddr = sockaddrToUnix
		if sotype == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUnixgram
		} else if sotype == syscall.SOCK_SEQPACKET {
			toAddr = sockaddrToUnixpacket
		}
	}
	laddr := toAddr(sa)
	sa, _ = syscall.Getpeername(fd)
	raddr := toAddr(sa)

	netfd, err := newFD(fd, family, sotype, laddr.Network())
	if err != nil {
		closesocket(fd)
		return nil, err
	}
	netfd.setAddr(laddr, raddr)
	return netfd, nil
}
예제 #14
0
파일: fd_plan9.go 프로젝트: varialus/godfly
func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
	syscall.ForkLock.RLock()
	dfd, err := syscall.Dup(int(f.Fd()), -1)
	syscall.ForkLock.RUnlock()
	if err != nil {
		return nil, &OpError{"dup", s, fd.laddr, err}
	}
	return os.NewFile(uintptr(dfd), s), nil
}
예제 #15
0
func newFileFD(f *os.File) (net *netFD, err error) {
	var ctl *os.File
	close := func(fd int) {
		if err != nil {
			syscall.Close(fd)
		}
	}

	path, err := syscall.Fd2path(int(f.Fd()))
	if err != nil {
		return nil, os.NewSyscallError("fd2path", err)
	}
	comp := splitAtBytes(path, "/")
	n := len(comp)
	if n < 3 || comp[0] != "net" {
		return nil, syscall.EPLAN9
	}

	name := comp[2]
	switch file := comp[n-1]; file {
	case "ctl", "clone":
		syscall.ForkLock.RLock()
		fd, err := syscall.Dup(int(f.Fd()), -1)
		syscall.ForkLock.RUnlock()
		if err != nil {
			return nil, os.NewSyscallError("dup", err)
		}
		defer close(fd)

		dir := "/net/" + comp[n-2]
		ctl = os.NewFile(uintptr(fd), dir+"/"+file)
		ctl.Seek(0, 0)
		var buf [16]byte
		n, err := ctl.Read(buf[:])
		if err != nil {
			return nil, err
		}
		name = string(buf[:n])
	default:
		if len(comp) < 4 {
			return nil, errors.New("could not find control file for connection")
		}
		dir := "/net/" + comp[1] + "/" + name
		ctl, err = os.OpenFile(dir+"/ctl", os.O_RDWR, 0)
		if err != nil {
			return nil, err
		}
		defer close(int(ctl.Fd()))
	}
	dir := "/net/" + comp[1] + "/" + name
	laddr, err := readPlan9Addr(comp[1], dir+"/local")
	if err != nil {
		return nil, err
	}
	return newFD(comp[1], name, ctl, nil, laddr, nil), nil
}
예제 #16
0
파일: fd_unix.go 프로젝트: duhaibo0404/go-1
// dupCloseOnExecUnixOld is the traditional way to dup an fd and
// set its O_CLOEXEC bit, using two system calls.
func dupCloseOnExecOld(fd int) (newfd int, err error) {
	syscall.ForkLock.RLock()
	defer syscall.ForkLock.RUnlock()
	newfd, err = syscall.Dup(fd)
	if err != nil {
		return -1, os.NewSyscallError("dup", err)
	}
	syscall.CloseOnExec(newfd)
	return
}
예제 #17
0
func Test_println(t *testing.T) {
	cleanup1 := testutils.Chtemp()
	defer cleanup1()

	rfile, err := os.Create("stdout")
	if err != nil {
		panic(err)
	}

	// save a copy of stdout in another fd
	stdout_fd := int(os.Stdout.Fd())
	save_stdout, err := syscall.Dup(stdout_fd)
	if err != nil {
		panic(err)
	}

	// redirect stdout to rfile
	err = syscall.Dup2(int(rfile.Fd()), stdout_fd)
	if err != nil {
		panic(err)
	}

	cleanup2 := func() {
		rfile.Close()
		err = syscall.Dup2(save_stdout, stdout_fd)
		if err != nil {
			panic(err)
		}
		syscall.Close(save_stdout)
	}
	defer cleanup2()

	args := RuntimeArgs{
		BasicArgs: types.MakeBasicArgs(nil, []types.FuObject{}, nil),
	}

	result, errs := fn_println(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	data, err := ioutil.ReadFile("stdout")
	assert.Nil(t, err)
	assert.Equal(t, "\n", string(data))
	rfile.Truncate(0)
	rfile.Seek(0, 0)

	args.SetArgs(types.MakeStringList("hello", "world").List())
	fn_println(args)
	data, err = ioutil.ReadFile("stdout")
	assert.Nil(t, err)
	assert.Equal(t, "hello world\n", string(data))
	rfile.Truncate(0)
	rfile.Seek(0, 0)
}
예제 #18
0
파일: disk.go 프로젝트: radii/pond
// LockStateFile attempts to lock the given file. If successful, it returns
// true and the lock persists for the lifetime of the process.
func LockStateFile(stateFile *os.File) (*Lock, bool) {
	fd := int(stateFile.Fd())
	newFd, err := syscall.Dup(fd)
	if err != nil {
		panic(err)
	}
	if syscall.Flock(newFd, syscall.LOCK_EX|syscall.LOCK_NB) != nil {
		syscall.Close(newFd)
		return nil, false
	}
	return &Lock{newFd}, true
}
예제 #19
0
파일: read_test.go 프로젝트: ncw/rclone
// Test double close
func TestReadFileDoubleClose(t *testing.T) {
	run.skipIfNoFUSE(t)

	run.createFile(t, "testdoubleclose", "hello")

	in, err := os.Open(run.path("testdoubleclose"))
	assert.NoError(t, err)
	fd := in.Fd()

	fd1, err := syscall.Dup(int(fd))
	assert.NoError(t, err)

	fd2, err := syscall.Dup(int(fd))
	assert.NoError(t, err)

	// close one of the dups - should produce no error
	err = syscall.Close(fd1)
	assert.NoError(t, err)

	// read from the file
	buf := make([]byte, 1)
	_, err = in.Read(buf)
	assert.NoError(t, err)

	// close it
	err = in.Close()
	assert.NoError(t, err)

	// read from the other dup - should produce no error as this
	// file is now buffered
	n, err := syscall.Read(fd2, buf)
	assert.NoError(t, err)
	assert.Equal(t, 1, n)

	// close the dup - should not produce an error
	err = syscall.Close(fd2)
	assert.NoError(t, err, "input/output error")

	run.rm(t, "testdoubleclose")
}
예제 #20
0
func (k *PosixKernel) Mmap(addrHint, size uint64, prot, flags int, fd co.Fd, off co.Off) uint64 {
	addr, _ := k.U.Mmap(addrHint, size)
	if fd > 0 {
		fd2, _ := syscall.Dup(int(fd))
		f := os.NewFile(uintptr(fd2), "")
		f.Seek(int64(off), 0)
		tmp := make([]byte, size)
		n, _ := f.Read(tmp)
		k.U.MemWrite(addr, tmp[:n])
		syscall.Close(fd2)
	}
	return addr
}
예제 #21
0
파일: node.go 프로젝트: rizki96/kakigoori
func (f *AzukiFile) Flush() fuse.Status {
	f.lock.Lock()
	newFd, err := syscall.Dup(int(f.File.Fd()))
	f.lock.Unlock()

	if err != nil {
		return fuse.ToStatus(err)
	}

	err = syscall.Close(newFd)

	return fuse.ToStatus(err)
}
예제 #22
0
파일: fd.go 프로젝트: WXB506/golang
func (fd *netFD) dup() (f *os.File, err os.Error) {
	ns, e := syscall.Dup(fd.sysfd)
	if e != 0 {
		return nil, &OpError{"dup", fd.net, fd.laddr, os.Errno(e)}
	}

	// We want blocking mode for the new fd, hence the double negative.
	if e = syscall.SetNonblock(ns, false); e != 0 {
		return nil, &OpError{"setnonblock", fd.net, fd.laddr, os.Errno(e)}
	}

	return os.NewFile(ns, fd.sysfile.Name()), nil
}
예제 #23
0
파일: fd.go 프로젝트: rgmabs19357/gcc
func (fd *netFD) dup() (f *os.File, err error) {
	ns, err := syscall.Dup(fd.sysfd)
	if err != nil {
		return nil, &OpError{"dup", fd.net, fd.laddr, err}
	}

	// We want blocking mode for the new fd, hence the double negative.
	if err = syscall.SetNonblock(ns, false); err != nil {
		return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
	}

	return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil
}
예제 #24
0
파일: file.go 프로젝트: aubonbeurre/gcc
func newFileFD(f *os.File) (nfd *netFD, err error) {
	fd, errno := syscall.Dup(f.Fd())
	if errno != 0 {
		return nil, os.NewSyscallError("dup", errno)
	}

	proto, errno := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
	if errno != 0 {
		return nil, os.NewSyscallError("getsockopt", errno)
	}

	family := syscall.AF_UNSPEC
	toAddr := sockaddrToTCP
	sa, _ := syscall.Getsockname(fd)
	switch sa.(type) {
	default:
		closesocket(fd)
		return nil, os.EINVAL
	case *syscall.SockaddrInet4:
		family = syscall.AF_INET
		if proto == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUDP
		} else if proto == syscall.SOCK_RAW {
			toAddr = sockaddrToIP
		}
	case *syscall.SockaddrInet6:
		family = syscall.AF_INET6
		if proto == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUDP
		} else if proto == syscall.SOCK_RAW {
			toAddr = sockaddrToIP
		}
	case *syscall.SockaddrUnix:
		family = syscall.AF_UNIX
		toAddr = sockaddrToUnix
		if proto == syscall.SOCK_DGRAM {
			toAddr = sockaddrToUnixgram
		} else if proto == syscall.SOCK_SEQPACKET {
			toAddr = sockaddrToUnixpacket
		}
	}
	laddr := toAddr(sa)
	sa, _ = syscall.Getpeername(fd)
	raddr := toAddr(sa)

	if nfd, err = newFD(fd, family, proto, laddr.Network()); err != nil {
		return nil, err
	}
	nfd.setAddr(laddr, raddr)
	return nfd, nil
}
예제 #25
0
파일: syscalls.go 프로젝트: eqv/usercorn
func mmap(u U, a []uint64) uint64 {
	addr_hint, size, prot, flags, fd, off := a[0], a[1], a[2], a[3], int(int32(a[4])), int64(a[5])
	prot, flags = flags, prot // ignore go error
	addr, _ := u.Mmap(addr_hint, size)
	if fd > 0 {
		fd2, _ := syscall.Dup(fd)
		f := os.NewFile(uintptr(fd2), "")
		f.Seek(off, 0)
		tmp := make([]byte, size)
		n, _ := f.Read(tmp)
		u.MemWrite(addr, tmp[:n])
	}
	return uint64(addr)
}
예제 #26
0
// Test double close
func TestWriteFileDoubleClose(t *testing.T) {
	run.skipIfNoFUSE(t)

	out, err := os.Create(run.path("testdoubleclose"))
	assert.NoError(t, err)
	fd := out.Fd()

	fd1, err := syscall.Dup(int(fd))
	assert.NoError(t, err)

	fd2, err := syscall.Dup(int(fd))
	assert.NoError(t, err)

	// close one of the dups - should produce no error
	err = syscall.Close(fd1)
	assert.NoError(t, err)

	// write to the file
	buf := []byte("hello")
	n, err := out.Write(buf)
	assert.NoError(t, err)
	assert.Equal(t, 5, n)

	// close it
	err = out.Close()
	assert.NoError(t, err)

	// write to the other dup - should produce an error
	n, err = syscall.Write(fd2, buf)
	assert.Error(t, err, "input/output error")

	// close the dup - should produce an error
	err = syscall.Close(fd2)
	assert.Error(t, err, "input/output error")

	run.rm(t, "testdoubleclose")
}
예제 #27
0
파일: files.go 프로젝트: y-okubo/go-fuse
func (f *loopbackFile) Flush() fuse.Status {
	f.lock.Lock()

	// Since Flush() may be called for each dup'd fd, we don't
	// want to really close the file, we just want to flush. This
	// is achieved by closing a dup'd fd.
	newFd, err := syscall.Dup(int(f.File.Fd()))
	f.lock.Unlock()

	if err != nil {
		return fuse.ToStatus(err)
	}
	err = syscall.Close(newFd)
	return fuse.ToStatus(err)
}
예제 #28
0
func (_entity *Entity) HashData(_hasher1 hasher.Hasher) (_hash []byte, _error Error) {
	if !_entity.IsRegular() {
		return nil, newError("dup", _entity.Path, -1, syscall.EBADF)
	}
	var _descriptor, _errno int
	_descriptor = _entity.Descriptor
	if _descriptor < 0 {
		return nil, newError("dup", _entity.Path, _entity.Descriptor, syscall.EBADF)
	}
	_descriptor, _errno = syscall.Dup(_descriptor)
	if _errno != 0 {
		return nil, newError("dup", _entity.Path, _entity.Descriptor, _errno)
	}
	defer syscall.Close(_descriptor)
	_, _errno = syscall.Seek(_descriptor, 0, 0 /* syscall.SEEK_SET */)
	if _errno != 0 {
		return nil, newError("seek", _entity.Path, _descriptor, _errno)
	}
	_hasher := _hasher1.Create()
	_buffer := make([]byte, _bufferSize)
	for {
		var _limit int
		_limit, _errno = syscall.Read(_descriptor, _buffer)
		if _errno != 0 {
			return nil, newError("read", _entity.Path, _descriptor, _errno)
		}
		if _limit == 0 {
			break
		}
		_error = hasher.HashUpdate(_hasher, _buffer[:_limit])
		if _error != nil {
			return nil, newError("hash", _entity.Path, _descriptor, syscall.EIO)
		}
	}
	_hash, _error = hasher.HashFinalize(_hasher)
	if _error != nil {
		return nil, newError("hash", _entity.Path, _descriptor, syscall.EIO)
	}
	if _entity.Hashes == nil {
		_entity.Hashes = make(map[string][]byte, 1)
	}
	_entity.Hashes[_hasher1.Identifier()] = _hash
	return _hash, nil
}
예제 #29
0
파일: dir_haiku.go 프로젝트: korli/go
func (file *File) readdirnames(n int) (names []string, err error) {
	size := n
	if size <= 0 {
		size = 100
		n = -1
	}

	names = make([]string, 0, size) // Empty with room to grow.

	dirfd, err := syscall.Dup(file.fd)
	if err != nil {
		return names, err
	}
	dir, err := syscall.Fdopendir(dirfd)
	if err != nil {
		return names, err
	}
	defer syscall.Closedir(dir)
	var result *syscall.Dirent = nil
	entry := syscall.Dirent{}
	for n != 0 {
		status := syscall.Readdir_r(dir, &entry, &result)
		if status != 0 {
			return names, syscall.Errno(status)
		}
		if result == nil {
			break
		}
		if result.Ino == 0 { // File absent in directory
			continue
		}
		bytes := (*[10000]byte)(unsafe.Pointer(&result.Name[0]))
		name := string(bytes[0:clen(bytes[:])])
		if name == "." || name == ".." {
			// considered "Useless names" by ParseDirent
			continue
		}
		names = append(names, name)
		n--
	}
	return names, err
}
예제 #30
0
func (fd *netFD) dup() (f *os.File, err error) {
	syscall.ForkLock.RLock()
	ns, err := syscall.Dup(fd.sysfd)
	if err != nil {
		syscall.ForkLock.RUnlock()
		return nil, &OpError{"dup", fd.net, fd.laddr, err}
	}
	syscall.CloseOnExec(ns)
	syscall.ForkLock.RUnlock()

	// We want blocking mode for the new fd, hence the double negative.
	// This also puts the old fd into blocking mode, meaning that
	// I/O will block the thread instead of letting us use the epoll server.
	// Everything will still work, just with more threads.
	if err = syscall.SetNonblock(ns, false); err != nil {
		return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
	}

	return os.NewFile(uintptr(ns), fd.name()), nil
}