diff --git a/lib/fs.js b/lib/fs.js index 6e28a41118..a965c84afc 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -16,6 +16,7 @@ const FSReqWrap = binding.FSReqWrap; const FSEvent = process.binding('fs_event_wrap').FSEvent; const internalFS = require('internal/fs'); const assertEncoding = internalFS.assertEncoding; +const stringToFlags = internalFS.stringToFlags; const SyncWriteStream = internalFS.SyncWriteStream; Object.defineProperty(exports, 'constants', { @@ -30,15 +31,6 @@ const Writable = Stream.Writable; const kMinPoolSpace = 128; const kMaxLength = require('buffer').kMaxLength; -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - const isWindows = process.platform === 'win32'; const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); @@ -522,48 +514,6 @@ fs.readFileSync = function(path, options) { }; -// Used by binding.open and friends -function stringToFlags(flag) { - // Return early if it's a number - if (typeof flag === 'number') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - // Yes, the follow could be easily DRYed up but I provide the explicit // list to make the arguments clear. diff --git a/lib/internal/fs.js b/lib/internal/fs.js index dcfb4be123..41b4905f1d 100644 --- a/lib/internal/fs.js +++ b/lib/internal/fs.js @@ -4,6 +4,16 @@ const Buffer = require('buffer').Buffer; const Stream = require('stream').Stream; const fs = require('fs'); const util = require('util'); +const constants = process.binding('constants').fs; + +const O_APPEND = constants.O_APPEND | 0; +const O_CREAT = constants.O_CREAT | 0; +const O_EXCL = constants.O_EXCL | 0; +const O_RDONLY = constants.O_RDONLY | 0; +const O_RDWR = constants.O_RDWR | 0; +const O_SYNC = constants.O_SYNC | 0; +const O_TRUNC = constants.O_TRUNC | 0; +const O_WRONLY = constants.O_WRONLY | 0; function assertEncoding(encoding) { if (encoding && !Buffer.isEncoding(encoding)) { @@ -12,6 +22,40 @@ function assertEncoding(encoding) { } exports.assertEncoding = assertEncoding; +function stringToFlags(flag) { + if (typeof flag === 'number') { + return flag; + } + + switch (flag) { + case 'r' : return O_RDONLY; + case 'rs' : // Fall through. + case 'sr' : return O_RDONLY | O_SYNC; + case 'r+' : return O_RDWR; + case 'rs+' : // Fall through. + case 'sr+' : return O_RDWR | O_SYNC; + + case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; + case 'wx' : // Fall through. + case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; + + case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; + case 'wx+': // Fall through. + case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; + + case 'a' : return O_APPEND | O_CREAT | O_WRONLY; + case 'ax' : // Fall through. + case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; + + case 'a+' : return O_APPEND | O_CREAT | O_RDWR; + case 'ax+': // Fall through. + case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; + } + + throw new Error('Unknown file open flag: ' + flag); +} +exports.stringToFlags = stringToFlags; + // Temporary hack for process.stdout and process.stderr when piped to files. function SyncWriteStream(fd, options) { Stream.call(this); diff --git a/test/parallel/test-fs-open-flags.js b/test/parallel/test-fs-open-flags.js index d212130bc9..ce7eaad580 100644 --- a/test/parallel/test-fs-open-flags.js +++ b/test/parallel/test-fs-open-flags.js @@ -1,3 +1,4 @@ +// Flags: --expose_internals 'use strict'; require('../common'); var assert = require('assert'); @@ -12,39 +13,41 @@ var O_RDWR = fs.constants.O_RDWR || 0; var O_TRUNC = fs.constants.O_TRUNC || 0; var O_WRONLY = fs.constants.O_WRONLY || 0; -assert.equal(fs._stringToFlags('r'), O_RDONLY); -assert.equal(fs._stringToFlags('r+'), O_RDWR); -assert.equal(fs._stringToFlags('w'), O_TRUNC | O_CREAT | O_WRONLY); -assert.equal(fs._stringToFlags('w+'), O_TRUNC | O_CREAT | O_RDWR); -assert.equal(fs._stringToFlags('a'), O_APPEND | O_CREAT | O_WRONLY); -assert.equal(fs._stringToFlags('a+'), O_APPEND | O_CREAT | O_RDWR); - -assert.equal(fs._stringToFlags('wx'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); -assert.equal(fs._stringToFlags('xw'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); -assert.equal(fs._stringToFlags('wx+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); -assert.equal(fs._stringToFlags('xw+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); -assert.equal(fs._stringToFlags('ax'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); -assert.equal(fs._stringToFlags('xa'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); -assert.equal(fs._stringToFlags('ax+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); -assert.equal(fs._stringToFlags('xa+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); +const { stringToFlags } = require('internal/fs'); + +assert.equal(stringToFlags('r'), O_RDONLY); +assert.equal(stringToFlags('r+'), O_RDWR); +assert.equal(stringToFlags('w'), O_TRUNC | O_CREAT | O_WRONLY); +assert.equal(stringToFlags('w+'), O_TRUNC | O_CREAT | O_RDWR); +assert.equal(stringToFlags('a'), O_APPEND | O_CREAT | O_WRONLY); +assert.equal(stringToFlags('a+'), O_APPEND | O_CREAT | O_RDWR); + +assert.equal(stringToFlags('wx'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); +assert.equal(stringToFlags('xw'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); +assert.equal(stringToFlags('wx+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); +assert.equal(stringToFlags('xw+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); +assert.equal(stringToFlags('ax'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); +assert.equal(stringToFlags('xa'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); +assert.equal(stringToFlags('ax+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); +assert.equal(stringToFlags('xa+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); ('+ +a +r +w rw wa war raw r++ a++ w++ x +x x+ rx rx+ wxx wax xwx xxx') .split(' ') .forEach(function(flags) { - assert.throws(function() { fs._stringToFlags(flags); }); + assert.throws(function() { stringToFlags(flags); }); }); assert.throws( - () => fs._stringToFlags({}), + () => stringToFlags({}), /Unknown file open flag: \[object Object\]/ ); assert.throws( - () => fs._stringToFlags(true), + () => stringToFlags(true), /Unknown file open flag: true/ ); assert.throws( - () => fs._stringToFlags(null), + () => stringToFlags(null), /Unknown file open flag: null/ );