mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Ticket #3821: initialize struct stat st_[acm]tim.tv_nsec when present
struct stat in libc for Linux kernel contains few fields more since 14+ years [1]. From bits/stat.h: ``` struct timespec st_atim; /* Time of last access. */ struct timespec st_mtim; /* Time of last modification. */ struct timespec st_ctim; /* Time of last status change. */ # define st_atime st_atim.tv_sec /* Backward compatibility. */ # define st_mtime st_mtim.tv_sec # define st_ctime st_ctim.tv_sec ``` The conventional fields became an alias. POSIX.1-2008 made struct stat st_[acm]tim mandatory [2]. OS takes care to initialize struct stat properly [3]. By not using an OS syscall or a libc wrapper to fill struct stat, we have to take care of initializing all fields (or at least those being used later) explicitly. [1]: https://www.sourceware.org/ml/libc-alpha/2002-12/msg00011.html [2]: https://www.sourceware.org/ml/libc-alpha/2009-11/msg00102.html [3]: https://www.sourceware.org/ml/libc-alpha/2002-12/msg00013.html Fixes: file timestamps not preserved (https://mail.gnome.org/archives/mc-devel/2017-April/msg00000.html) Reported-By: Nerijus Baliunas <nerijus@users.sourceforge.net> Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
This commit is contained in:
parent
71c8f5bedc
commit
243cdc1755
@ -181,7 +181,7 @@ AC_TYPE_PID_T
|
||||
AC_TYPE_UID_T
|
||||
|
||||
AC_STRUCT_ST_BLOCKS
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev])
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev, struct stat.st_mtim])
|
||||
gl_STAT_SIZE
|
||||
|
||||
AH_TEMPLATE([sig_atomic_t],
|
||||
|
@ -462,9 +462,15 @@ cpio_create_entry (struct vfs_class *me, struct vfs_s_super *super, struct stat
|
||||
entry->ino->st.st_mode = st->st_mode;
|
||||
entry->ino->st.st_uid = st->st_uid;
|
||||
entry->ino->st.st_gid = st->st_gid;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
entry->ino->st.st_atim = st->st_atim;
|
||||
entry->ino->st.st_mtim = st->st_mtim;
|
||||
entry->ino->st.st_ctim = st->st_ctim;
|
||||
#else
|
||||
entry->ino->st.st_atime = st->st_atime;
|
||||
entry->ino->st.st_mtime = st->st_mtime;
|
||||
entry->ino->st.st_ctime = st->st_ctime;
|
||||
#endif
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
@ -589,6 +595,9 @@ cpio_read_bin_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
st.st_rdev = u.buf.c_rdev;
|
||||
#endif
|
||||
st.st_size = (u.buf.c_filesizes[0] << 16) | u.buf.c_filesizes[1];
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
st.st_atim.tv_nsec = st.st_mtim.tv_nsec = st.st_ctim.tv_nsec = 0;
|
||||
#endif
|
||||
st.st_atime = st.st_mtime = st.st_ctime = (u.buf.c_mtimes[0] << 16) | u.buf.c_mtimes[1];
|
||||
|
||||
return cpio_create_entry (me, super, &st, name);
|
||||
@ -658,6 +667,9 @@ cpio_read_oldc_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
u.st.st_rdev = hd.c_rdev;
|
||||
#endif
|
||||
u.st.st_size = hd.c_filesize;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
u.st.st_atim.tv_nsec = u.st.st_mtim.tv_nsec = u.st.st_ctim.tv_nsec = 0;
|
||||
#endif
|
||||
u.st.st_atime = u.st.st_mtime = u.st.st_ctime = hd.c_mtime;
|
||||
|
||||
return cpio_create_entry (me, super, &u.st, name);
|
||||
@ -736,6 +748,9 @@ cpio_read_crc_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
u.st.st_rdev = makedev (hd.c_rdev, hd.c_rdevmin);
|
||||
#endif
|
||||
u.st.st_size = hd.c_filesize;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
u.st.st_atim.tv_nsec = u.st.st_mtim.tv_nsec = u.st.st_ctim.tv_nsec = 0;
|
||||
#endif
|
||||
u.st.st_atime = u.st.st_mtime = u.st.st_ctime = hd.c_mtime;
|
||||
|
||||
return cpio_create_entry (me, super, &u.st, name);
|
||||
|
@ -442,6 +442,9 @@ tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union record *heade
|
||||
}
|
||||
|
||||
st->st_size = h_size;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec = 0;
|
||||
#endif
|
||||
st->st_mtime = tar_from_oct (1 + 12, header->header.mtime);
|
||||
st->st_atime = 0;
|
||||
st->st_ctime = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user