export function copyOrLinkFile(src: string, dest: string, stats?: Stats | null, isUseHardLink = _isUseHardLink): Promise<any> { if (stats != null) { const originalModeNumber = stats.mode const mode = new Mode(stats) if (mode.owner.execute) { mode.group.execute = true mode.others.execute = true } mode.group.read = true mode.others.read = true if (originalModeNumber !== stats.mode) { if (debug.enabled) { const oldMode = new Mode({mode: originalModeNumber}) debug(`${dest} permissions fixed from ${oldMode.toOctal()} (${oldMode.toString()}) to ${mode.toOctal()} (${mode.toString()})`) } // https://helgeklein.com/blog/2009/05/hard-links-and-permissions-acls/ // Permissions on all hard links to the same data on disk are always identical. The same applies to attributes. // That means if you change the permissions/owner/attributes on one hard link, you will immediately see the changes on all other hard links. if (isUseHardLink) { isUseHardLink = false debug(`${dest} will be copied, but not linked, because file permissions need to be fixed`) } } } if (isUseHardLink) { return link(src, dest) } if (_nodeCopyFile == null) { return new BluebirdPromise((resolve, reject) => { const reader = createReadStream(src) const writer = createWriteStream(dest, stats == null ? undefined : {mode: stats!!.mode}) reader.on("error", reject) writer.on("error", reject) writer.on("open", () => { reader.pipe(writer) }) writer.once("close", resolve) }) } else { // node 8.5.0 return _nodeCopyFile(src, dest) .then((): any => { if (stats != null) { return chmod(dest, stats.mode) } return null }) } }
export function copyOrLinkFile(src: string, dest: string, stats?: Stats | null, isUseHardLink?: boolean, exDevErrorHandler?: (() => boolean) | null): Promise<any> { if (isUseHardLink === undefined) { isUseHardLink = _isUseHardLink } if (stats != null) { const originalModeNumber = stats.mode const mode = new Mode(stats) if (mode.owner.execute) { mode.group.execute = true mode.others.execute = true } mode.group.read = true mode.others.read = true if (originalModeNumber !== stats.mode) { if (log.isDebugEnabled) { const oldMode = new Mode({mode: originalModeNumber}) log.debug({file: dest, oldMode, mode}, "permissions fixed from") } // https://helgeklein.com/blog/2009/05/hard-links-and-permissions-acls/ // Permissions on all hard links to the same data on disk are always identical. The same applies to attributes. // That means if you change the permissions/owner/attributes on one hard link, you will immediately see the changes on all other hard links. if (isUseHardLink) { isUseHardLink = false log.debug({dest}, "copied, but not linked, because file permissions need to be fixed") } } } if (isUseHardLink) { return link(src, dest) .catch(e => { if (e.code === "EXDEV") { const isLog = exDevErrorHandler == null ? true : exDevErrorHandler() if (isLog && log.isDebugEnabled) { log.debug({error: e.message}, "cannot copy using hard link") } return doCopyFile(src, dest, stats) } else { throw e } }) } return doCopyFile(src, dest, stats) }
export function copyOrLinkFile(src: string, dest: string, stats?: Stats | null, isUseHardLink = _isUseHardLink): Promise<any> { if (stats != null) { const originalModeNumber = stats.mode const mode = new Mode(stats) if (mode.owner.execute) { mode.group.execute = true mode.others.execute = true } mode.group.read = true mode.others.read = true if (originalModeNumber !== stats.mode) { if (debug.enabled) { const oldMode = new Mode({...stats, mode: originalModeNumber}) debug(`${dest} permissions fixed from ${oldMode.toOctal()} (${oldMode.toString()}) to ${mode.toOctal()} (${mode.toString()})`) } // https://helgeklein.com/blog/2009/05/hard-links-and-permissions-acls/ // Permissions on all hard links to the same data on disk are always identical. The same applies to attributes. // That means if you change the permissions/owner/attributes on one hard link, you will immediately see the changes on all other hard links. if (isUseHardLink) { isUseHardLink = false debug(`${dest} will be copied, but not linked, because file permissions need to be fixed`) } } } if (isUseHardLink) { return link(src, dest) } return new BluebirdPromise((resolve, reject) => { fcopy(src, dest, stats == null ? undefined : {mode: stats.mode}, error => error == null ? resolve() : reject(error)) }) }