@@ -205,6 +205,20 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
205205}
206206
207207
208+ UV_UNUSED (static struct timespec uv__fs_to_timespec (double time )) {
209+ struct timespec ts ;
210+ ts .tv_sec = time ;
211+ ts .tv_nsec = (uint64_t )(time * 1000000 ) % 1000000 * 1000 ;
212+ return ts ;
213+ }
214+
215+ UV_UNUSED (static struct timeval uv__fs_to_timeval (double time )) {
216+ struct timeval tv ;
217+ tv .tv_sec = time ;
218+ tv .tv_usec = (uint64_t )(time * 1000000 ) % 1000000 ;
219+ return tv ;
220+ }
221+
208222static ssize_t uv__fs_futime (uv_fs_t * req ) {
209223#if defined(__linux__ ) \
210224 || defined(_AIX71 ) \
@@ -213,10 +227,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
213227 * for the sake of consistency with other platforms.
214228 */
215229 struct timespec ts [2 ];
216- ts [0 ].tv_sec = req -> atime ;
217- ts [0 ].tv_nsec = (uint64_t )(req -> atime * 1000000 ) % 1000000 * 1000 ;
218- ts [1 ].tv_sec = req -> mtime ;
219- ts [1 ].tv_nsec = (uint64_t )(req -> mtime * 1000000 ) % 1000000 * 1000 ;
230+ ts [0 ] = uv__fs_to_timespec (req -> atime );
231+ ts [1 ] = uv__fs_to_timespec (req -> mtime );
220232#if defined(__ANDROID_API__ ) && __ANDROID_API__ < 21
221233 return utimensat (req -> file , NULL , ts , 0 );
222234#else
@@ -230,10 +242,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
230242 || defined(__OpenBSD__ ) \
231243 || defined(__sun )
232244 struct timeval tv [2 ];
233- tv [0 ].tv_sec = req -> atime ;
234- tv [0 ].tv_usec = (uint64_t )(req -> atime * 1000000 ) % 1000000 ;
235- tv [1 ].tv_sec = req -> mtime ;
236- tv [1 ].tv_usec = (uint64_t )(req -> mtime * 1000000 ) % 1000000 ;
245+ tv [0 ] = uv__fs_to_timeval (req -> atime );
246+ tv [1 ] = uv__fs_to_timeval (req -> mtime );
237247# if defined(__sun )
238248 return futimesat (req -> file , NULL , tv );
239249# else
@@ -972,10 +982,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
972982 * for the sake of consistency with other platforms.
973983 */
974984 struct timespec ts [2 ];
975- ts [0 ].tv_sec = req -> atime ;
976- ts [0 ].tv_nsec = (uint64_t )(req -> atime * 1000000 ) % 1000000 * 1000 ;
977- ts [1 ].tv_sec = req -> mtime ;
978- ts [1 ].tv_nsec = (uint64_t )(req -> mtime * 1000000 ) % 1000000 * 1000 ;
985+ ts [0 ] = uv__fs_to_timespec (req -> atime );
986+ ts [1 ] = uv__fs_to_timespec (req -> mtime );
979987 return utimensat (AT_FDCWD , req -> path , ts , 0 );
980988#elif defined(__APPLE__ ) \
981989 || defined(__DragonFly__ ) \
@@ -984,10 +992,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
984992 || defined(__NetBSD__ ) \
985993 || defined(__OpenBSD__ )
986994 struct timeval tv [2 ];
987- tv [0 ].tv_sec = req -> atime ;
988- tv [0 ].tv_usec = (uint64_t )(req -> atime * 1000000 ) % 1000000 ;
989- tv [1 ].tv_sec = req -> mtime ;
990- tv [1 ].tv_usec = (uint64_t )(req -> mtime * 1000000 ) % 1000000 ;
995+ tv [0 ] = uv__fs_to_timeval (req -> atime );
996+ tv [1 ] = uv__fs_to_timeval (req -> mtime );
991997 return utimes (req -> path , tv );
992998#elif defined(_AIX ) \
993999 && !defined(_AIX71 )
@@ -1010,6 +1016,31 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
10101016}
10111017
10121018
1019+ static ssize_t uv__fs_lutime (uv_fs_t * req ) {
1020+ #if defined(__linux__ ) || \
1021+ defined(_AIX71 ) || \
1022+ defined(__sun ) || \
1023+ defined(__HAIKU__ )
1024+ struct timespec ts [2 ];
1025+ ts [0 ] = uv__fs_to_timespec (req -> atime );
1026+ ts [1 ] = uv__fs_to_timespec (req -> mtime );
1027+ return utimensat (AT_FDCWD , req -> path , ts , AT_SYMLINK_NOFOLLOW );
1028+ #elif defined(__APPLE__ ) || \
1029+ defined(__DragonFly__ ) || \
1030+ defined(__FreeBSD__ ) || \
1031+ defined(__FreeBSD_kernel__ ) || \
1032+ defined(__NetBSD__ )
1033+ struct timeval tv [2 ];
1034+ tv [0 ] = uv__fs_to_timeval (req -> atime );
1035+ tv [1 ] = uv__fs_to_timeval (req -> mtime );
1036+ return lutimes (req -> path , tv );
1037+ #else
1038+ errno = ENOSYS ;
1039+ return -1 ;
1040+ #endif
1041+ }
1042+
1043+
10131044static ssize_t uv__fs_write (uv_fs_t * req ) {
10141045#if defined(__linux__ )
10151046 static int no_pwritev ;
@@ -1523,6 +1554,7 @@ static void uv__fs_work(struct uv__work* w) {
15231554 X (FSYNC , uv__fs_fsync (req ));
15241555 X (FTRUNCATE , ftruncate (req -> file , req -> off ));
15251556 X (FUTIME , uv__fs_futime (req ));
1557+ X (LUTIME , uv__fs_lutime (req ));
15261558 X (LSTAT , uv__fs_lstat (req -> path , & req -> statbuf ));
15271559 X (LINK , link (req -> path , req -> new_path ));
15281560 X (MKDIR , mkdir (req -> path , req -> mode ));
@@ -1709,6 +1741,19 @@ int uv_fs_futime(uv_loop_t* loop,
17091741 POST ;
17101742}
17111743
1744+ int uv_fs_lutime (uv_loop_t * loop ,
1745+ uv_fs_t * req ,
1746+ const char * path ,
1747+ double atime ,
1748+ double mtime ,
1749+ uv_fs_cb cb ) {
1750+ INIT (LUTIME );
1751+ PATH ;
1752+ req -> atime = atime ;
1753+ req -> mtime = mtime ;
1754+ POST ;
1755+ }
1756+
17121757
17131758int uv_fs_lstat (uv_loop_t * loop , uv_fs_t * req , const char * path , uv_fs_cb cb ) {
17141759 INIT (LSTAT );
0 commit comments