mirror of
https://github.com/fuse-friends/fuse-native
synced 2024-10-27 18:34:01 +00:00
* Fix possible deadlock because of never unlocked mutex during failed unmount. * Fix segmentation fault after unmounting. Scenario: 1. Mount path /a 2. Mount path /b 3. Unmount path /b 4. Appempt to read from path /a will throw segmentation fault. Reason: The function bindings_alloc correctly allocates memory and sets the index property of the binding. Afterwards the mount function does memset again for the binding and resets the index to zero. Unmounting will now always NULL the binding at position zero. However the actual binding on position zero is still mounted and the next access to it results in segmentation fault.
224 lines
5.4 KiB
JavaScript
224 lines
5.4 KiB
JavaScript
var bindings = require('bindings')
|
|
var fuse = bindings('fuse_bindings')
|
|
var fs = require('fs')
|
|
var os = require('os')
|
|
var xtend = require('xtend')
|
|
var path = require('path')
|
|
|
|
var noop = function () {}
|
|
var call = function (cb) { cb() }
|
|
|
|
var IS_OSX = os.platform() === 'darwin'
|
|
var OSX_FOLDER_ICON = '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericFolderIcon.icns'
|
|
var HAS_FOLDER_ICON = IS_OSX && fs.existsSync(OSX_FOLDER_ICON)
|
|
|
|
var FuseBuffer = function () {
|
|
this.length = 0
|
|
this.parent = undefined
|
|
}
|
|
|
|
FuseBuffer.prototype = Buffer.prototype
|
|
|
|
fuse.setBuffer(FuseBuffer)
|
|
fuse.setCallback(function (index, callback) {
|
|
return callback.bind(null, index)
|
|
})
|
|
|
|
exports.context = function () {
|
|
var ctx = {}
|
|
fuse.populateContext(ctx)
|
|
return ctx
|
|
}
|
|
|
|
exports.mount = function (mnt, ops, opts, cb) {
|
|
if (typeof opts === 'function') return exports.mount(mnt, ops, null, opts)
|
|
if (!cb) cb = noop
|
|
|
|
ops = xtend(ops, opts) // clone
|
|
if (/\*|(^,)fuse-bindings(,$)/.test(process.env.DEBUG)) ops.options = ['debug'].concat(ops.options || [])
|
|
mnt = path.resolve(mnt)
|
|
|
|
if (ops.displayFolder && IS_OSX) { // only works on osx
|
|
if (!ops.options) ops.options = []
|
|
ops.options.push('volname=' + path.basename(mnt))
|
|
if (HAS_FOLDER_ICON) ops.options.push('volicon=' + OSX_FOLDER_ICON)
|
|
}
|
|
|
|
var callback = function (err) {
|
|
callback = noop
|
|
setImmediate(cb.bind(null, err))
|
|
}
|
|
|
|
var init = ops.init || call
|
|
ops.init = function (next) {
|
|
callback()
|
|
if (init.length > 1) init(mnt, next) // backwards compat for now
|
|
else init(next)
|
|
}
|
|
|
|
var error = ops.error || call
|
|
ops.error = function (next) {
|
|
callback(new Error('Mount failed'))
|
|
error(next)
|
|
}
|
|
|
|
if (!ops.getattr) { // we need this for unmount to work on osx
|
|
ops.getattr = function (path, cb) {
|
|
if (path !== '/') return cb(fuse.EPERM)
|
|
cb(null, {mtime: new Date(0), atime: new Date(0), ctime: new Date(0), mode: 16877, size: 4096})
|
|
}
|
|
}
|
|
|
|
var mount = function () {
|
|
// TODO: I got a feeling this can be done better
|
|
if (os.platform() !== 'win32') {
|
|
fs.stat(mnt, function (err, stat) {
|
|
if (err) return cb(new Error('Mountpoint does not exist'))
|
|
if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory'))
|
|
fs.stat(path.join(mnt, '..'), function (_, parent) {
|
|
if (parent && parent.dev !== stat.dev) return cb(new Error('Mountpoint in use'))
|
|
fuse.mount(mnt, ops)
|
|
})
|
|
})
|
|
} else {
|
|
fuse.mount(mnt, ops)
|
|
}
|
|
}
|
|
|
|
if (!ops.force) return mount()
|
|
exports.unmount(mnt, mount)
|
|
}
|
|
|
|
exports.unmount = function (mnt, cb) {
|
|
fuse.unmount(path.resolve(mnt), cb)
|
|
}
|
|
|
|
exports.errno = function (code) {
|
|
return (code && exports[code.toUpperCase()]) || -1
|
|
}
|
|
|
|
exports.EPERM = -1
|
|
exports.ENOENT = -2
|
|
exports.ESRCH = -3
|
|
exports.EINTR = -4
|
|
exports.EIO = -5
|
|
exports.ENXIO = -6
|
|
exports.E2BIG = -7
|
|
exports.ENOEXEC = -8
|
|
exports.EBADF = -9
|
|
exports.ECHILD = -10
|
|
exports.EAGAIN = -11
|
|
exports.ENOMEM = -12
|
|
exports.EACCES = -13
|
|
exports.EFAULT = -14
|
|
exports.ENOTBLK = -15
|
|
exports.EBUSY = -16
|
|
exports.EEXIST = -17
|
|
exports.EXDEV = -18
|
|
exports.ENODEV = -19
|
|
exports.ENOTDIR = -20
|
|
exports.EISDIR = -21
|
|
exports.EINVAL = -22
|
|
exports.ENFILE = -23
|
|
exports.EMFILE = -24
|
|
exports.ENOTTY = -25
|
|
exports.ETXTBSY = -26
|
|
exports.EFBIG = -27
|
|
exports.ENOSPC = -28
|
|
exports.ESPIPE = -29
|
|
exports.EROFS = -30
|
|
exports.EMLINK = -31
|
|
exports.EPIPE = -32
|
|
exports.EDOM = -33
|
|
exports.ERANGE = -34
|
|
exports.EDEADLK = -35
|
|
exports.ENAMETOOLONG = -36
|
|
exports.ENOLCK = -37
|
|
exports.ENOSYS = -38
|
|
exports.ENOTEMPTY = -39
|
|
exports.ELOOP = -40
|
|
exports.EWOULDBLOCK = -11
|
|
exports.ENOMSG = -42
|
|
exports.EIDRM = -43
|
|
exports.ECHRNG = -44
|
|
exports.EL2NSYNC = -45
|
|
exports.EL3HLT = -46
|
|
exports.EL3RST = -47
|
|
exports.ELNRNG = -48
|
|
exports.EUNATCH = -49
|
|
exports.ENOCSI = -50
|
|
exports.EL2HLT = -51
|
|
exports.EBADE = -52
|
|
exports.EBADR = -53
|
|
exports.EXFULL = -54
|
|
exports.ENOANO = -55
|
|
exports.EBADRQC = -56
|
|
exports.EBADSLT = -57
|
|
exports.EDEADLOCK = -35
|
|
exports.EBFONT = -59
|
|
exports.ENOSTR = -60
|
|
exports.ENODATA = -61
|
|
exports.ETIME = -62
|
|
exports.ENOSR = -63
|
|
exports.ENONET = -64
|
|
exports.ENOPKG = -65
|
|
exports.EREMOTE = -66
|
|
exports.ENOLINK = -67
|
|
exports.EADV = -68
|
|
exports.ESRMNT = -69
|
|
exports.ECOMM = -70
|
|
exports.EPROTO = -71
|
|
exports.EMULTIHOP = -72
|
|
exports.EDOTDOT = -73
|
|
exports.EBADMSG = -74
|
|
exports.EOVERFLOW = -75
|
|
exports.ENOTUNIQ = -76
|
|
exports.EBADFD = -77
|
|
exports.EREMCHG = -78
|
|
exports.ELIBACC = -79
|
|
exports.ELIBBAD = -80
|
|
exports.ELIBSCN = -81
|
|
exports.ELIBMAX = -82
|
|
exports.ELIBEXEC = -83
|
|
exports.EILSEQ = -84
|
|
exports.ERESTART = -85
|
|
exports.ESTRPIPE = -86
|
|
exports.EUSERS = -87
|
|
exports.ENOTSOCK = -88
|
|
exports.EDESTADDRREQ = -89
|
|
exports.EMSGSIZE = -90
|
|
exports.EPROTOTYPE = -91
|
|
exports.ENOPROTOOPT = -92
|
|
exports.EPROTONOSUPPORT = -93
|
|
exports.ESOCKTNOSUPPORT = -94
|
|
exports.EOPNOTSUPP = -95
|
|
exports.EPFNOSUPPORT = -96
|
|
exports.EAFNOSUPPORT = -97
|
|
exports.EADDRINUSE = -98
|
|
exports.EADDRNOTAVAIL = -99
|
|
exports.ENETDOWN = -100
|
|
exports.ENETUNREACH = -101
|
|
exports.ENETRESET = -102
|
|
exports.ECONNABORTED = -103
|
|
exports.ECONNRESET = -104
|
|
exports.ENOBUFS = -105
|
|
exports.EISCONN = -106
|
|
exports.ENOTCONN = -107
|
|
exports.ESHUTDOWN = -108
|
|
exports.ETOOMANYREFS = -109
|
|
exports.ETIMEDOUT = -110
|
|
exports.ECONNREFUSED = -111
|
|
exports.EHOSTDOWN = -112
|
|
exports.EHOSTUNREACH = -113
|
|
exports.EALREADY = -114
|
|
exports.EINPROGRESS = -115
|
|
exports.ESTALE = -116
|
|
exports.EUCLEAN = -117
|
|
exports.ENOTNAM = -118
|
|
exports.ENAVAIL = -119
|
|
exports.EISNAM = -120
|
|
exports.EREMOTEIO = -121
|
|
exports.EDQUOT = -122
|
|
exports.ENOMEDIUM = -123
|
|
exports.EMEDIUMTYPE = -124
|