Created
November 28, 2018 13:39
-
-
Save jorangreef/3695c546367512f8d5bb4cb45b531c39 to your computer and use it in GitHub Desktop.
DirectIO cross-platform open()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const DirectIO = require('@ronomon/direct-io'); | |
const Node = { | |
fs: require('fs'), | |
path: require('path'), | |
process: require('process') | |
}; | |
const PATH = '\\\\.\\PhysicalDrive1'; | |
// 4096 is better than 512 because it works with new Advanced Format devices: | |
// It's also backwards-compatible with 512 byte sector devices. | |
const SECTOR = 4096; | |
function openDevice(path, callback) { | |
var fd = null; | |
var flags = 0; | |
function close(error, end) { | |
if (!error) throw new Error('must be called only in the event of an error'); | |
if (fd === null) return end(error); | |
console.log('closing fd because of an error...'); | |
Node.fs.close(fd, | |
function(errorClose) { | |
end(error); // Ignoring any `errorClose` in favor of original `error`. | |
} | |
); | |
} | |
function end(error) { | |
if (error) return close(error, callback); | |
callback(undefined, fd); | |
} | |
function open(end) { | |
console.log('opening ' + path + ' flags=' + flags + '...'); | |
Node.fs.open(path, flags, | |
function(error, result) { | |
if (error) return end(error); | |
console.log('opened fd=' + result); | |
fd = result; | |
end(); | |
} | |
); | |
} | |
function setFSCTL_LOCK_VOLUME(end) { | |
if (Node.process.platform !== 'win32') return end(); | |
console.log('setting FSCTL_LOCK_VOLUME=1...'); | |
DirectIO.setFSCTL_LOCK_VOLUME(fd, 1, end); | |
} | |
function setF_NOCACHE(end) { | |
if (Node.process.platform !== 'darwin') return end(); | |
console.log('setting F_NOCACHE=1 (O_DIRECT for macOS)...'); | |
DirectIO.setF_NOCACHE(fd, 1, end); | |
} | |
if (Node.fs.constants.O_RDWR) { | |
console.log('flags |= O_RDWR'); | |
flags |= Node.fs.constants.O_RDWR; | |
} else { | |
return end(new Error('O_RDWR not supported on this platform')); | |
} | |
if (Node.process.platform !== 'win32') { | |
// libuv has an issue setting FILE_FLAG_NO_BUFFERING on Windows. | |
// Skip Windows while this is being resolved. | |
if (DirectIO.O_DIRECT) { | |
console.log('flags |= O_DIRECT'); | |
flags |= DirectIO.O_DIRECT; | |
} else if (Node.process.platform !== 'darwin') { | |
return end(new Error('O_DIRECT not supported on this platform')); | |
} | |
} | |
if (DirectIO.O_SYNC) { | |
console.log('flags |= O_SYNC'); | |
flags |= DirectIO.O_SYNC; | |
} else { | |
return end(new Error('O_SYNC not supported on this platform')); | |
} | |
if (Node.process.platform === 'darwin' || Node.process.platform === 'win32') { | |
console.log('flags |= O_EXLOCK'); | |
flags |= DirectIO.O_EXLOCK; | |
} else { | |
console.log('flags |= O_EXCL'); | |
flags |= DirectIO.O_EXCL; | |
} | |
open( | |
function(error) { | |
if (error) return end(error); | |
setF_NOCACHE(end); | |
} | |
); | |
} | |
function readDevice(fd, offset, buffer, end) { | |
console.log( | |
'reading ' + buffer.length + ' bytes at offset ' + offset + '...' | |
); | |
Node.fs.read(fd, buffer, 0, buffer.length, offset, end); | |
} | |
function writeDevice(fd, offset, buffer, end) { | |
console.log( | |
'writing ' + buffer.length + ' bytes at offset ' + offset + '...' | |
); | |
Node.fs.write(fd, buffer, 0, buffer.length, offset, end); | |
} | |
openDevice(PATH, | |
function(error, fd) { | |
if (error) throw error; | |
var buffer = DirectIO.getAlignedBuffer(65536, SECTOR); | |
// Go beyond the MBR to make sure we really have write access on Windows: | |
var offset = 16 * 1024 * 1024; | |
readDevice(fd, offset, buffer, | |
function(error) { | |
if (error) throw error; | |
writeDevice(fd, offset, buffer, | |
function(error) { | |
if (error) throw error; | |
console.log('100% OK'); | |
} | |
); | |
} | |
); | |
} | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"dependencies": { | |
"@ronomon/direct-io": "^2.4.3" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment