123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- var fs = require("fs")
- , cons = require("constants")
- module.exports = touch
- touch.touchSync = touch.sync = function (f, options) {
- return touch(f, options)
- }
- touch.ftouch = ftouch
- touch.ftouchSync = ftouch.sync = function (fd, options) {
- return ftouch(fd, options)
- }
- function validOpts (options) {
- options = Object.create(options || {})
- // {mtime: true}, {ctime: true}
- // If set to something else, then treat as epoch ms value
- var now = new Date(options.time || Date.now())
- if (!options.atime && !options.mtime) {
- options.atime = options.mtime = now
- } else {
- if (true === options.atime) {
- options.atime = now
- }
- if (true === options.mtime) {
- options.mtime = now
- }
- }
- var oflags = 0
- if (!options.force) {
- oflags = oflags | cons.O_RDWR
- }
- if (!options.nocreate) {
- oflags = oflags | cons.O_CREAT
- }
- options.oflags = oflags
- return options
- }
- function optionsRef (then, arg, options, cb) {
- if (!options.ref) return then(arg, options, cb)
- return cb
- ? fs.stat(options.ref, optionsRefcb(then, arg, options, cb))
- : optionsRefcb(then, arg, options)(null, fs.statSync(options.ref))
- }
- function optionsRefcb (then, arg, options, cb) { return function (er, s) {
- if (er) {
- er.path = er.file = options.ref
- return cb(er)
- }
- options.atime = options.atime && s.atime.getTime()
- options.mtime = options.mtime && s.mtime.getTime()
- // so we don't keep doing this.
- options.ref = null
- return then(arg, options, cb)
- }}
- function touch (f, options, cb) {
- if (typeof options === "function") cb = options, options = null
- options = validOpts(options)
- return optionsRef(touch_, f, validOpts(options), cb)
- }
- function touch_ (f, options, cb) {
- return openThenF(f, options, cb)
- }
- function openThenF (f, options, cb) {
- options.closeAfter = true
- return cb
- ? fs.open(f, options.oflags, openThenFcb(options, cb))
- : openThenFcb(options)(null, fs.openSync(f, options.oflags))
- }
- function openThenFcb (options, cb) { return function (er, fd) {
- if (er) {
- if (fd && options.closeAfter) fs.close(fd, function () {})
- return cb(er)
- }
- return ftouch(fd, options, cb)
- }}
- function ftouch (fd, options, cb) {
- if (typeof options === "function") cb = options, options = null
- return optionsRef(ftouch_, fd, validOpts(options), cb)
- }
- function ftouch_ (fd, options, cb) {
- // still not set. leave as what the file already has.
- return fstatThenFutimes(fd, options, cb)
- }
- function fstatThenFutimes (fd, options, cb) {
- if (options.atime && options.mtime) return thenFutimes(fd, options, cb)
- return cb
- ? fs.fstat(fd, fstatThenFutimescb(fd, options, cb))
- : fstatThenFutimescb(fd, options)(null, fs.fstatSync(fd))
- }
- function fstatThenFutimescb (fd, options, cb) { return function (er, s) {
- if (er) {
- if (options.closeAfter) fs.close(fd, function () {})
- return cb(er)
- }
- options.atime = options.atime || s.atime.getTime()
- options.mtime = options.mtime || s.mtime.getTime()
- return thenFutimes(fd, options, cb)
- }}
- function thenFutimes (fd, options, cb) {
- if (typeof options.atime === "object") {
- options.atime = options.atime.getTime()
- }
- if (typeof options.mtime === "object") {
- options.mtime = options.mtime.getTime()
- }
- var a = parseInt(options.atime / 1000, 10)
- , m = parseInt(options.mtime / 1000, 10)
- return cb
- ? fs.futimes(fd, a, m, thenFutimescb(fd, options, cb))
- : thenFutimescb(fd, options)(null, fs.futimesSync(fd, a, m))
- }
- function thenFutimescb (fd, options, cb) { return function (er, res) {
- if (er) {
- if (options.closeAfter) fs.close(fd, function () {})
- return cb(er)
- }
- return finish(fd, options, res, cb)
- }}
- function finish (fd, options, res, cb) {
- return options.closeAfter ? finishClose(fd, options, res, cb)
- : cb ? cb(null, res)
- : res
- }
- function finishClose (fd, options, res, cb) {
- return cb
- ? fs.close(fd, finishClosecb(res, options, cb))
- : finishClosecb(res, options)(null, fs.closeSync(fd))
- }
- function finishClosecb (res, options, cb) { return function (er) {
- if (er) return cb(er)
- options.closeAfter = null
- return finish(null, options, res, cb)
- }}
|