Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Levin Zimmermann
go-fuse
Commits
1bb5cc5e
Commit
1bb5cc5e
authored
Aug 13, 2010
by
Ivan Krasin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
splitted mount.go and fuse.go
parent
9f3e25d0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
173 additions
and
162 deletions
+173
-162
fuse/Makefile
fuse/Makefile
+1
-0
fuse/fuse.go
fuse/fuse.go
+10
-162
fuse/mount.go
fuse/mount.go
+162
-0
No files found.
fuse/Makefile
View file @
1bb5cc5e
...
...
@@ -5,6 +5,7 @@ TARG=github.com/krasin/go-fuse-zip/fuse
GOFILES
=
\
fuse.go
\
mount.go
\
types.go
\
include
$(GOROOT)/src/Make.pkg
...
...
fuse/fuse.go
View file @
1bb5cc5e
...
...
@@ -6,15 +6,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"net"
"os"
"path"
"syscall"
"unsafe"
)
const
(
bufSize
=
66000
)
type
FileSystem
interface
{
...
...
@@ -22,66 +14,28 @@ type FileSystem interface {
GetAttr
(
h
*
InHeader
,
in
*
GetAttrIn
)
(
out
*
AttrOut
,
code
Error
)
}
type
MountPoint
struct
{
mountPoint
string
f
*
os
.
File
fs
FileSystem
}
var
was
bool
// Mount create a fuse fs on the specified mount point.
func
Mount
(
mountPoint
string
,
fs
FileSystem
)
(
m
*
MountPoint
,
err
os
.
Error
,
errors
chan
os
.
Error
)
{
local
,
remote
,
err
:=
net
.
Socketpair
(
"unixgram"
)
if
err
!=
nil
{
return
}
defer
local
.
Close
()
defer
remote
.
Close
()
mountPoint
=
path
.
Clean
(
mountPoint
)
if
!
path
.
Rooted
(
mountPoint
)
{
cwd
,
err
:=
os
.
Getwd
()
if
err
!=
nil
{
return
}
mountPoint
=
path
.
Clean
(
path
.
Join
(
cwd
,
mountPoint
))
}
pid
,
err
:=
os
.
ForkExec
(
"/bin/fusermount"
,
[]
string
{
"/bin/fusermount"
,
mountPoint
},
[]
string
{
"_FUSE_COMMFD=3"
},
""
,
[]
*
os
.
File
{
nil
,
nil
,
nil
,
remote
.
File
()})
if
err
!=
nil
{
return
}
w
,
err
:=
os
.
Wait
(
pid
,
0
)
if
err
!=
nil
{
return
}
if
w
.
ExitStatus
()
!=
0
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"fusermount exited with code %d
\n
"
,
w
.
ExitStatus
()))
return
}
type
Mounted
interface
{
Unmount
()
(
err
os
.
Error
)
}
f
,
err
:=
getFuseConn
(
local
)
func
Mount
(
mountPoint
string
,
fs
FileSystem
)
(
m
Mounted
,
err
os
.
Error
,
errors
chan
os
.
Error
)
{
f
,
m
,
err
:=
mount
(
mountPoint
)
if
err
!=
nil
{
return
}
m
=
&
MountPoint
{
mountPoint
,
f
,
fs
}
errors
=
make
(
chan
os
.
Error
,
100
)
go
m
.
loop
(
errors
)
go
loop
(
f
,
fs
,
errors
)
return
}
func
(
m
*
MountPoint
)
loop
(
errors
chan
os
.
Error
)
{
func
loop
(
f
*
os
.
File
,
fs
FileSystem
,
errors
chan
os
.
Error
)
{
buf
:=
make
([]
byte
,
bufSize
)
f
:=
m
.
f
defer
close
(
errors
)
toW
:=
make
(
chan
[][]
byte
,
100
)
defer
close
(
toW
)
go
m
.
writer
(
f
,
toW
,
errors
)
go
writer
(
f
,
toW
,
errors
)
for
{
n
,
err
:=
f
.
Read
(
buf
)
if
err
==
os
.
EOF
{
...
...
@@ -92,7 +46,7 @@ func (m *MountPoint) loop(errors chan os.Error) {
break
}
handle
(
m
.
fs
,
buf
[
0
:
n
],
toW
,
errors
)
handle
(
fs
,
buf
[
0
:
n
],
toW
,
errors
)
}
}
...
...
@@ -230,7 +184,7 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
toW
<-
[][]
byte
{
b
.
Bytes
()}
}
func
(
m
*
MountPoint
)
writer
(
f
*
os
.
File
,
in
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
func
writer
(
f
*
os
.
File
,
in
chan
[][]
byte
,
errors
chan
os
.
Error
)
{
fd
:=
f
.
Fd
()
for
packet
:=
range
in
{
fmt
.
Printf
(
"writer, packet: %v
\n
"
,
packet
)
...
...
@@ -243,109 +197,3 @@ func (m *MountPoint) writer(f *os.File, in chan [][]byte, errors chan os.Error)
}
}
func
(
m
*
MountPoint
)
Unmount
()
(
err
os
.
Error
)
{
if
m
==
nil
{
return
nil
}
pid
,
err
:=
os
.
ForkExec
(
"/bin/fusermount"
,
[]
string
{
"/bin/fusermount"
,
"-u"
,
m
.
mountPoint
},
nil
,
""
,
[]
*
os
.
File
{
nil
,
nil
,
os
.
Stderr
})
if
err
!=
nil
{
return
}
w
,
err
:=
os
.
Wait
(
pid
,
0
)
if
err
!=
nil
{
return
}
if
w
.
ExitStatus
()
!=
0
{
return
os
.
NewError
(
fmt
.
Sprintf
(
"fusermount exited with code %d
\n
"
,
w
.
ExitStatus
()))
}
m
.
f
.
Close
()
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
)
{
n1
,
_
,
e1
:=
syscall
.
Syscall
(
syscall
.
SYS_WRITEV
,
uintptr
(
fd
),
uintptr
(
unsafe
.
Pointer
(
iovecs
)),
uintptr
(
cnt
))
n
=
int
(
n1
)
errno
=
int
(
e1
)
return
}
func
Writev
(
fd
int
,
packet
[][]
byte
)
(
n
int
,
err
os
.
Error
)
{
if
len
(
packet
)
==
0
{
return
}
iovecs
:=
make
([]
syscall
.
Iovec
,
len
(
packet
))
for
i
,
v
:=
range
packet
{
if
v
==
nil
{
continue
}
iovecs
[
i
]
.
Base
=
(
*
byte
)(
unsafe
.
Pointer
(
&
packet
[
i
][
0
]))
iovecs
[
i
]
.
Len
=
uint64
(
len
(
packet
[
i
]))
}
n
,
errno
:=
writev
(
fd
,
(
*
syscall
.
Iovec
)(
unsafe
.
Pointer
(
&
iovecs
[
0
])),
len
(
iovecs
))
if
errno
!=
0
{
err
=
os
.
NewSyscallError
(
"writev"
,
errno
)
return
}
return
}
func
getFuseConn
(
local
net
.
Conn
)
(
f
*
os
.
File
,
err
os
.
Error
)
{
var
msg
syscall
.
Msghdr
var
iov
syscall
.
Iovec
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
)
if
err
!=
nil
{
return
}
length
:=
control
[
0
]
typ
:=
control
[
2
]
// syscall.Cmsghdr.Type
fd
:=
control
[
4
]
if
typ
!=
1
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: recvmsg returned wrong control type: %d"
,
typ
))
return
}
if
length
<
20
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: too short control message. Length: %d"
,
length
))
return
}
if
fd
<
0
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: fd < 0: %d"
,
fd
))
return
}
f
=
os
.
NewFile
(
int
(
fd
),
"fuse-conn"
)
return
}
fuse/mount.go
0 → 100644
View file @
1bb5cc5e
package
fuse
// Written with a look to http://ptspts.blogspot.com/2009/11/fuse-protocol-tutorial-for-linux-26.html
import
(
"fmt"
"net"
"os"
"path"
"syscall"
"unsafe"
)
const
(
bufSize
=
66000
)
type
mounted
string
// Mount create a fuse fs on the specified mount point.
func
mount
(
mountPoint
string
)
(
f
*
os
.
File
,
m
mounted
,
err
os
.
Error
)
{
local
,
remote
,
err
:=
net
.
Socketpair
(
"unixgram"
)
if
err
!=
nil
{
return
}
defer
local
.
Close
()
defer
remote
.
Close
()
mountPoint
=
path
.
Clean
(
mountPoint
)
if
!
path
.
Rooted
(
mountPoint
)
{
cwd
,
err
:=
os
.
Getwd
()
if
err
!=
nil
{
return
}
mountPoint
=
path
.
Clean
(
path
.
Join
(
cwd
,
mountPoint
))
}
pid
,
err
:=
os
.
ForkExec
(
"/bin/fusermount"
,
[]
string
{
"/bin/fusermount"
,
mountPoint
},
[]
string
{
"_FUSE_COMMFD=3"
},
""
,
[]
*
os
.
File
{
nil
,
nil
,
nil
,
remote
.
File
()})
if
err
!=
nil
{
return
}
w
,
err
:=
os
.
Wait
(
pid
,
0
)
if
err
!=
nil
{
return
}
if
w
.
ExitStatus
()
!=
0
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"fusermount exited with code %d
\n
"
,
w
.
ExitStatus
()))
return
}
f
,
err
=
getFuseConn
(
local
)
m
=
mounted
(
mountPoint
)
return
}
func
(
m
mounted
)
Unmount
()
(
err
os
.
Error
)
{
mountPoint
:=
string
(
m
)
pid
,
err
:=
os
.
ForkExec
(
"/bin/fusermount"
,
[]
string
{
"/bin/fusermount"
,
"-u"
,
mountPoint
},
nil
,
""
,
[]
*
os
.
File
{
nil
,
nil
,
os
.
Stderr
})
if
err
!=
nil
{
return
}
w
,
err
:=
os
.
Wait
(
pid
,
0
)
if
err
!=
nil
{
return
}
if
w
.
ExitStatus
()
!=
0
{
return
os
.
NewError
(
fmt
.
Sprintf
(
"fusermount exited with code %d
\n
"
,
w
.
ExitStatus
()))
}
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
)
{
n1
,
_
,
e1
:=
syscall
.
Syscall
(
syscall
.
SYS_WRITEV
,
uintptr
(
fd
),
uintptr
(
unsafe
.
Pointer
(
iovecs
)),
uintptr
(
cnt
))
n
=
int
(
n1
)
errno
=
int
(
e1
)
return
}
func
Writev
(
fd
int
,
packet
[][]
byte
)
(
n
int
,
err
os
.
Error
)
{
if
len
(
packet
)
==
0
{
return
}
iovecs
:=
make
([]
syscall
.
Iovec
,
len
(
packet
))
for
i
,
v
:=
range
packet
{
if
v
==
nil
{
continue
}
iovecs
[
i
]
.
Base
=
(
*
byte
)(
unsafe
.
Pointer
(
&
packet
[
i
][
0
]))
iovecs
[
i
]
.
Len
=
uint64
(
len
(
packet
[
i
]))
}
n
,
errno
:=
writev
(
fd
,
(
*
syscall
.
Iovec
)(
unsafe
.
Pointer
(
&
iovecs
[
0
])),
len
(
iovecs
))
if
errno
!=
0
{
err
=
os
.
NewSyscallError
(
"writev"
,
errno
)
return
}
return
}
func
getFuseConn
(
local
net
.
Conn
)
(
f
*
os
.
File
,
err
os
.
Error
)
{
var
msg
syscall
.
Msghdr
var
iov
syscall
.
Iovec
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
)
if
err
!=
nil
{
return
}
length
:=
control
[
0
]
typ
:=
control
[
2
]
// syscall.Cmsghdr.Type
fd
:=
control
[
4
]
if
typ
!=
1
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: recvmsg returned wrong control type: %d"
,
typ
))
return
}
if
length
<
20
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: too short control message. Length: %d"
,
length
))
return
}
if
fd
<
0
{
err
=
os
.
NewError
(
fmt
.
Sprintf
(
"getFuseConn: fd < 0: %d"
,
fd
))
return
}
f
=
os
.
NewFile
(
int
(
fd
),
"fuse-conn"
)
return
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment