Re: [PATCH] apr_stat() on macOS gives only a resolution of seconds for mtime

Jun Omae <[email protected]>
Newsgroups gmane.comp.apache.apr.devel
Message-ID <CAEVLMageBfhjisX+QAJnGSqArvAyQMk_ETohMtpu1WUytUezZQ@mail.gmail.com>
Could anyone please review and test the patch on macOS? I hope it is merged
to 1.7-stable.

Jun Omae <[email protected]> (大前 潤)


On Sun, Jan 7, 2024 at 13:46 Jun Omae <[email protected]> wrote:

> Hi,
>
> I noticed that apr_stat() on macOS gives only a resolution of seconds for
> mtime/ctime/atime while running tests of Subversion on macOS. However,
> according to man page of stat(2) [1], it provides a resolution of
> nanoseconds
> for mtime/ctime/atime.
>
> [[[
> Process 62313 launched: '/tmp/stat' (x86_64)
> Process 62313 stopped
> * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
>     frame #0: 0x0000000100003e65 stat`main(argc=1, argv=<unavailable>) at
> stat.c:14:9 [opt]
>    11           apr_finfo_t finfo;
>    12           stat(filename, &statbuf);
>    13           apr_stat(&finfo, filename, 0, NULL);
> -> 14           printf("%s:\n", filename);
>    15           printf("         %19s  %20s\n", "apr_stat", "stat");
>    16           printf("  mtime: %19lld  %10lld.%09ld\n",
>    17                  (int64_t) finfo.mtime,
> Target 0: (stat) stopped.
> warning: stat was compiled with optimization - stepping may behave oddly;
> variables may not be available.
> (lldb) p finfo.mtime
> (apr_time_t) 1704523440000000
> (lldb) p statbuf.st_mtimespec
> (timespec)  (tv_sec = 1704523440, tv_nsec = 172445899)
> ]]]
>
> I think we could check `struct stat.st_{m,c,a}timespec.tv_nsec` in the
> configure script.
>
> [1]
> https://man.freebsd.org/cgi/man.cgi?query=stat&sektion=2&apropos=0&manpath=macOS+10.13.6#DESCRIPTION
>
>
> Proposed patch:
>
> [[[
> Support microseconds of mtime/atime/ctime in apr_stat() on macOS.
>
> * configure.in
>   (Checking for File Info Support): Add struct stat.st_atimespec.tv_nsec,
>   struct stat.st_mtimespec.tv_nsec, struct stat.st_ctimespec.tv_nsec.
> * file_io/unix/filestat.c
>   (fill_out_finfo): Use st_mtimespec.tv_nsec, st_atimensec.tv_nsec and
>   st_ctimensec.tv_nsec if available.
>
>
> Index: configure.in
> ===================================================================
> --- configure.in        (revision 1915079)
> +++ configure.in        (working copy)
> @@ -2876,7 +2876,9 @@ AC_MSG_NOTICE([Checking for File Info Support...])
>  AC_CHECK_MEMBERS([struct stat.st_blocks, struct stat.st_atimensec,
>  struct stat.st_ctimensec, struct stat.st_mtimensec, struct
> stat.st_atim.tv_nsec,
>  struct stat.st_ctim.tv_nsec, struct stat.st_mtim.tv_nsec,
> -struct stat.st_atime_n, struct stat.st_ctime_n, struct
> stat.st_mtime_n],,,[
> +struct stat.st_atime_n, struct stat.st_ctime_n, struct stat.st_mtime_n,
> +struct stat.st_atimespec.tv_nsec, struct stat.st_mtimespec.tv_nsec,
> +struct stat.st_ctimespec.tv_nsec],,,[
>  #ifdef HAVE_SYS_TYPES_H
>  #include <sys/types.h>
>  #endif
> Index: file_io/unix/filestat.c
> ===================================================================
> --- file_io/unix/filestat.c     (revision 1915079)
> +++ file_io/unix/filestat.c     (working copy)
> @@ -96,6 +96,8 @@ static void fill_out_finfo(apr_finfo_t *finfo, str
>      finfo->atime += info->st_atimensec / APR_TIME_C(1000);
>  #elif defined(HAVE_STRUCT_STAT_ST_ATIME_N)
>      finfo->atime += info->st_atime_n / APR_TIME_C(1000);
> +#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
> +    finfo->atime += info->st_atimespec.tv_nsec / APR_TIME_C(1000);
>  #endif
>
>      apr_time_ansi_put(&finfo->mtime, info->st_mtime);
> @@ -105,6 +107,8 @@ static void fill_out_finfo(apr_finfo_t *finfo, str
>      finfo->mtime += info->st_mtimensec / APR_TIME_C(1000);
>  #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
>      finfo->mtime += info->st_mtime_n / APR_TIME_C(1000);
> +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
> +    finfo->mtime += info->st_mtimespec.tv_nsec / APR_TIME_C(1000);
>  #endif
>
>      apr_time_ansi_put(&finfo->ctime, info->st_ctime);
> @@ -114,6 +118,8 @@ static void fill_out_finfo(apr_finfo_t *finfo, str
>      finfo->ctime += info->st_ctimensec / APR_TIME_C(1000);
>  #elif defined(HAVE_STRUCT_STAT_ST_CTIME_N)
>      finfo->ctime += info->st_ctime_n / APR_TIME_C(1000);
> +#elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC_TV_NSEC)
> +    finfo->ctime += info->st_ctimespec.tv_nsec / APR_TIME_C(1000);
>  #endif
>
>  #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
> ]]]
>
> --
> Jun Omae <[email protected]> (大前 潤)
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.