diff --git a/lib/storage.js b/lib/storage.js index 4b0bfd7..fa8f12a 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -50,15 +50,25 @@ storage.flushToStorage = (options, callback) => { flags = options.isDir ? 'r' : 'r+' } - // Windows can't fsync (FlushFileBuffers) directories. We can live with this as it cannot cause 100% dataloss - // except in the very rare event of the first time database is loaded and a crash happens - if (flags === 'r' && (process.platform === 'win32' || process.platform === 'win64')) return callback(null) + /** + * Some OSes and/or storage backends (augmented node fs) do not support fsync (FlushFileBuffers) directories, + * or calling open() on directories at all. Flushing fails silently in this case, supported by following heuristics: + * + isDir === true + * |-- open() -> (err.code === 'EISDIR'): can't call open() on directories (eg. BrowserFS) + * `-- fsync() -> (errFS.code === 'EPERM' || errFS.code === 'EISDIR'): can't fsync directory: permissions are checked + * on open(); EPERM error should only occur on fsync incapability and not for general lack of permissions (e.g. Windows) + * + * We can live with this as it cannot cause 100% dataloss except in the very rare event of the first time + * database is loaded and a crash happens. + */ fs.open(filename, flags, (err, fd) => { - if (err) return callback(err) + if (err) { + return callback((err.code === 'EISDIR' && options.isDir) ? null : err) + } fs.fsync(fd, errFS => { fs.close(fd, errC => { - if (errFS || errC) { + if ((errFS || errC) && !((errFS.code === 'EPERM' || errFS.code === 'EISDIR') && options.isDir)) { const e = new Error('Failed to flush to storage') e.errorOnFsync = errFS e.errorOnClose = errC diff --git a/test/byline.test.js b/test/byline.test.js index fa07524..713d80d 100644 --- a/test/byline.test.js +++ b/test/byline.test.js @@ -37,7 +37,7 @@ describe('byline', function () { lineStream.pipe(output) output.on('close', function () { const out = fs.readFileSync(localPath('test.txt'), 'utf8') - const in_ = fs.readFileSync(localPath('empty.txt'), 'utf8').replace(/\n/g, '') + const in_ = fs.readFileSync(localPath('empty.txt'), 'utf8').replace(/\r?\n/g, '') assert.equal(in_, out) fs.unlinkSync(localPath('test.txt')) done() diff --git a/test_lac/openFdsLaunch.sh b/test_lac/openFdsLaunch.sh index 495c8a3..7c04a5a 100755 --- a/test_lac/openFdsLaunch.sh +++ b/test_lac/openFdsLaunch.sh @@ -1,2 +1,3 @@ +#!/bin/sh ulimit -n 128 node ./test_lac/openFds.test.js