A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/npm/cli/commit/53ed632561cc0336f4194524de6e236f50d67212 below:

update write-file-atomic@6.0.0 · npm/cli@53ed632 · GitHub

1 +

'use strict'

2 +

module.exports = writeFile

3 +

module.exports.sync = writeFileSync

4 +

module.exports._getTmpname = getTmpname // for testing

5 +

module.exports._cleanupOnExit = cleanupOnExit

6 + 7 +

const fs = require('fs')

8 +

const MurmurHash3 = require('imurmurhash')

9 +

const { onExit } = require('signal-exit')

10 +

const path = require('path')

11 +

const { promisify } = require('util')

12 +

const activeFiles = {}

13 + 14 +

// if we run inside of a worker_thread, `process.pid` is not unique

15 +

/* istanbul ignore next */

16 +

const threadId = (function getId () {

17 +

try {

18 +

const workerThreads = require('worker_threads')

19 + 20 +

/// if we are in main thread, this is set to `0`

21 +

return workerThreads.threadId

22 +

} catch (e) {

23 +

// worker_threads are not available, fallback to 0

24 +

return 0

25 +

}

26 +

})()

27 + 28 +

let invocations = 0

29 +

function getTmpname (filename) {

30 +

return filename + '.' +

31 +

MurmurHash3(__filename)

32 +

.hash(String(process.pid))

33 +

.hash(String(threadId))

34 +

.hash(String(++invocations))

35 +

.result()

36 +

}

37 + 38 +

function cleanupOnExit (tmpfile) {

39 +

return () => {

40 +

try {

41 +

fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile)

42 +

} catch {

43 +

// ignore errors

44 +

}

45 +

}

46 +

}

47 + 48 +

function serializeActiveFile (absoluteName) {

49 +

return new Promise(resolve => {

50 +

// make a queue if it doesn't already exist

51 +

if (!activeFiles[absoluteName]) {

52 +

activeFiles[absoluteName] = []

53 +

}

54 + 55 +

activeFiles[absoluteName].push(resolve) // add this job to the queue

56 +

if (activeFiles[absoluteName].length === 1) {

57 +

resolve()

58 +

} // kick off the first one

59 +

})

60 +

}

61 + 62 +

// https://github.com/isaacs/node-graceful-fs/blob/master/polyfills.js#L315-L342

63 +

function isChownErrOk (err) {

64 +

if (err.code === 'ENOSYS') {

65 +

return true

66 +

}

67 + 68 +

const nonroot = !process.getuid || process.getuid() !== 0

69 +

if (nonroot) {

70 +

if (err.code === 'EINVAL' || err.code === 'EPERM') {

71 +

return true

72 +

}

73 +

}

74 + 75 +

return false

76 +

}

77 + 78 +

async function writeFileAsync (filename, data, options = {}) {

79 +

if (typeof options === 'string') {

80 +

options = { encoding: options }

81 +

}

82 + 83 +

let fd

84 +

let tmpfile

85 +

/* istanbul ignore next -- The closure only gets called when onExit triggers */

86 +

const removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile))

87 +

const absoluteName = path.resolve(filename)

88 + 89 +

try {

90 +

await serializeActiveFile(absoluteName)

91 +

const truename = await promisify(fs.realpath)(filename).catch(() => filename)

92 +

tmpfile = getTmpname(truename)

93 + 94 +

if (!options.mode || !options.chown) {

95 +

// Either mode or chown is not explicitly set

96 +

// Default behavior is to copy it from original file

97 +

const stats = await promisify(fs.stat)(truename).catch(() => {})

98 +

if (stats) {

99 +

if (options.mode == null) {

100 +

options.mode = stats.mode

101 +

}

102 + 103 +

if (options.chown == null && process.getuid) {

104 +

options.chown = { uid: stats.uid, gid: stats.gid }

105 +

}

106 +

}

107 +

}

108 + 109 +

fd = await promisify(fs.open)(tmpfile, 'w', options.mode)

110 +

if (options.tmpfileCreated) {

111 +

await options.tmpfileCreated(tmpfile)

112 +

}

113 +

if (ArrayBuffer.isView(data)) {

114 +

await promisify(fs.write)(fd, data, 0, data.length, 0)

115 +

} else if (data != null) {

116 +

await promisify(fs.write)(fd, String(data), 0, String(options.encoding || 'utf8'))

117 +

}

118 + 119 +

if (options.fsync !== false) {

120 +

await promisify(fs.fsync)(fd)

121 +

}

122 + 123 +

await promisify(fs.close)(fd)

124 +

fd = null

125 + 126 +

if (options.chown) {

127 +

await promisify(fs.chown)(tmpfile, options.chown.uid, options.chown.gid).catch(err => {

128 +

if (!isChownErrOk(err)) {

129 +

throw err

130 +

}

131 +

})

132 +

}

133 + 134 +

if (options.mode) {

135 +

await promisify(fs.chmod)(tmpfile, options.mode).catch(err => {

136 +

if (!isChownErrOk(err)) {

137 +

throw err

138 +

}

139 +

})

140 +

}

141 + 142 +

await promisify(fs.rename)(tmpfile, truename)

143 +

} finally {

144 +

if (fd) {

145 +

await promisify(fs.close)(fd).catch(

146 +

/* istanbul ignore next */

147 +

() => {}

148 +

)

149 +

}

150 +

removeOnExitHandler()

151 +

await promisify(fs.unlink)(tmpfile).catch(() => {})

152 +

activeFiles[absoluteName].shift() // remove the element added by serializeSameFile

153 +

if (activeFiles[absoluteName].length > 0) {

154 +

activeFiles[absoluteName][0]() // start next job if one is pending

155 +

} else {

156 +

delete activeFiles[absoluteName]

157 +

}

158 +

}

159 +

}

160 + 161 +

async function writeFile (filename, data, options, callback) {

162 +

if (options instanceof Function) {

163 +

callback = options

164 +

options = {}

165 +

}

166 + 167 +

const promise = writeFileAsync(filename, data, options)

168 +

if (callback) {

169 +

try {

170 +

const result = await promise

171 +

return callback(result)

172 +

} catch (err) {

173 +

return callback(err)

174 +

}

175 +

}

176 + 177 +

return promise

178 +

}

179 + 180 +

function writeFileSync (filename, data, options) {

181 +

if (typeof options === 'string') {

182 +

options = { encoding: options }

183 +

} else if (!options) {

184 +

options = {}

185 +

}

186 +

try {

187 +

filename = fs.realpathSync(filename)

188 +

} catch (ex) {

189 +

// it's ok, it'll happen on a not yet existing file

190 +

}

191 +

const tmpfile = getTmpname(filename)

192 + 193 +

if (!options.mode || !options.chown) {

194 +

// Either mode or chown is not explicitly set

195 +

// Default behavior is to copy it from original file

196 +

try {

197 +

const stats = fs.statSync(filename)

198 +

options = Object.assign({}, options)

199 +

if (!options.mode) {

200 +

options.mode = stats.mode

201 +

}

202 +

if (!options.chown && process.getuid) {

203 +

options.chown = { uid: stats.uid, gid: stats.gid }

204 +

}

205 +

} catch (ex) {

206 +

// ignore stat errors

207 +

}

208 +

}

209 + 210 +

let fd

211 +

const cleanup = cleanupOnExit(tmpfile)

212 +

const removeOnExitHandler = onExit(cleanup)

213 + 214 +

let threw = true

215 +

try {

216 +

fd = fs.openSync(tmpfile, 'w', options.mode || 0o666)

217 +

if (options.tmpfileCreated) {

218 +

options.tmpfileCreated(tmpfile)

219 +

}

220 +

if (ArrayBuffer.isView(data)) {

221 +

fs.writeSync(fd, data, 0, data.length, 0)

222 +

} else if (data != null) {

223 +

fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8'))

224 +

}

225 +

if (options.fsync !== false) {

226 +

fs.fsyncSync(fd)

227 +

}

228 + 229 +

fs.closeSync(fd)

230 +

fd = null

231 + 232 +

if (options.chown) {

233 +

try {

234 +

fs.chownSync(tmpfile, options.chown.uid, options.chown.gid)

235 +

} catch (err) {

236 +

if (!isChownErrOk(err)) {

237 +

throw err

238 +

}

239 +

}

240 +

}

241 + 242 +

if (options.mode) {

243 +

try {

244 +

fs.chmodSync(tmpfile, options.mode)

245 +

} catch (err) {

246 +

if (!isChownErrOk(err)) {

247 +

throw err

248 +

}

249 +

}

250 +

}

251 + 252 +

fs.renameSync(tmpfile, filename)

253 +

threw = false

254 +

} finally {

255 +

if (fd) {

256 +

try {

257 +

fs.closeSync(fd)

258 +

} catch (ex) {

259 +

// ignore close errors at this stage, error may have closed fd already.

260 +

}

261 +

}

262 +

removeOnExitHandler()

263 +

if (threw) {

264 +

cleanup()

265 +

}

266 +

}

267 +

}


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4