https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?14253458252012-10-11T02:33:14ZRuby Issue Tracking SystemRuby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=301752012-10-11T02:33:14ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul></ul><p>Hey,</p>
<p>Definitely a nice to have feature in the standard library :)</p>
<p>And so... few thoughts / ideas ...</p>
<p>On Linux, it would require both the glibc &gt;= 2.6 and kernel &gt;= 2.6.22 since lutimes() on linux uses the utimensat() system-call (and then do_times() which provides actual interface) with the AT_SYMLINK_NOFOLLOW flag set (defined in fcntl.h). In other words, it might cause problems to some people running older / ancient kernels or having old older glibc. Kernel and glibc would also have to support nanoseconds in the &quot;timespec&quot; struct (e.g. tv_nsec, etc) which is what a similar bug touches on: <a href="http://bugs.ruby-lang.org/issues/7109">http://bugs.ruby-lang.org/issues/7109</a></p>
<p>On *BSD, I guess both kernel and libc support it (at least as per the documentation).</p>
<p>Then, on Solaris / OpenSolaris (or anything that does not have necessary capability), we could create a new temporary symbolic link (with safe unpredictable and randomly generated name) and then move it over to clobber old symbolic link rely on the sheer fact that rename()[1] on most Unix-alike systems should be atomic (it is most of the time guaranteed to be such on the same file system) and should be fast (and in a case of any errors we do not loose original link; excluding critical I/O errors or sudden power down, etc).</p>
<p>On Windows... I have no idea :)</p>
<p>Anyway, hope that helps a little :)</p>
<ol>
<li><a href="http://linux.die.net/man/2/rename">http://linux.die.net/man/2/rename</a></li>
</ol>
<p>KW</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=310222012-10-19T03:54:43ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul><li><strong>File</strong> <a href="/attachments/download/3124/0001-Add-support-for-lutimes-3-to-file.c-as-File-lutime.patch">0001-Add-support-for-lutimes-3-to-file.c-as-File-lutime.patch</a><a href="/attachments/3124/0001-Add-support-for-lutimes-3-to-file.c-as-File-lutime.patch"><img alt="Magnifier" src="/images/magnifier.png?1425345825" /></a> added</li><li><strong>File</strong> <a href="/attachments/download/3125/0002-Add-support-for-File-lutimes-on-Windows.patch">0002-Add-support-for-File-lutimes-on-Windows.patch</a><a href="/attachments/3125/0002-Add-support-for-File-lutimes-on-Windows.patch"><img alt="Magnifier" src="/images/magnifier.png?1425345825" /></a> added</li><li><strong>File</strong> <a href="/attachments/download/3126/0003-Add-support-for-File-lutimes-to-FileUtils.patch">0003-Add-support-for-File-lutimes-to-FileUtils.patch</a><a href="/attachments/3126/0003-Add-support-for-File-lutimes-to-FileUtils.patch"><img alt="Magnifier" src="/images/magnifier.png?1425345825" /></a> added</li></ul><p>Hey,</p>
<p>Small updates regarding this :) Support for nanoseconds in Linux kernel for VFS and stat(2) was added around 2.5.38[1]. Then, adding support of lutimes(3) was already mentioned here: <a href="http://bugs.ruby-lang.org/issues/4052">http://bugs.ruby-lang.org/issues/4052</a></p>
<p>Said that, I have made three small patches that try to address lack of File::lutimes and support for symbolic links in FileUtils::touch. There is no support for the trick involving rename(2) mentioned previously (don&#39;t think such measures are needed), plus implementation is agnostic from whether an underlying architecture supports nanoseconds for atime, mtime and ctime, or not -- this was addressed to some extent already in the code (although, I am not sure about FAT on Windows, as support for any of these there seems to be rather odd).</p>
<p>Anyhow, I would be very grateful is somebody could review them, especially the Windows one as I am not sure if this would be the correct way of handling how to update access and modification time on Windows. This is my first contribution and I am sure it is far from being perfect, but I did run make test-all on many different versions of Linux distributions with different kernel versions in order to make sure that it works as expected. I need to install NetBSD and FreeBSD and test it there.</p>
<p>I hope that helps :)</p>
<ol>
<li><a href="http://lwn.net/Articles/10634/">http://lwn.net/Articles/10634/</a></li>
</ol>
<p>KW</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=314522012-10-24T10:39:45ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul><li><strong>File</strong> <a href="/attachments/download/3143/0001-Add-support-for-lutimes.patch">0001-Add-support-for-lutimes.patch</a><a href="/attachments/3143/0001-Add-support-for-lutimes.patch"><img alt="Magnifier" src="/images/magnifier.png?1425345825" /></a> added</li></ul><p>Hey,</p>
<p>I am adding one large patch, as per Aaron Patterson&#39;s request :-)</p>
<p>KW</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=314832012-10-25T11:57:05ZUsaku NAKAMURAusa@garbagecollect.jp
<ul><li><strong>File</strong> <a href="/attachments/download/3146/0002-Add-support-for-File-lutimes-on-Windows-updated.patch">0002-Add-support-for-File-lutimes-on-Windows-updated.patch</a><a href="/attachments/3146/0002-Add-support-for-File-lutimes-on-Windows-updated.patch"><img alt="Magnifier" src="/images/magnifier.png?1425345825" /></a> added</li></ul><p>Updated a patch for Windows because the old one includes many errors :)</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=324662012-11-06T13:40:45ZLuis Lavenaluislavena@gmail.com
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>Luis Lavena</i></li><li><strong>Target version</strong> changed from <i>1.9.3</i> to <i>2.0.0</i></li></ul> Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=325172012-11-07T06:51:38ZLuis Lavenaluislavena@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Feedback</i></li></ul><p>=begin</p>
<p>I&#39;ve combined your patch and Usa&#39;s Windows modification (plus other misses) and put it here:</p>
<p><a href="https://gist.github.com/4022459">https://gist.github.com/4022459</a></p>
<p>Also, I&#39;ve created the following files on a drive:</p>
<ul>
<li>foo: directory</li>
<li>READ: a real file</li>
</ul>
<p>And created the following type of links:</p>
<ul>
<li>bar: symlinkd (directory symlink) of foo</li>
<li>a-link: symlink of READ</li>
<li>HARD: hardlink of READ</li>
<li><p>junc: a junction point of foo</p>
<p>V:&gt;dir<br>
Volume in drive V is RAMDISK<br>
Volume Serial Number is 9A3E-37F6</p>
<p>Directory of V:\</p>
<p>06/11/2012 12:57 a.m. a-link [READ]<br>
06/11/2012 12:54 a.m. bar [foo]<br>
05/11/2012 09:25 p.m. foo<br>
06/11/2012 12:56 a.m. 7 HARD<br>
06/11/2012 01:02 a.m. junc [V:\foo]<br>
06/11/2012 12:56 a.m. 7 READ<br>
06/11/2012 12:49 a.m. ruby2</p></li>
</ul>
<p>As you can see from the output, all have different timestamps</p>
<p>Now, from IRB:</p>
<p>V:&gt;irb<br>
irb(main):001:0&gt; File.mtime &quot;foo&quot;<br>
=&gt; 2012-11-05 21:25:54 -0300<br>
irb(main):002:0&gt; File.mtime &quot;bar&quot;<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):003:0&gt; File.mtime &quot;junc&quot;<br>
=&gt; 2012-11-06 01:02:03 -0300</p>
<p>On Windows, access of modification time gets the link modification time and not the target.</p>
<p>Same goes for atime and ctime:</p>
<p>irb(main):004:0&gt; [&quot;foo&quot;, &quot;bar&quot;, &quot;junc&quot;].each { |folder| puts File.atime(folder) }<br>
2012-11-05 21:25:54 -0300<br>
2012-11-06 00:54:22 -0300<br>
2012-11-06 01:02:03 -0300</p>
<p>irb(main):006:0&gt; [&quot;foo&quot;, &quot;bar&quot;, &quot;junc&quot;].each { |folder| puts File.ctime(folder) }; nil<br>
2012-11-05 21:23:45 -0300<br>
2012-11-06 00:54:22 -0300<br>
2012-11-06 01:02:03 -0300</p>
<p>Now, doing (({File.utime})) on the symlinkd modifies the target:</p>
<p>irb(main):016:0&gt; a = File.mtime(&quot;foo&quot;)<br>
=&gt; 2012-11-07 00:54:22 -0300<br>
irb(main):017:0&gt; a = File.atime(&quot;bar&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):018:0&gt; File.utime(a, a, &quot;bar&quot;)<br>
=&gt; 1<br>
irb(main):019:0&gt; a = File.atime(&quot;bar&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):020:0&gt; a = File.atime(&quot;foo&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300</p>
<p>But not the symlink, which is expected.</p>
<p>Problem is now that the code around (({rb_file_s_lutime})) avoids it getting defined on Windows, even when functions around it were faked.<br>
(it checks for (({HAVE_LUTIMES})) and that doesn&#39;t exists on Windows)</p>
<p>I did a minor tweak and got that passing (is included in my patch), and now:</p>
<p>V:&gt;irb<br>
irb(main):001:0&gt; a = File.atime(&quot;bar&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):002:0&gt; b = a + 3600<br>
=&gt; 2012-11-06 01:54:22 -0300<br>
irb(main):003:0&gt; File.lutime(b, b, &quot;bar&quot;)<br>
=&gt; 1<br>
irb(main):004:0&gt; File.atime(&quot;bar&quot;)<br>
=&gt; 2012-11-06 01:54:22 -0300<br>
irb(main):005:0&gt; File.atime(&quot;foo&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300</p>
<p>Symlinks can only be created by administrators, but modifying the timestamps (access, modification) is totally possible.</p>
<p>It also works transparently with junction points (which normal users can create too):</p>
<p>irb(main):008:0&gt; File.atime(&quot;junc&quot;)<br>
=&gt; 2012-11-06 01:02:03 -0300<br>
irb(main):009:0&gt; File.atime(&quot;foo&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):010:0&gt; File.lutime(b, b, &quot;junc&quot;)<br>
=&gt; 1<br>
irb(main):011:0&gt; File.atime(&quot;foo&quot;)<br>
=&gt; 2012-11-06 00:54:22 -0300<br>
irb(main):012:0&gt; File.atime(&quot;junc&quot;)<br>
=&gt; 2012-11-06 01:54:22 -0300</p>
<p>And file symlinks (previous were directory symlinks, are two different kind of links):</p>
<p>irb(main):018:0&gt; File.atime(&quot;READ&quot;)<br>
=&gt; 2012-11-06 00:56:43 -0300<br>
irb(main):019:0&gt; File.atime(&quot;a-link&quot;)<br>
=&gt; 2012-11-06 00:57:07 -0300<br>
irb(main):020:0&gt; c = _ + (4 * 3600)<br>
=&gt; 2012-11-06 04:57:07 -0300<br>
irb(main):021:0&gt; File.lutime(c, c, &quot;a-link&quot;)<br>
=&gt; 1<br>
irb(main):022:0&gt; File.atime(&quot;READ&quot;)<br>
=&gt; 2012-11-06 00:56:43 -0300<br>
irb(main):023:0&gt; File.atime(&quot;a-link&quot;)<br>
=&gt; 2012-11-06 04:57:07 -0300</p>
<p>The only one that has no effect are hardlinks, but because the file itself is the same (which is expected)</p>
<p>irb(main):024:0&gt; File.atime(&quot;READ&quot;)<br>
=&gt; 2012-11-06 00:56:43 -0300<br>
irb(main):025:0&gt; File.atime(&quot;HARD&quot;)<br>
=&gt; 2012-11-06 00:56:43 -0300<br>
irb(main):026:0&gt; d = _ + (9 * 3600)<br>
=&gt; 2012-11-06 09:56:43 -0300<br>
irb(main):027:0&gt; File.lutime(d, d, &quot;HARD&quot;)<br>
=&gt; 1<br>
irb(main):028:0&gt; File.atime(&quot;READ&quot;)<br>
=&gt; 2012-11-06 09:56:43 -0300<br>
irb(main):029:0&gt; File.atime(&quot;HARD&quot;)<br>
=&gt; 2012-11-06 09:56:43 -0300</p>
<p>All this was performed with a normal command prompt (without admin rights)</p>
<p>Now, (({File.lutime})) seems to work properly, but the modification to (({FileUtils})) might not work.</p>
<p>As you see, FileUtils relies on (({File.symlink?})) to combine with (({:nofollow})) option and then use either (({lutime})) or (({utime})).</p>
<p>Problem is, (({File.symlink?})) always return false on Windows:</p>
<p>irb(main):001:0&gt; File.symlink?(&quot;foo&quot;)<br>
=&gt; false<br>
irb(main):002:0&gt; File.symlink?(&quot;bar&quot;)<br>
=&gt; false<br>
irb(main):003:0&gt; File.symlink?(&quot;a-link&quot;)<br>
=&gt; false<br>
irb(main):004:0&gt; File.symlink?(&quot;HARD&quot;)<br>
=&gt; false<br>
irb(main):005:0&gt; File.symlink?(&quot;junc&quot;)</p>
<p>While current Ruby can create hardlinks, it cannot determine a symlink (the code returns directly (({Qfalse})).</p>
<p>I think that is the final part to get your code into Ruby (at least working on Windows).</p>
<p>Thank you.<br>
=end</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=331232012-11-20T04:08:32ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul></ul><p>Hey,</p>
<p>Thanks a million Luis! :-)</p>
<p>It would be amazing to get File#lutime added now so *nix / POSIX compliant environment will benefit from it, and then we can look (under a separate ticket) how to add File#symlink? for Windows platform (lack of it is lingering for quite some time now).</p>
<p>Again, thanks for help to everyone who helped :-)</p>
<p>KW</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=331252012-11-20T05:12:50ZLuis Lavenaluislavena@gmail.com
<ul><li><strong>Assignee</strong> changed from <i>Luis Lavena</i> to <i>Usaku NAKAMURA</i></li></ul><p>Nakamura-san</p>
<p>Are you OK with making File#lutime return a NotImplementedError for now and we can work on next version making File#symlink? and associated work on Windows?</p>
<p>Thank you.</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=331522012-11-20T12:34:26ZUsaku NAKAMURAusa@garbagecollect.jp
<ul><li><strong>Target version</strong> changed from <i>2.0.0</i> to <i>next minor</i></li></ul><p>Yes, OK.<br>
Let&#39;s do it on next minor.</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=331542012-11-20T12:51:57ZUsaku NAKAMURAusa@garbagecollect.jp
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Assigned</i></li></ul> Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=401412013-06-26T06:08:36ZZachary Scotte@zzak.io
<ul></ul><p>usa: ping!</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=403542013-07-08T10:15:11ZLuis Lavenaluislavena@gmail.com
<ul></ul><p>Krzysztof Wilczynski, would you mind provide an updated patch that return NotImplementedError on Windows?</p>
<p>Feel free to send a pull request on GitHub and I&#39;ll get these bits merged.</p>
<p>Thank you.</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=405462013-07-17T11:05:32ZUsaku NAKAMURAusa@garbagecollect.jp
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Open</i></li><li><strong>Assignee</strong> deleted (<del><i>Usaku NAKAMURA</i></del>)</li></ul><p>Ah, I take charge of Windows versions, but I cannot judge whether we should accept this feature request or not.<br>
fileutils doesn&#39;t have the maintainer now, can someone judge it?</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=408102013-08-02T10:24:03ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul></ul><p>When talking about accepting it ... two things to consider as patch has two parts, really:</p>
<p>Part 1 - Adding support for lutimes on <em>nix/POSIX operating systems[</em>];<br>
Part 2 - Changing FileUtils accordingly to accommodate for File getting new methods;</p>
<ul>
<li>which can be benefit them right away.</li>
</ul>
<p>As Luis proven in the past, adding Windows (_WIN32 et al) support might be non-trivial. That having said, I can amend the patch to return NonImplementedError on Windows - not sure how much trouble it is to add support for Windows family (citation needed).</p>
<p>So, even if we consider FileUtils being frozen due to lack of maintainer and Windows implementation for entire Windows family being complex (at this point at least), then perhaps we could separate concerns here and include lutimes patch for *nix/POSIX and return NotImplementedError for Windows for the time being, and then get FileUtils and proper Windows support in check.</p>
<p>What do you guys think?</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=408902013-08-05T08:53:13ZZachary Scotte@zzak.io
<ul></ul><p>Can you just write a gem?</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=410902013-08-11T19:31:40ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul></ul><p>In the grand scheme of things FileUtils could be a gem (especially, since it lacks a maintainer now), yes. This probably would turn to be good for it, actually.</p>
<p>As per your suggestion, I am going to do my best and maintain this as a gem for any BSD/POSIX.1 compliant platform. Maybe even with Windows support later (with Luis&#39; blessing).</p>
<p>Edit:</p>
<p>But I would really like to see these system calls added to Ruby. Some of them are almost 10 years old, and it breaks my heart to see Ruby missing them from the Core.</p>
Ruby trunk - Feature #7106: FileUtils.touch should allow touching the symlink itself rather than the file the link points tohttps://bugs.ruby-lang.org/issues/7106?journal_id=501232014-11-27T03:51:02ZKrzysztof Wilczynskikrzysztof.wilczynski@linux.com
<ul></ul><p>I would like to resurrect this - what do you think Luis and Usa-san? I am more happy to re-base against Ruby 2.1.5 or head, and try to solve other issues.</p>
<p>Just let me know what needs doing, I would really love to help with this :)</p>