| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 319707a commit cf97c56
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2392,6 +2392,38 @@ changes: | |||
| 2392 | 2392 | ||
| 2393 | 2393 | Synchronous lchown(2). Returns `undefined`. | |
| 2394 | 2394 | ||
| 2395 | + ## `fs.lutimes(path, atime, mtime, callback)` | ||
| 2396 | + <!-- YAML | ||
| 2397 | + addded: REPLACEME | ||
| 2398 | + --> | ||
| 2399 | + | ||
| 2400 | + * `path` {string|Buffer|URL} | ||
| 2401 | + * `atime` {number|string|Date} | ||
| 2402 | + * `mtime` {number|string|Date} | ||
| 2403 | + * `callback` {Function} | ||
| 2404 | + * `err` {Error} | ||
| 2405 | + | ||
| 2406 | + Changes the access and modification times of a file in the same way as | ||
| 2407 | + [`fs.utimes()`][], with the difference that if the path refers to a symbolic | ||
| 2408 | + link, then the link is not dereferenced: instead, the timestamps of the | ||
| 2409 | + symbolic link itself are changed. | ||
| 2410 | + | ||
| 2411 | + No arguments other than a possible exception are given to the completion | ||
| 2412 | + callback. | ||
| 2413 | + | ||
| 2414 | + ## `fs.lutimesSync(path, atime, mtime)` | ||
| 2415 | + <!-- YAML | ||
| 2416 | + added: REPLACEME | ||
| 2417 | + --> | ||
| 2418 | + | ||
| 2419 | + * `path` {string|Buffer|URL} | ||
| 2420 | + * `atime` {number|string|Date} | ||
| 2421 | + * `mtime` {number|string|Date} | ||
| 2422 | + | ||
| 2423 | + Change the file system timestamps of the symbolic link referenced by `path`. | ||
| 2424 | + Returns `undefined`, or throws an exception when parameters are incorrect or | ||
| 2425 | + the operation fails. This is the synchronous version of [`fs.lutimes()`][]. | ||
| 2426 | + | ||
| 2395 | 2427 | ## `fs.link(existingPath, newPath, callback)` | |
| 2396 | 2428 | <!-- YAML | |
| 2397 | 2429 | added: v0.1.31 | |
@@ -5011,6 +5043,23 @@ changes: | |||
| 5011 | 5043 | Changes the ownership on a symbolic link then resolves the `Promise` with | |
| 5012 | 5044 | no arguments upon success. | |
| 5013 | 5045 | ||
| 5046 | + ### `fsPromises.lutimes(path, atime, mtime)` | ||
| 5047 | + <!-- YAML | ||
| 5048 | + added: REPLACEME | ||
| 5049 | + --> | ||
| 5050 | + | ||
| 5051 | + * `path` {string|Buffer|URL} | ||
| 5052 | + * `atime` {number|string|Date} | ||
| 5053 | + * `mtime` {number|string|Date} | ||
| 5054 | + * Returns: {Promise} | ||
| 5055 | + | ||
| 5056 | + Changes the access and modification times of a file in the same way as | ||
| 5057 | + [`fsPromises.utimes()`][], with the difference that if the path refers to a | ||
| 5058 | + symbolic link, then the link is not dereferenced: instead, the timestamps of | ||
| 5059 | + the symbolic link itself are changed. | ||
| 5060 | + | ||
| 5061 | + Upon success, the `Promise` is resolved without arguments. | ||
| 5062 | + | ||
| 5014 | 5063 | ### `fsPromises.link(existingPath, newPath)` | |
| 5015 | 5064 | <!-- YAML | |
| 5016 | 5065 | added: v10.0.0 | |
@@ -5829,6 +5878,7 @@ the file contents. | |||
| 5829 | 5878 | [`fs.ftruncate()`]: #fs_fs_ftruncate_fd_len_callback | |
| 5830 | 5879 | [`fs.futimes()`]: #fs_fs_futimes_fd_atime_mtime_callback | |
| 5831 | 5880 | [`fs.lstat()`]: #fs_fs_lstat_path_options_callback | |
| 5881 | + [`fs.lutimes()`]: #fs_fs_lutimes_path_atime_mtime_callback | ||
| 5832 | 5882 | [`fs.mkdir()`]: #fs_fs_mkdir_path_options_callback | |
| 5833 | 5883 | [`fs.mkdtemp()`]: #fs_fs_mkdtemp_prefix_options_callback | |
| 5834 | 5884 | [`fs.open()`]: #fs_fs_open_path_flags_mode_callback | |
@@ -5852,6 +5902,7 @@ the file contents. | |||
| 5852 | 5902 | [`fs.writev()`]: #fs_fs_writev_fd_buffers_position_callback | |
| 5853 | 5903 | [`fsPromises.open()`]: #fs_fspromises_open_path_flags_mode | |
| 5854 | 5904 | [`fsPromises.opendir()`]: #fs_fspromises_opendir_path_options | |
| 5905 | + [`fsPromises.utimes()`]: #fs_fspromises_utimes_path_atime_mtime | ||
| 5855 | 5906 | [`inotify(7)`]: http://man7.org/linux/man-pages/man7/inotify.7.html | |
| 5856 | 5907 | [`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 | |
| 5857 | 5908 | [`net.Socket`]: net.html#net_class_net_socket | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1325,6 +1325,28 @@ function futimesSync(fd, atime, mtime) { | |||
| 1325 | 1325 | handleErrorFromBinding(ctx); | |
| 1326 | 1326 | } | |
| 1327 | 1327 | ||
| 1328 | + function lutimes(path, atime, mtime, callback) { | ||
| 1329 | + callback = makeCallback(callback); | ||
| 1330 | + path = getValidatedPath(path); | ||
| 1331 | + | ||
| 1332 | + const req = new FSReqCallback(); | ||
| 1333 | + req.oncomplete = callback; | ||
| 1334 | + binding.lutimes(pathModule.toNamespacedPath(path), | ||
| 1335 | + toUnixTimestamp(atime), | ||
| 1336 | + toUnixTimestamp(mtime), | ||
| 1337 | + req); | ||
| 1338 | + } | ||
| 1339 | + | ||
| 1340 | + function lutimesSync(path, atime, mtime) { | ||
| 1341 | + path = getValidatedPath(path); | ||
| 1342 | + const ctx = { path }; | ||
| 1343 | + binding.lutimes(pathModule.toNamespacedPath(path), | ||
| 1344 | + toUnixTimestamp(atime), | ||
| 1345 | + toUnixTimestamp(mtime), | ||
| 1346 | + undefined, ctx); | ||
| 1347 | + handleErrorFromBinding(ctx); | ||
| 1348 | + } | ||
| 1349 | + | ||
| 1328 | 1350 | function writeAll(fd, isUserFd, buffer, offset, length, callback) { | |
| 1329 | 1351 | // write(fd, buffer, offset, length, position, callback) | |
| 1330 | 1352 | fs.write(fd, buffer, offset, length, null, (writeErr, written) => { | |
@@ -1971,6 +1993,8 @@ module.exports = fs = { | |||
| 1971 | 1993 | linkSync, | |
| 1972 | 1994 | lstat, | |
| 1973 | 1995 | lstatSync, | |
| 1996 | + lutimes, | ||
| 1997 | + lutimesSync, | ||
| 1974 | 1998 | mkdir, | |
| 1975 | 1999 | mkdirSync, | |
| 1976 | 2000 | mkdtemp, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -510,6 +510,14 @@ async function futimes(handle, atime, mtime) { | |||
| 510 | 510 | return binding.futimes(handle.fd, atime, mtime, kUsePromises); | |
| 511 | 511 | } | |
| 512 | 512 | ||
| 513 | + async function lutimes(path, atime, mtime) { | ||
| 514 | + path = getValidatedPath(path); | ||
| 515 | + return binding.lutimes(pathModule.toNamespacedPath(path), | ||
| 516 | + toUnixTimestamp(atime), | ||
| 517 | + toUnixTimestamp(mtime), | ||
| 518 | + kUsePromises); | ||
| 519 | + } | ||
| 520 | + | ||
| 513 | 521 | async function realpath(path, options) { | |
| 514 | 522 | options = getOptions(options, {}); | |
| 515 | 523 | path = getValidatedPath(path); | |
@@ -582,6 +590,7 @@ module.exports = { | |||
| 582 | 590 | lchown, | |
| 583 | 591 | chown, | |
| 584 | 592 | utimes, | |
| 593 | + lutimes, | ||
| 585 | 594 | realpath, | |
| 586 | 595 | mkdtemp, | |
| 587 | 596 | writeFile, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2304,6 +2304,35 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) { | |||
| 2304 | 2304 | } | |
| 2305 | 2305 | } | |
| 2306 | 2306 | ||
| 2307 | + static void LUTimes(const FunctionCallbackInfo<Value>& args) { | ||
| 2308 | + Environment* env = Environment::GetCurrent(args); | ||
| 2309 | + | ||
| 2310 | + const int argc = args.Length(); | ||
| 2311 | + CHECK_GE(argc, 3); | ||
| 2312 | + | ||
| 2313 | + BufferValue path(env->isolate(), args[0]); | ||
| 2314 | + CHECK_NOT_NULL(*path); | ||
| 2315 | + | ||
| 2316 | + CHECK(args[1]->IsNumber()); | ||
| 2317 | + const double atime = args[1].As<Number>()->Value(); | ||
| 2318 | + | ||
| 2319 | + CHECK(args[2]->IsNumber()); | ||
| 2320 | + const double mtime = args[2].As<Number>()->Value(); | ||
| 2321 | + | ||
| 2322 | + FSReqBase* req_wrap_async = GetReqWrap(args, 3); | ||
| 2323 | + if (req_wrap_async != nullptr) { // lutimes(path, atime, mtime, req) | ||
| 2324 | + AsyncCall(env, req_wrap_async, args, "lutime", UTF8, AfterNoArgs, | ||
| 2325 | + uv_fs_lutime, *path, atime, mtime); | ||
| 2326 | + } else { // lutimes(path, atime, mtime, undefined, ctx) | ||
| 2327 | + CHECK_EQ(argc, 5); | ||
| 2328 | + FSReqWrapSync req_wrap_sync; | ||
| 2329 | + FS_SYNC_TRACE_BEGIN(lutimes); | ||
| 2330 | + SyncCall(env, args[4], &req_wrap_sync, "lutime", | ||
| 2331 | + uv_fs_lutime, *path, atime, mtime); | ||
| 2332 | + FS_SYNC_TRACE_END(lutimes); | ||
| 2333 | + } | ||
| 2334 | + } | ||
| 2335 | + | ||
| 2307 | 2336 | static void Mkdtemp(const FunctionCallbackInfo<Value>& args) { | |
| 2308 | 2337 | Environment* env = Environment::GetCurrent(args); | |
| 2309 | 2338 | Isolate* isolate = env->isolate(); | |
@@ -2399,6 +2428,7 @@ void Initialize(Local<Object> target, | |||
| 2399 | 2428 | ||
| 2400 | 2429 | env->SetMethod(target, "utimes", UTimes); | |
| 2401 | 2430 | env->SetMethod(target, "futimes", FUTimes); | |
| 2431 | + env->SetMethod(target, "lutimes", LUTimes); | ||
| 2402 | 2432 | ||
| 2403 | 2433 | env->SetMethod(target, "mkdtemp", Mkdtemp); | |
| 2404 | 2434 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,13 +24,17 @@ const common = require('../common'); | |||
| 24 | 24 | const assert = require('assert'); | |
| 25 | 25 | const util = require('util'); | |
| 26 | 26 | const fs = require('fs'); | |
| 27 | + const url = require('url'); | ||
| 27 | 28 | ||
| 28 | 29 | const tmpdir = require('../common/tmpdir'); | |
| 29 | 30 | tmpdir.refresh(); | |
| 30 | 31 | ||
| 31 | - function stat_resource(resource) { | ||
| 32 | + const lpath = `${tmpdir.path}/symlink`; | ||
| 33 | + fs.symlinkSync('unoent-entry', lpath); | ||
| 34 | + | ||
| 35 | + function stat_resource(resource, statSync = fs.statSync) { | ||
| 32 | 36 | if (typeof resource === 'string') { | |
| 33 | - return fs.statSync(resource); | ||
| 37 | + return statSync(resource); | ||
| 34 | 38 | } | |
| 35 | 39 | const stats = fs.fstatSync(resource); | |
| 36 | 40 | // Ensure mtime has been written to disk | |
@@ -41,9 +45,9 @@ function stat_resource(resource) { | |||
| 41 | 45 | return fs.fstatSync(resource); | |
| 42 | 46 | } | |
| 43 | 47 | ||
| 44 | - function check_mtime(resource, mtime) { | ||
| 48 | + function check_mtime(resource, mtime, statSync) { | ||
| 45 | 49 | mtime = fs._toUnixTimestamp(mtime); | |
| 46 | - const stats = stat_resource(resource); | ||
| 50 | + const stats = stat_resource(resource, statSync); | ||
| 47 | 51 | const real_mtime = fs._toUnixTimestamp(stats.mtime); | |
| 48 | 52 | return mtime - real_mtime; | |
| 49 | 53 | } | |
@@ -55,8 +59,8 @@ function expect_errno(syscall, resource, err, errno) { | |||
| 55 | 59 | ); | |
| 56 | 60 | } | |
| 57 | 61 | ||
| 58 | - function expect_ok(syscall, resource, err, atime, mtime) { | ||
| 59 | - const mtime_diff = check_mtime(resource, mtime); | ||
| 62 | + function expect_ok(syscall, resource, err, atime, mtime, statSync) { | ||
| 63 | + const mtime_diff = check_mtime(resource, mtime, statSync); | ||
| 60 | 64 | assert( | |
| 61 | 65 | // Check up to single-second precision. | |
| 62 | 66 | // Sub-second precision is OS and fs dependant. | |
@@ -68,45 +72,55 @@ function expect_ok(syscall, resource, err, atime, mtime) { | |||
| 68 | 72 | ||
| 69 | 73 | const stats = fs.statSync(tmpdir.path); | |
| 70 | 74 | ||
| 75 | + const asPath = (path) => path; | ||
| 76 | + const asUrl = (path) => url.pathToFileURL(path); | ||
| 77 | + | ||
| 71 | 78 | const cases = [ | |
| 72 | - new Date('1982-09-10 13:37'), | ||
| 73 | - new Date(), | ||
| 74 | - 123456.789, | ||
| 75 | - stats.mtime, | ||
| 76 | - ['123456', -1], | ||
| 77 | - new Date('2017-04-08T17:59:38.008Z') | ||
| 79 | + [asPath, new Date('1982-09-10 13:37')], | ||
| 80 | + [asPath, new Date()], | ||
| 81 | + [asPath, 123456.789], | ||
| 82 | + [asPath, stats.mtime], | ||
| 83 | + [asPath, '123456', -1], | ||
| 84 | + [asPath, new Date('2017-04-08T17:59:38.008Z')], | ||
| 85 | + [asUrl, new Date()], | ||
| 78 | 86 | ]; | |
| 87 | + | ||
| 79 | 88 | runTests(cases.values()); | |
| 80 | 89 | ||
| 81 | 90 | function runTests(iter) { | |
| 82 | 91 | const { value, done } = iter.next(); | |
| 83 | 92 | if (done) return; | |
| 93 | + | ||
| 84 | 94 | // Support easy setting same or different atime / mtime values. | |
| 85 | - const [atime, mtime] = Array.isArray(value) ? value : [value, value]; | ||
| 95 | + const [pathType, atime, mtime = atime] = value; | ||
| 86 | 96 | ||
| 87 | 97 | let fd; | |
| 88 | 98 | // | |
| 89 | 99 | // test async code paths | |
| 90 | 100 | // | |
| 91 | - fs.utimes(tmpdir.path, atime, mtime, common.mustCall((err) => { | ||
| 101 | + fs.utimes(pathType(tmpdir.path), atime, mtime, common.mustCall((err) => { | ||
| 92 | 102 | expect_ok('utimes', tmpdir.path, err, atime, mtime); | |
| 93 | 103 | ||
| 94 | - fs.utimes('foobarbaz', atime, mtime, common.mustCall((err) => { | ||
| 95 | - expect_errno('utimes', 'foobarbaz', err, 'ENOENT'); | ||
| 104 | + fs.lutimes(pathType(lpath), atime, mtime, common.mustCall((err) => { | ||
| 105 | + expect_ok('lutimes', lpath, err, atime, mtime, fs.lstatSync); | ||
| 106 | + | ||
| 107 | + fs.utimes(pathType('foobarbaz'), atime, mtime, common.mustCall((err) => { | ||
| 108 | + expect_errno('utimes', 'foobarbaz', err, 'ENOENT'); | ||
| 96 | 109 | ||
| 97 | - // don't close this fd | ||
| 98 | - if (common.isWindows) { | ||
| 99 | - fd = fs.openSync(tmpdir.path, 'r+'); | ||
| 100 | - } else { | ||
| 101 | - fd = fs.openSync(tmpdir.path, 'r'); | ||
| 102 | - } | ||
| 110 | + // don't close this fd | ||
| 111 | + if (common.isWindows) { | ||
| 112 | + fd = fs.openSync(tmpdir.path, 'r+'); | ||
| 113 | + } else { | ||
| 114 | + fd = fs.openSync(tmpdir.path, 'r'); | ||
| 115 | + } | ||
| 103 | 116 | ||
| 104 | - fs.futimes(fd, atime, mtime, common.mustCall((err) => { | ||
| 105 | - expect_ok('futimes', fd, err, atime, mtime); | ||
| 117 | + fs.futimes(fd, atime, mtime, common.mustCall((err) => { | ||
| 118 | + expect_ok('futimes', fd, err, atime, mtime); | ||
| 106 | 119 | ||
| 107 | - syncTests(); | ||
| 120 | + syncTests(); | ||
| 108 | 121 | ||
| 109 | - setImmediate(common.mustCall(runTests), iter); | ||
| 122 | + setImmediate(common.mustCall(runTests), iter); | ||
| 123 | + })); | ||
| 110 | 124 | })); | |
| 111 | 125 | })); | |
| 112 | 126 | })); | |
@@ -115,9 +129,12 @@ function runTests(iter) { | |||
| 115 | 129 | // test synchronized code paths, these functions throw on failure | |
| 116 | 130 | // | |
| 117 | 131 | function syncTests() { | |
| 118 | - fs.utimesSync(tmpdir.path, atime, mtime); | ||
| 132 | + fs.utimesSync(pathType(tmpdir.path), atime, mtime); | ||
| 119 | 133 | expect_ok('utimesSync', tmpdir.path, undefined, atime, mtime); | |
| 120 | 134 | ||
| 135 | + fs.lutimesSync(pathType(lpath), atime, mtime); | ||
| 136 | + expect_ok('lutimesSync', lpath, undefined, atime, mtime, fs.lstatSync); | ||
| 137 | + | ||
| 121 | 138 | // Some systems don't have futimes | |
| 122 | 139 | // if there's an error, it should be ENOSYS | |
| 123 | 140 | try { | |
@@ -129,7 +146,7 @@ function runTests(iter) { | |||
| 129 | 146 | ||
| 130 | 147 | let err; | |
| 131 | 148 | try { | |
| 132 | - fs.utimesSync('foobarbaz', atime, mtime); | ||
| 149 | + fs.utimesSync(pathType('foobarbaz'), atime, mtime); | ||
| 133 | 150 | } catch (ex) { | |
| 134 | 151 | err = ex; | |
| 135 | 152 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments