From 8740147aa23c001fd3ab6d1efa017d06d85351b3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 24 Sep 2014 15:38:07 +0800 Subject: [PATCH] Make fs.readFile support asar package --- atom/common/lib/asar.coffee | 66 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index 9d35deeffb3..a5faaa2ecba 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -25,6 +25,13 @@ asarStatsToFsStats = (stats) -> isSocket: -> false } +# Create a ENOENT error. +createNotFoundError = (asarPath, filePath) -> + error = new Error("ENOENT, #{filePath} not found in #{asarPath}") + error.code = "ENOENT" + error.errno = -2 + error + # Override fs APIs. statSync = fs.statSync fs.statSync = (p) -> @@ -35,7 +42,7 @@ fs.statSync = (p) -> throw new Error("Invalid package #{asarPath}") unless archive stats = archive.stat filePath - throw new Error("#{filePath} not found in #{asarPath}") unless stats + throw createNotFoundError(asarPath, filePath) unless stats asarStatsToFsStats stats @@ -48,7 +55,7 @@ fs.stat = (p, callback) -> return callback throw new Error("Invalid package #{asarPath}") unless archive stats = asar.createArchive(asarPath).stat filePath - return callback new Error("#{filePath} not found in #{asarPath}") unless stats + return callback createNotFoundError(asarPath, filePath) unless stats callback undefined, asarStatsToFsStats stats @@ -62,3 +69,58 @@ fs.statSyncNoException = (p) -> stats = asar.createArchive(asarPath).stat filePath return false unless stats asarStatsToFsStats stats + +exists = fs.exists +fs.exists = (p, callback) -> + [isAsar, asarPath, filePath] = splitPath p + return exists p, callback unless isAsar + + archive = asar.createArchive asarPath + return callback throw new Error("Invalid package #{asarPath}") unless archive + + callback archive.stat(filePath) isnt false + +existsSync = fs.existsSync +fs.existsSync = (p) -> + [isAsar, asarPath, filePath] = splitPath p + return existsSync p unless isAsar + + archive = asar.createArchive asarPath + return false unless archive + + archive.stat(filePath) isnt false + +readFile = fs.readFile +fs.readFile = (p, callback) -> + [isAsar, asarPath, filePath] = splitPath p + return readFile.apply this, arguments unless isAsar + + archive = asar.createArchive asarPath + return callback throw new Error("Invalid package #{asarPath}") unless archive + + info = archive.getFileInfo filePath + return callback createNotFoundError(asarPath, filePath) unless info + + buffer = new Buffer(info.size) + fs.open archive.path, 'r', (error, fd) -> + return callback error if error + fs.read fd, buffer, 0, info.size, info.offset, (error) -> + fs.close fd, -> + callback error, buffer + +readFileSync = fs.readFileSync +fs.readFileSync = (p) -> + [isAsar, asarPath, filePath] = splitPath p + return readFileSync.apply this, arguments unless isAsar + + archive = asar.createArchive asarPath + throw new Error("Invalid package #{asarPath}") unless archive + + info = archive.getFileInfo filePath + throw createNotFoundError(asarPath, filePath) unless info + + buffer = new Buffer(info.size) + fd = fs.openSync archive.path, 'r' + fs.readSync fd, buffer, 0, info.size, info.offset + fs.closeSync fd + buffer