Subject: Re: bug#73709: 29.4; Doc of `file-newer-than-file-p'

From: Eli Zaretskii <[email-masked]>
Date: Tue, 15 Oct 2024 16:46:03 +0300

> From: Michael Heerdegen <[email-masked]>
> Cc: Drew Adams <[email-masked]>,  [email-masked]
> Date: Tue, 15 Oct 2024 03:10:56 +0200
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > > "Return t if content of FILE1 is newer than content of FILE2."
> > >
> > > Short and clear.
> >
> > It's short and clear, but it's inaccurate.  E.g., how to define
> > "content newer" when both files have the same content (like if one of
> > them is a copy of the other)?
> 
> Would it be less problematic to refer to "the time when the file has
> been last saved"?

"Last saved" assumes the file is edited, but this function doesn't
care whether a file has been edited.  "Last written to" might be
better.  But the problem for which I find no good solution is that
there are ways to make the filesystem lie to us about when was file
last written to: use set-file-times in Emacs or the 'touch' shell
command or anything similar.

Observe:

  ~$ ls -l --full-time foo
  -rwxrwxrwx 1 eliz eliz 0 2024-10-15 07:35:02.980000000 -0400 foo
  ~$ ls -l --time=birth --full-time foo
  -rw-rw-rw- 1 eliz eliz 0 2024-10-15 07:35:02.980000000 -0400 foo
  ~$ ls -l --time=ctime --full-time foo
  -rw-rw-rw- 1 eliz eliz 0 2024-10-15 07:35:02.980000000 -0400 foo
  ~$ cp -p foo bar
  ~$ ls -l --time=birth --full-time bar
  -rwxrwxrwx 1 eliz eliz 0 2024-10-15 09:21:17.744000000 -0400 bar*
  ~$ ls -l --full-time bar
  -rwxrwxrwx 1 eliz eliz 0 2024-10-15 07:35:02.980000000 -0400 bar*

So by copying a file while preserving its "mtime" we made the copy
appear as if its last modification time was _before_ the file was
created!  The same could be done using "touch -t foo".  How do we
explain that?

Btw, Emacs doesn't let us access the file's creation time, even on
filesystems which support that.  It documents the "ctime" attribute as
"the time of last change to the file's attributes".  Which is correct,
but only on Unix:

  ~$ chmod a-w foo
  ~$ ls -l --time=ctime --full-time foo
  -r--r--r-- 1 eliz eliz 0 2024-10-15 07:35:42.796000000 -0400 foo*
  ~$ ls -l --time=birth --full-time foo
  -r--r--r-- 1 eliz eliz 0 2024-10-15 07:35:02.980000000 -0400 foo*

The same sequence of commands on MS-Windows doesn't change "ctime":

  >ls -l --time=ctime --full-time foo
  -rw-rw-rw- 1 EliZ None 0 2024-10-15 14:36:11.201456400 +0300 foo
  >chmod a-w foo
  >ls -l --time=ctime --full-time foo
  -r--r--r-- 1 EliZ None 0 2024-10-15 14:36:11.201456400 +0300 foo
  > ls -l --full-time test-stat
  -rw-rw-rw- 1 EliZ None 0 2024-10-15 14:36:11.201456400 +0300 foo

So on Windows, chmod changes neither the last-written time nor the
last-attribute-change time (NTFS, the Windows filesystem, doesn't
track time of attribute changes at all).  And I'm guessing there are
other filesystems (SMB, NFS, etc.) which have similar idiosyncrasies.
On MS-Windows "ctime" is the file's creation time, which is why many
people think that "ctime" is "creation time" on other systems as well.

So these are the conceptual difficulties we bump into when we go down
to this low level.