diff --git a/README.md b/README.md index d5efec3..ab16b1e 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ Create a new `Fuse` object. ``` displayFolder: 'Folder Name', // Add a name/icon to the mount volume on OSX, debug: false, // Enable detailed tracing of operations. + force: false, // Attempt to unmount a the mountpoint before remounting. + mkdir: false // Create the mountpoint before mounting. ``` Additionally, all (FUSE-specific options)[http://man7.org/linux/man-pages/man8/mount.fuse.8.html] will be passed to the underlying FUSE module (though we use camel casing instead of snake casing). diff --git a/index.js b/index.js index 3e71ec2..2af8d38 100644 --- a/index.js +++ b/index.js @@ -142,6 +142,7 @@ class Fuse extends Nanoresource { this.timeout = opts.timeout || DEFAULT_TIMEOUT this._force = !!opts.force + this._mkdir = !!opts.mkdir this._thread = null this._handlers = this._makeHandlerArray() @@ -281,9 +282,23 @@ class Fuse extends Nanoresource { const implemented = self._getImplementedArray() return fs.stat(self.mnt, (err, stat) => { - if (err) return cb(new Error('Mountpoint does not exist')) + if (err && err.errno !== -2) return cb(err) + if (err) { + if (!self._mkdir) return cb(new Error('Mountpoint does not exist')) + return fs.mkdir(self.mnt, { recursive: true }, err => { + if (err) return cb(err) + fs.stat(self.mnt, (err, stat) => { + if (err) return cb(err) + return onexists(stat) + }) + }) + } if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory')) - return fs.stat(path.join(self.mnt, '..'), (_, parent) => { + return onexists(stat) + }) + + function onexists (stat) { + fs.stat(path.join(self.mnt, '..'), (_, parent) => { if (parent && parent.dev !== stat.dev) return cb(new Error('Mountpoint in use')) try { // TODO: asyncify @@ -292,7 +307,7 @@ class Fuse extends Nanoresource { return cb(err) } }) - }) + } } } diff --git a/test/big.js b/test/big.js index 1e1c664..479c1f8 100644 --- a/test/big.js +++ b/test/big.js @@ -4,10 +4,12 @@ const path = require('path') const concat = require('concat-stream') const Fuse = require('../') -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') const { unmount } = require('./helpers') +const mnt = createMountpoint() + tape('read and write big file', function (t) { let size = 0 const reads = [0, 4 * 1024 * 1024 * 1024, 6 * 1024 * 1024 * 1024] diff --git a/test/fixtures/mnt.js b/test/fixtures/mnt.js index ab7762b..d9189d2 100644 --- a/test/fixtures/mnt.js +++ b/test/fixtures/mnt.js @@ -2,12 +2,18 @@ var os = require('os') var path = require('path') var fs = require('fs') -var mnt = path.join(os.tmpdir(), 'fuse-bindings-' + process.pid + '-' + Date.now()) +function create (opts = {}) { + var mnt = path.join(os.tmpdir(), 'fuse-bindings-' + process.pid + '-' + Date.now()) -try { - fs.mkdirSync(mnt) -} catch (err) { - // do nothing + if (!opts.doNotCreate) { + try { + fs.mkdirSync(mnt) + } catch (err) { + // do nothing + } + } + + return mnt } -module.exports = mnt +module.exports = create diff --git a/test/links.js b/test/links.js index a52d5c1..6a2dae9 100644 --- a/test/links.js +++ b/test/links.js @@ -4,9 +4,11 @@ const path = require('path') const { unmount } = require('./helpers') const Fuse = require('../') -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') +const mnt = createMountpoint() + tape('readlink', function (t) { var ops = { force: true, diff --git a/test/misc.js b/test/misc.js index 8039439..c351e6d 100644 --- a/test/misc.js +++ b/test/misc.js @@ -1,10 +1,12 @@ -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const tape = require('tape') const { spawnSync } = require('child_process') const Fuse = require('../') const { unmount } = require('./helpers') +const mnt = createMountpoint() + tape('mount', function (t) { const fuse = new Fuse(mnt, {}, { force: true }) fuse.mount(function (err) { @@ -111,6 +113,28 @@ tape('mounting over a broken mountpoint with force succeeds', function (t) { }) }) +tape('mounting without mkdir option and a nonexistent mountpoint fails', function (t) { + const nonexistentMnt = createMountpoint({ doNotCreate: true }) + + const fuse = new Fuse(nonexistentMnt, {}, { debug: false }) + fuse.mount(function (err) { + t.true(err, 'could not mount') + t.end() + }) +}) + +tape('mounting with mkdir option and a nonexistent mountpoint succeeds', function (t) { + const nonexistentMnt = createMountpoint({ doNotCreate: true }) + + const fuse = new Fuse(nonexistentMnt, {}, { debug: false, mkdir: true }) + fuse.mount(function (err) { + t.error(err, 'no error') + unmount(fuse, function (err) { + t.end() + }) + }) +}) + tape('static unmounting', function (t) { t.end() }) diff --git a/test/read.js b/test/read.js index 388eae1..c45c687 100644 --- a/test/read.js +++ b/test/read.js @@ -4,10 +4,12 @@ const path = require('path') const concat = require('concat-stream') const Fuse = require('../') -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') const { unmount } = require('./helpers') +const mnt = createMountpoint() + tape('read', function (t) { var ops = { force: true, diff --git a/test/statfs.js b/test/statfs.js index 5fcd377..f5de18a 100644 --- a/test/statfs.js +++ b/test/statfs.js @@ -3,9 +3,11 @@ const { unmount } = require('./helpers') const tape = require('tape') const Fuse = require('../') -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') +const mnt = createMountpoint() + tape('statfs', function (t) { const ops = { force: true, diff --git a/test/write.js b/test/write.js index b3aa051..72ea060 100644 --- a/test/write.js +++ b/test/write.js @@ -3,10 +3,12 @@ const fs = require('fs') const path = require('path') const Fuse = require('../') -const mnt = require('./fixtures/mnt') +const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') const { unmount } = require('./helpers') +const mnt = createMountpoint() + tape('write', function (t) { var created = false var data = Buffer.alloc(1024)