File System (fs) is lacking bindings for lutimes(3), and thus it is very difficult to modify the metadata for a symbolic link from within a Node.js application. This C Library function has been implemented in glibc since version 2.6, which is over 10 years old, and has likely been available on the Mac for even longer, given its origins in BSD UNIX. The behavior on Windows could simply be to call utimes(2).
This omission seems like an oversight given the support for symbolic link-aware functions including: lstat, lchmod, and lchown. Additionally, its peer function futimes(3) is also already supported.
@System-Arch - I am interested to know the use case for lutimes. Agree that decades of existence in the C runtime provides sufficient relevance, but getting / setting time attributes of a symbolic link (in contrast to a physical file that holds business data) looks like a (file) sys-admin's use case to me, not much for general purpose programs. Thoughts?
https://github.com/nodejs/node-v0.x-archive/issues/2142 - almost six years old to the day. :-)
This omission seems like an oversight given the support for symbolic link-aware functions including: lstat, lchmod, and lchown.
Note that the last two are only available on BSD-like systems (although they could be implemented on Linux now - kernel support used to be an issue.)
If you're on a BSD-like system, you can already do this:
const fs = require('fs');
const { O_WRONLY, O_SYMLINK } = fs.constants;
const fd = fs.openSync(filename, O_WRONLY | O_SYMLINK);
fs.futimesSync(fd, atime, mtime);
That is in fact how fs.lchmod() and fs.lchown() are implemented.
I'd like to work on this if people want it to be added.
@gireeshpunathil - I am developing an "update installer" that makes extensive use of time stamps (and other info) to determine which files have or need to be updated (i.e., to achieve idempotency). Symbolic links threw a wrinkle into this plan, but using fs.lstat in place of fs.stat took care of most of the issues along with using fs.symlink in place of fs.copyFile. The one real difficulty was trying to set the time stamps of the symbolic links as fs.utimes works great for files but does not handle symlinks. Having fs.lutimes would address this issue and preserve the simplicity of my overall approach. I was able to prove out the concept by making a system call to "touch -h" but this is platform dependent (e.g., Mac doesn't accept @
@bnoordhuis - My application does not require fs.lchmod() or fs.lchown(), so I was probably over zealous in citing those in my analysis. I did try the fs.open() with O_SYMLINK approach but it did not appear to work on Linux (not too surprising since it is not BSD). lutimes(3) does appear to be portable across both Linux and Mac OSX at the C run-time library API level. Thanks.
@chris--young - Thanks for volunteering. It would be great to see this missing functionality added. Thanks.
@chris--young It needs to be added to libuv first. It's trivial for Unices (see uv_fs_futime() in src/unix/fs.c) but it should also do something reasonable on Windows, if at all possible.
@bnoordhuis awesome, I鈥檒l start there.
@bnoordhuis @chris--young - To my surprise. it looks like libuv does actually support symbolic links in win/fs.c::fs__stat_impl(), so presumably a similar approach can be used to provide full support for lutimes on Windows. Thanks.
Put into https://github.com/nodejs/node/projects/13 backlog
This binding being missing makes it difficult (impossible?) to make perfect copy algorithms, which in turns make it very difficult to generate deterministic archives (in the sense that the same operations will end up with the same checksum).
PR by @arcanis https://github.com/nodejs/node/pull/33399