mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-02 10:31:15 +00:00
Support sub-second file time-stamps on MS-Windows
* nt/inc/sys/stat.h (struct stat): New members for nsec part of file times. * lib-src/ntlib.c (convert_time): * src/w32.c (convert_time): Accept an additional argument TIME_NSEC and set it to the sub-second part of time. All callers changed.
This commit is contained in:
parent
9df2074a06
commit
3975094f1d
3 changed files with 65 additions and 24 deletions
|
@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <direct.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/timeb.h>
|
||||
|
@ -256,7 +257,7 @@ static long double utc_base;
|
|||
static int init = 0;
|
||||
|
||||
static time_t
|
||||
convert_time (FILETIME ft)
|
||||
convert_time (FILETIME ft, int *time_nsec)
|
||||
{
|
||||
long double ret;
|
||||
|
||||
|
@ -266,7 +267,8 @@ convert_time (FILETIME ft)
|
|||
ret = (long double) ft.dwHighDateTime
|
||||
* 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
|
||||
ret -= utc_base;
|
||||
return (time_t) (ret * 1e-7L);
|
||||
*time_nsec = (int) fmodl (ret, 1.0e7L) * 100;
|
||||
return (time_t) (ret * 1.0e-7L);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -373,11 +375,19 @@ stat (const char * path, struct stat * buf)
|
|||
buf->st_size += wfd.nFileSizeLow;
|
||||
|
||||
/* Convert timestamps to Unix format. */
|
||||
buf->st_mtime = convert_time (wfd.ftLastWriteTime);
|
||||
buf->st_atime = convert_time (wfd.ftLastAccessTime);
|
||||
if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
|
||||
buf->st_ctime = convert_time (wfd.ftCreationTime);
|
||||
if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
|
||||
buf->st_mtime = convert_time (wfd.ftLastWriteTime, &buf->st_mtimensec);
|
||||
buf->st_atime = convert_time (wfd.ftLastAccessTime, &buf->st_atimensec);
|
||||
if (buf->st_atime == 0)
|
||||
{
|
||||
buf->st_atime = buf->st_mtime;
|
||||
buf->st_atimensec = buf->st_mtimensec;
|
||||
}
|
||||
buf->st_ctime = convert_time (wfd.ftCreationTime, &buf->st_ctimensec);
|
||||
if (buf->st_ctime == 0)
|
||||
{
|
||||
buf->st_ctime = buf->st_mtime;
|
||||
buf->st_ctimensec = buf->st_mtimensec;
|
||||
}
|
||||
|
||||
/* determine rwx permissions */
|
||||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
|
@ -473,11 +483,19 @@ fstat (int desc, struct stat * buf)
|
|||
buf->st_size += info.nFileSizeLow;
|
||||
|
||||
/* Convert timestamps to Unix format. */
|
||||
buf->st_mtime = convert_time (info.ftLastWriteTime);
|
||||
buf->st_atime = convert_time (info.ftLastAccessTime);
|
||||
if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
|
||||
buf->st_ctime = convert_time (info.ftCreationTime);
|
||||
if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
|
||||
buf->st_mtime = convert_time (info.ftLastWriteTime, &buf->st_mtimensec);
|
||||
buf->st_atime = convert_time (info.ftLastAccessTime, &buf->st_atimensec);
|
||||
if (buf->st_atime == 0)
|
||||
{
|
||||
buf->st_atime = buf->st_mtime;
|
||||
buf->st_atimensec = buf->st_mtimensec;
|
||||
}
|
||||
buf->st_ctime = convert_time (info.ftCreationTime, &buf->st_ctimensec);
|
||||
if (buf->st_ctime == 0)
|
||||
{
|
||||
buf->st_ctime = buf->st_mtime;
|
||||
buf->st_ctimensec = buf->st_mtimensec;
|
||||
}
|
||||
|
||||
/* determine rwx permissions */
|
||||
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
|
|
|
@ -108,6 +108,9 @@ struct stat {
|
|||
time_t st_ctime;
|
||||
char st_uname[260];
|
||||
char st_gname[260];
|
||||
int st_atimensec;
|
||||
int st_mtimensec;
|
||||
int st_ctimensec;
|
||||
};
|
||||
|
||||
/* These are here to avoid compiler warnings when using wchar.h. */
|
||||
|
|
44
src/w32.c
44
src/w32.c
|
@ -5076,9 +5076,10 @@ initialize_utc_base (void)
|
|||
}
|
||||
|
||||
static time_t
|
||||
convert_time (FILETIME ft)
|
||||
convert_time (FILETIME ft, int *time_nsec)
|
||||
{
|
||||
ULONGLONG tmp;
|
||||
time_t time_sec;
|
||||
|
||||
if (!init)
|
||||
{
|
||||
|
@ -5090,7 +5091,10 @@ convert_time (FILETIME ft)
|
|||
return 0;
|
||||
|
||||
FILETIME_TO_U64 (tmp, ft);
|
||||
return (time_t) ((tmp - utc_base) / 10000000L);
|
||||
tmp -= utc_base;
|
||||
time_sec = (time_t) (tmp / 10000000L);
|
||||
*time_nsec = (tmp - (ULONGLONG) time_sec * 10000000L) * 100L;
|
||||
return time_sec;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5707,11 +5711,19 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
|
|||
buf->st_nlink = nlinks;
|
||||
|
||||
/* Convert timestamps to Unix format. */
|
||||
buf->st_mtime = convert_time (wtime);
|
||||
buf->st_atime = convert_time (atime);
|
||||
if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
|
||||
buf->st_ctime = convert_time (ctime);
|
||||
if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
|
||||
buf->st_mtime = convert_time (wtime, &buf->st_mtimensec);
|
||||
buf->st_atime = convert_time (atime, &buf->st_atimensec);
|
||||
if (buf->st_atime == 0)
|
||||
{
|
||||
buf->st_atime = buf->st_mtime;
|
||||
buf->st_atimensec = buf->st_mtimensec;
|
||||
}
|
||||
buf->st_ctime = convert_time (ctime, &buf->st_ctimensec);
|
||||
if (buf->st_ctime == 0)
|
||||
{
|
||||
buf->st_ctime = buf->st_mtime;
|
||||
buf->st_ctimensec = buf->st_mtimensec;
|
||||
}
|
||||
|
||||
/* determine rwx permissions */
|
||||
if (is_a_symlink && !follow_symlinks)
|
||||
|
@ -5853,11 +5865,19 @@ fstat (int desc, struct stat * buf)
|
|||
buf->st_size += info.nFileSizeLow;
|
||||
|
||||
/* Convert timestamps to Unix format. */
|
||||
buf->st_mtime = convert_time (info.ftLastWriteTime);
|
||||
buf->st_atime = convert_time (info.ftLastAccessTime);
|
||||
if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
|
||||
buf->st_ctime = convert_time (info.ftCreationTime);
|
||||
if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
|
||||
buf->st_mtime = convert_time (info.ftLastWriteTime, &buf->st_mtimensec);
|
||||
buf->st_atime = convert_time (info.ftLastAccessTime, &buf->st_atimensec);
|
||||
if (buf->st_atime == 0)
|
||||
{
|
||||
buf->st_atime = buf->st_mtime;
|
||||
buf->st_atimensec = buf->st_mtimensec;
|
||||
}
|
||||
buf->st_ctime = convert_time (info.ftCreationTime, &buf->st_ctimensec);
|
||||
if (buf->st_ctime == 0)
|
||||
{
|
||||
buf->st_ctime = buf->st_mtime;
|
||||
buf->st_ctimensec = buf->st_mtimensec;
|
||||
}
|
||||
|
||||
/* determine rwx permissions */
|
||||
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue