Subject: bug#13149: 24.3.50; Emacs thinks file was changed outside Emacs, but it was not

From: Paul Eggert <[email-masked]>
Date: Fri, 18 Jan 2013 16:55:29 -0800

On 01/18/2013 02:52 PM, Dmitry Gutov wrote:
> Is is possible that the test is measuring something not directly relevant?
> Like I mentioned, emacs-24 build seems to work fine on cifs in all observable respects

I suspect the problem is that cifs mishandles fstat
but works with stat/lstat.  What does the following
program do for you?

#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

static int
report_times (int fd, char const *file)
{
  struct stat fst, lst, st;
  if (0 <= fd && fstat (fd, &fst) != 0)
    return perror ("fstat"), -1;
  if (lstat (file, &lst) != 0)
    return perror ("lstat"), -1;
  if (stat (file, &st) != 0)
    return perror ("stat"), -1;
  if (0 <= fd)
    printf ("%ld.%09ld fstat\n", (long) fst.st_mtim.tv_sec, fst.st_mtim.tv_nsec);
  printf ("%ld.%09ld lstat\n", (long) lst.st_mtim.tv_sec, lst.st_mtim.tv_nsec);
  printf ("%ld.%09ld stat\n", (long) st.st_mtim.tv_sec, st.st_mtim.tv_nsec);
  printf ("\n");
  return 0;
}

int
main (void)
{
  static char const file[] = "foo";
  struct timespec interval;
  int fd;
  unlink (file);
  fd = open (file, O_CREAT | O_WRONLY, -1);
  if (fd < 0)
    return perror ("open O_CREAT"), 1;
  if (report_times (fd, file) != 0)
    return 1;
  interval.tv_sec = 0;
  interval.tv_nsec = 10000000;
  if (nanosleep (&interval, 0) != 0)
    return perror ("nanosleep"), 1;
  if (write (fd, file, sizeof file - 1) != sizeof file - 1)
    return perror ("write"), 1;
  if (report_times (fd, file) != 0)
    return 1;
  if (close (fd) != 0)
    return perror ("close"), 1;
  if (report_times (-1, file) != 0)
    return 1;
  fd = open (file, O_RDONLY, 0);
  if (fd < 0)
    return perror ("open O_RDONLY"), 1;
  if (report_times (fd, file) != 0)
    return 1;
  return 0;
}

It should output something like this:

1358556859.329948949 fstat
1358556859.329948949 lstat
1358556859.329948949 stat

1358556859.341948950 fstat
1358556859.341948950 lstat
1358556859.341948950 stat

1358556859.341948950 lstat
1358556859.341948950 stat

1358556859.341948950 fstat
1358556859.341948950 lstat
1358556859.341948950 stat

That is, the first batch of times should differ from the other
batches, all of which should be the same.