11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 51cb0ef41Sopenharmony_citmpdir.refresh(); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst assert = require('assert'); 81cb0ef41Sopenharmony_ciconst fs = require('fs'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci// Check for Y2K38 support. For Windows, assume it's there. Windows 111cb0ef41Sopenharmony_ci// doesn't have `touch` and `date -r` which are used in the check for support. 121cb0ef41Sopenharmony_ciif (!common.isWindows) { 131cb0ef41Sopenharmony_ci const testFilePath = `${tmpdir.path}/y2k38-test`; 141cb0ef41Sopenharmony_ci const testFileDate = '204001020304'; 151cb0ef41Sopenharmony_ci const { spawnSync } = require('child_process'); 161cb0ef41Sopenharmony_ci const touchResult = spawnSync('touch', 171cb0ef41Sopenharmony_ci ['-t', testFileDate, testFilePath], 181cb0ef41Sopenharmony_ci { encoding: 'utf8' }); 191cb0ef41Sopenharmony_ci if (touchResult.status !== 0) { 201cb0ef41Sopenharmony_ci common.skip('File system appears to lack Y2K38 support (touch failed)'); 211cb0ef41Sopenharmony_ci } 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci // On some file systems that lack Y2K38 support, `touch` will succeed but 241cb0ef41Sopenharmony_ci // the time will be incorrect. 251cb0ef41Sopenharmony_ci const dateResult = spawnSync('date', 261cb0ef41Sopenharmony_ci ['-r', testFilePath, '+%Y%m%d%H%M'], 271cb0ef41Sopenharmony_ci { encoding: 'utf8' }); 281cb0ef41Sopenharmony_ci if (dateResult.status === 0) { 291cb0ef41Sopenharmony_ci if (dateResult.stdout.trim() !== testFileDate) { 301cb0ef41Sopenharmony_ci common.skip('File system appears to lack Y2k38 support (date failed)'); 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci } else { 331cb0ef41Sopenharmony_ci // On some platforms `date` may not support the `-r` option. Usually 341cb0ef41Sopenharmony_ci // this will result in a non-zero status and usage information printed. 351cb0ef41Sopenharmony_ci // In this case optimistically proceed -- the earlier `touch` succeeded 361cb0ef41Sopenharmony_ci // but validation that the file has the correct time is not easily possible. 371cb0ef41Sopenharmony_ci assert.match(dateResult.stderr, /[Uu]sage:/); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci} 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci// Ref: https://github.com/nodejs/node/issues/13255 421cb0ef41Sopenharmony_ciconst path = `${tmpdir.path}/test-utimes-precision`; 431cb0ef41Sopenharmony_cifs.writeFileSync(path, ''); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ciconst Y2K38_mtime = 2 ** 31; 461cb0ef41Sopenharmony_cifs.utimesSync(path, Y2K38_mtime, Y2K38_mtime); 471cb0ef41Sopenharmony_ciconst Y2K38_stats = fs.statSync(path); 481cb0ef41Sopenharmony_ciassert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciif (common.isWindows) { 511cb0ef41Sopenharmony_ci // This value would get converted to (double)1713037251359.9998 521cb0ef41Sopenharmony_ci const truncate_mtime = 1713037251360; 531cb0ef41Sopenharmony_ci fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000); 541cb0ef41Sopenharmony_ci const truncate_stats = fs.statSync(path); 551cb0ef41Sopenharmony_ci assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci // test Y2K38 for windows 581cb0ef41Sopenharmony_ci // This value if treaded as a `signed long` gets converted to -2135622133469. 591cb0ef41Sopenharmony_ci // POSIX systems stores timestamps in {long t_sec, long t_usec}. 601cb0ef41Sopenharmony_ci // NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv 611cb0ef41Sopenharmony_ci // calculates (long)`uv_timespec_t.tv_sec` we get 2's complement. 621cb0ef41Sopenharmony_ci const overflow_mtime = 2159345162531; 631cb0ef41Sopenharmony_ci fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000); 641cb0ef41Sopenharmony_ci const overflow_stats = fs.statSync(path); 651cb0ef41Sopenharmony_ci assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime); 661cb0ef41Sopenharmony_ci} 67