From 42e53213650036be3fa0c7412a9c3ae840c7ffbb Mon Sep 17 00:00:00 2001 From: Andrew Osheroff Date: Thu, 6 Feb 2020 17:42:13 +0100 Subject: [PATCH] Better unmount behavior on OSX + OSX-specific unmount tests --- index.js | 9 +++++--- test/misc.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- test/read.js | 32 ++++++----------------------- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/index.js b/index.js index e600c70..997053b 100644 --- a/index.js +++ b/index.js @@ -257,7 +257,7 @@ class Fuse extends Nanoresource { static unmount (mnt, cb) { mnt = JSON.stringify(mnt) - const cmd = IS_OSX ? `diskutil umount ${mnt}` : `fusermount -uz ${mnt}` + const cmd = IS_OSX ? `diskutil unmount force ${mnt}` : `fusermount -uz ${mnt}` exec(cmd, err => { if (err) return cb(err) return cb(null) @@ -320,8 +320,11 @@ class Fuse extends Nanoresource { _close (cb) { const self = this - Fuse.unmount(this.mnt, () => { - // Even if the unmount command fails, do the native unmount. + Fuse.unmount(this.mnt, err => { + if (err) { + err.unmountFailure = true + return cb(err) + } nativeUnmount() }) diff --git a/test/misc.js b/test/misc.js index c351e6d..c44c11c 100644 --- a/test/misc.js +++ b/test/misc.js @@ -1,9 +1,13 @@ -const createMountpoint = require('./fixtures/mnt') +const os = require('os') +const fs = require('fs') const tape = require('tape') -const { spawnSync } = require('child_process') +const { spawnSync, exec } = require('child_process') + +const createMountpoint = require('./fixtures/mnt') const Fuse = require('../') const { unmount } = require('./helpers') +const simpleFS = require('./fixtures/simple-fs') const mnt = createMountpoint() @@ -135,6 +139,56 @@ tape('mounting with mkdir option and a nonexistent mountpoint succeeds', functio }) }) +tape('(osx only) unmount with Finder open succeeds', function (t) { + if (os.platform() !== 'darwin') return t.end() + const fuse = new Fuse(mnt, simpleFS(), { force: true, debug: false }) + fuse.mount(function (err) { + t.error(err, 'no error') + exec(`open ${mnt}`, err => { + t.error(err, 'no error') + setTimeout(() => { + fs.readdir(mnt, (err, list) => { + t.error(err, 'no error') + t.same(list, ['test']) + unmount(fuse, err => { + t.error(err, 'no error') + fs.readdir(mnt, (err, list) => { + t.error(err, 'no error') + t.same(list, []) + t.end() + }) + }) + }) + }, 1000) + }) + }) +}) + +tape('(osx only) unmount with Terminal open succeeds', function (t) { + if (os.platform() !== 'darwin') return t.end() + const fuse = new Fuse(mnt, simpleFS(), { force: true, debug: false }) + fuse.mount(function (err) { + t.error(err, 'no error') + exec(`open -a Terminal ${mnt}`, err => { + t.error(err, 'no error') + setTimeout(() => { + fs.readdir(mnt, (err, list) => { + t.error(err, 'no error') + t.same(list, ['test']) + unmount(fuse, err => { + t.error(err, 'no error') + fs.readdir(mnt, (err, list) => { + t.error(err, 'no error') + t.same(list, []) + t.end() + }) + }) + }) + }, 1000) + }) + }) +}) + tape('static unmounting', function (t) { t.end() }) diff --git a/test/read.js b/test/read.js index c45c687..491118e 100644 --- a/test/read.js +++ b/test/read.js @@ -6,38 +6,18 @@ const concat = require('concat-stream') const Fuse = require('../') const createMountpoint = require('./fixtures/mnt') const stat = require('./fixtures/stat') -const { unmount } = require('./helpers') +const simpleFS = require('./fixtures/simple-fs') +const { unmount } = require('./helpers') const mnt = createMountpoint() tape('read', function (t) { - var ops = { - force: true, - readdir: function (path, cb) { - if (path === '/') return process.nextTick(cb, null, ['test']) - return process.nextTick(cb, Fuse.ENOENT) - }, - getattr: function (path, cb) { - if (path === '/') return process.nextTick(cb, null, stat({ mode: 'dir', size: 4096 })) - if (path === '/test') return process.nextTick(cb, null, stat({ mode: 'file', size: 11 })) - return process.nextTick(cb, Fuse.ENOENT) - }, - open: function (path, flags, cb) { - return process.nextTick(cb, 0, 42) - }, - release: function (path, fd, cb) { + const testFS = simpleFS({ + release: function (path, fd) { t.same(fd, 42, 'fd was passed to release') - return process.nextTick(cb, 0) - }, - read: function (path, fd, buf, len, pos, cb) { - var str = 'hello world'.slice(pos, pos + len) - if (!str) return process.nextTick(cb, 0) - buf.write(str) - return process.nextTick(cb, str.length) } - } - - const fuse = new Fuse(mnt, ops, { debug: true }) + }) + const fuse = new Fuse(mnt, testFS, { debug: true }) fuse.mount(function (err) { t.error(err, 'no error')