Commit a25a48d9 authored by Ivan Krasin's avatar Ivan Krasin

Apply patch

parent 8aec84bc
...@@ -155,7 +155,8 @@ func serialize(h *InHeader, res Status, out interface{}) (data [][]byte) { ...@@ -155,7 +155,8 @@ func serialize(h *InHeader, res Status, out interface{}) (data [][]byte) {
panic(fmt.Sprintf("Can't serialize out: %v, err: %v", out, err)) panic(fmt.Sprintf("Can't serialize out: %v, err: %v", out, err))
} }
} }
fmt.Printf("out_data: %v, len(out_data): %d, SizeOfOutHeader: %d\n", out_data, len(out_data), SizeOfOutHeader) fmt.Printf("out_data: %v, len(out_data): %d, SizeOfOutHeader: %d\n",
out_data, len(out_data), SizeOfOutHeader)
var hout OutHeader var hout OutHeader
hout.Unique = h.Unique hout.Unique = h.Unique
hout.Status = res hout.Status = res
......
package fuse package fuse
import ( import (
"fmt"
"log" "log"
"os" "os"
"strings" "strings"
...@@ -59,14 +60,13 @@ func (f *testFile) Close() (status Status) { ...@@ -59,14 +60,13 @@ func (f *testFile) Close() (status Status) {
func errorHandler(errors chan os.Error) { func errorHandler(errors chan os.Error) {
for err := range errors { for err := range errors {
log.Stderr("MountPoint.errorHandler: ", err) log.Println("MountPoint.errorHandler: ", err)
if err == os.EOF { if err == os.EOF {
break break
} }
} }
} }
func TestMount(t *testing.T) { func TestMount(t *testing.T) {
fs := new(testFuse) fs := new(testFuse)
...@@ -85,7 +85,9 @@ func TestMount(t *testing.T) { ...@@ -85,7 +85,9 @@ func TestMount(t *testing.T) {
t.Fatalf("Can't unmount a dir, err: %v", err) t.Fatalf("Can't unmount a dir, err: %v", err)
} }
}() }()
errorHandler(errors)
// ugh - error handling should be method of testfuse instead?
go errorHandler(errors)
f, err := os.Open(tempMountDir, os.O_RDONLY, 0) f, err := os.Open(tempMountDir, os.O_RDONLY, 0)
if err != nil { if err != nil {
t.Fatalf("Can't open a dir: %s, err: %v", tempMountDir, err) t.Fatalf("Can't open a dir: %s, err: %v", tempMountDir, err)
......
...@@ -4,18 +4,41 @@ package fuse ...@@ -4,18 +4,41 @@ package fuse
import ( import (
"fmt" "fmt"
"net"
"os" "os"
"path" "path"
"syscall" "syscall"
"unsafe" "unsafe"
) )
// Make a type to attach the Unmount method.
type mounted string type mounted string
func Socketpair(network string) (l, r *os.File, err os.Error) {
var domain int
var typ int
switch network {
default:
panic("unknown network " + network)
case "unix":
domain = syscall.AF_UNIX
typ = syscall.SOCK_STREAM
case "unixgram":
domain = syscall.AF_UNIX
typ = syscall.SOCK_SEQPACKET
}
fd, errno := syscall.Socketpair(domain, typ, 0)
if errno != 0 {
return nil, nil, os.NewSyscallError("socketpair", errno)
}
l = os.NewFile(fd[0], "socketpair-half1")
r = os.NewFile(fd[1], "socketpair-half2")
return
}
// Mount create a fuse fs on the specified mount point. // Mount create a fuse fs on the specified mount point.
func mount(mountPoint string) (f *os.File, m mounted, err os.Error) { func mount(mountPoint string) (f *os.File, m mounted, err os.Error) {
local, remote, err := net.Socketpair("unixgram") local, remote, err := Socketpair("unixgram")
if err != nil { if err != nil {
return return
} }
...@@ -35,7 +58,7 @@ func mount(mountPoint string) (f *os.File, m mounted, err os.Error) { ...@@ -35,7 +58,7 @@ func mount(mountPoint string) (f *os.File, m mounted, err os.Error) {
[]string{"/bin/fusermount", mountPoint}, []string{"/bin/fusermount", mountPoint},
[]string{"_FUSE_COMMFD=3"}, []string{"_FUSE_COMMFD=3"},
"", "",
[]*os.File{nil, nil, nil, remote.File()}) []*os.File{nil, nil, nil, remote})
if err != nil { if err != nil {
return return
} }
...@@ -73,24 +96,6 @@ func (m mounted) Unmount() (err os.Error) { ...@@ -73,24 +96,6 @@ func (m mounted) Unmount() (err os.Error) {
return return
} }
func recvmsg(fd int, msg *syscall.Msghdr, flags int) (n int, errno int) {
n1, _, e1 := syscall.Syscall(syscall.SYS_RECVMSG, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags))
n = int(n1)
errno = int(e1)
return
}
func Recvmsg(fd int, msg *syscall.Msghdr, flags int) (n int, err os.Error) {
n, errno := recvmsg(fd, msg, flags)
if n == 0 && errno == 0 {
return 0, os.EOF
}
if errno != 0 {
err = os.NewSyscallError("recvmsg", errno)
}
return
}
func writev(fd int, iovecs *syscall.Iovec, cnt int) (n int, errno int) { func writev(fd int, iovecs *syscall.Iovec, cnt int) (n int, errno int) {
n1, _, e1 := syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(iovecs)), uintptr(cnt)) n1, _, e1 := syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(iovecs)), uintptr(cnt))
n = int(n1) n = int(n1)
...@@ -108,7 +113,7 @@ func Writev(fd int, packet [][]byte) (n int, err os.Error) { ...@@ -108,7 +113,7 @@ func Writev(fd int, packet [][]byte) (n int, err os.Error) {
continue continue
} }
iovecs[i].Base = (*byte)(unsafe.Pointer(&packet[i][0])) iovecs[i].Base = (*byte)(unsafe.Pointer(&packet[i][0]))
iovecs[i].Len = uint64(len(packet[i])) iovecs[i].SetLen(len(packet[i]))
} }
n, errno := writev(fd, (*syscall.Iovec)(unsafe.Pointer(&iovecs[0])), len(iovecs)) n, errno := writev(fd, (*syscall.Iovec)(unsafe.Pointer(&iovecs[0])), len(iovecs))
...@@ -119,32 +124,35 @@ func Writev(fd int, packet [][]byte) (n int, err os.Error) { ...@@ -119,32 +124,35 @@ func Writev(fd int, packet [][]byte) (n int, err os.Error) {
return return
} }
func getFuseConn(local net.Conn) (f *os.File, err os.Error) { func getInt32(b []byte, idx int) int32 {
var msg syscall.Msghdr ptr := (*int32)(unsafe.Pointer(&b[idx*4]))
var iov syscall.Iovec return *ptr
base := make([]int32, 256) }
control := make([]int32, 256)
iov.Base = (*byte)(unsafe.Pointer(&base[0]))
iov.Len = uint64(len(base) * 4)
msg.Iov = (*syscall.Iovec)(unsafe.Pointer(&iov))
msg.Iovlen = 1
msg.Control = (*byte)(unsafe.Pointer(&control[0]))
msg.Controllen = uint64(len(control) * 4)
_, err = Recvmsg(local.File().Fd(), &msg, 0) func getFuseConn(local *os.File) (f *os.File, err os.Error) {
if err != nil { var data [4]byte
control := make([]byte, 4*256)
// n, oobn, recvflags - todo: error checking.
_, oobn, _,
errno := syscall.Recvmsg(
local.Fd(), data[:], control[:], 0)
if errno != 0 {
return return
} }
length := getInt32(control, 0)
// 1 = level.
typ := getInt32(control, 2) // syscall.Cmsghdr.Type
length := control[0] // Ugh - is this 64-bit proof?
typ := control[2] // syscall.Cmsghdr.Type fd := getInt32(control, 3)
fd := control[4]
if typ != 1 { if typ != 1 {
err = os.NewError(fmt.Sprintf("getFuseConn: recvmsg returned wrong control type: %d", typ)) err = os.NewError(fmt.Sprintf("getFuseConn: recvmsg returned wrong control type: %d", typ))
return return
} }
if length < 20 { if oobn < 16 {
err = os.NewError(fmt.Sprintf("getFuseConn: too short control message. Length: %d", length)) err = os.NewError(fmt.Sprintf("getFuseConn: too short control message. Length: %d", length))
return return
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment