Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

Commit 7e2cf63

Browse files
committed
Merge branch '4542_nanoseconds_2'
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
2 parents dbca937 + 0cfccd5 commit 7e2cf63

File tree

19 files changed

+179
-143
lines changed

19 files changed

+179
-143
lines changed

autogen.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
set -e
44

5-
srcdir="$(cd "$(dirname "$0")" && pwd)"
5+
# Use backticks to support ksh on Solaris
6+
basedir=`dirname "$0"`
7+
srcdir=`cd "$basedir" && pwd`
68

79
cd "$srcdir"
810

configure.ac

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ dnl ############################################################################
3636
dnl Check for compiler
3737
dnl ############################################################################
3838

39+
dnl This should be checked before toolchain macros, otherwise they will remember
40+
dnl that ar cannot be found and linking via libtool will fail at a later stage
41+
AC_CHECK_TOOLS([AR], [ar gar])
42+
3943
AC_PROG_CC
4044
AM_PROG_CC_C_O
4145

@@ -211,8 +215,7 @@ dnl ############################################################################
211215
dnl Check for other tools
212216
dnl ############################################################################
213217

214-
AC_CHECK_TOOL(AR, ar, ar)
215-
AC_CHECK_TOOL(INDENT, gindent, indent)
218+
AC_CHECK_TOOLS([INDENT], [gindent indent])
216219
mc_UNIT_TESTS
217220

218221

@@ -261,7 +264,7 @@ AC_CHECK_TYPE([major_t], [], [AC_DEFINE([major_t], [int], [Type of major device
261264
AC_CHECK_TYPE([minor_t], [], [AC_DEFINE([minor_t], [int], [Type of minor device numbers.])])
262265

263266
AC_STRUCT_ST_BLOCKS
264-
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev, struct stat.st_mtim])
267+
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev, struct stat.st_mtim, struct stat.st_mtimespec, struct stat.st_mtimensec])
265268
gl_STAT_SIZE
266269

267270
AH_TEMPLATE([sig_atomic_t],
@@ -387,14 +390,7 @@ AC_EGREP_CPP([yes],
387390
])
388391

389392
dnl utimensat is supported since glibc 2.6 and specified in POSIX.1-2008
390-
dnl utimensat() causes different timespec structures to cause failures on IBM i and AIX
391-
case $host_os in
392-
*os400 | aix*)
393-
;;
394-
*)
395-
AC_CHECK_FUNCS([utimensat])
396-
;;
397-
esac
393+
AC_CHECK_FUNCS([utimensat])
398394

399395
case $host_os in
400396
*os400)

lib/unixcompat.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,6 @@
113113
#define get_default_editor() "vi"
114114
#define OS_SORT_CASE_SENSITIVE_DEFAULT TRUE
115115

116-
/* struct stat members */
117-
#ifdef __APPLE__
118-
#define st_atim st_atimespec
119-
#define st_ctim st_ctimespec
120-
#define st_mtim st_mtimespec
121-
#endif
122-
123116
/*** enums ***************************************************************************************/
124117

125118
/*** structures declarations (and typedefs of structures)*****************************************/

lib/vfs/direntry.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,10 +1030,7 @@ vfs_s_default_stat (struct vfs_class *me, mode_t mode)
10301030
#endif
10311031
st.st_size = 0;
10321032

1033-
st.st_mtime = st.st_atime = st.st_ctime = time (NULL);
1034-
#ifdef HAVE_STRUCT_STAT_ST_MTIM
1035-
st.st_atim.tv_nsec = st.st_mtim.tv_nsec = st.st_ctim.tv_nsec = 0;
1036-
#endif
1033+
vfs_zero_stat_times (&st);
10371034

10381035
vfs_adjust_stat (&st);
10391036

lib/vfs/parse_ls_vga.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -796,15 +796,14 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam
796796
#endif
797797
}
798798

799+
vfs_zero_stat_times (s);
800+
799801
idx = vfs_parse_filedate (idx, &s->st_mtime);
800802
if (idx == 0)
801803
goto error;
802804

803805
/* Use resulting time value */
804806
s->st_atime = s->st_ctime = s->st_mtime;
805-
#ifdef HAVE_STRUCT_STAT_ST_MTIM
806-
s->st_atim.tv_nsec = s->st_mtim.tv_nsec = s->st_ctim.tv_nsec = 0;
807-
#endif
808807

809808
/* s->st_dev and s->st_ino must be initialized by vfs_s_new_inode () */
810809
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE

lib/vfs/utilvfs.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include <stdlib.h>
3939
#include <string.h>
4040

41+
#if !defined (HAVE_UTIMENSAT) && defined (HAVE_UTIME_H)
42+
#include <utime.h>
43+
#endif
44+
4145
#include "lib/global.h"
4246
#include "lib/unixcompat.h"
4347
#include "lib/widget.h" /* message() */
@@ -372,3 +376,102 @@ vfs_get_password (const char *msg)
372376
}
373377

374378
/* --------------------------------------------------------------------------------------------- */
379+
380+
int
381+
vfs_utime (const char *path, mc_timesbuf_t *times)
382+
{
383+
#ifdef HAVE_UTIMENSAT
384+
return utimensat (AT_FDCWD, path, *times, AT_SYMLINK_NOFOLLOW);
385+
#else
386+
return utime (path, times);
387+
#endif
388+
}
389+
390+
/* --------------------------------------------------------------------------------------------- */
391+
392+
void
393+
vfs_get_timespecs_from_timesbuf (mc_timesbuf_t *times, mc_timespec_t *atime, mc_timespec_t *mtime)
394+
{
395+
#ifdef HAVE_UTIMENSAT
396+
atime->tv_sec = (*times)[0].tv_sec;
397+
atime->tv_nsec = (*times)[0].tv_nsec;
398+
mtime->tv_sec = (*times)[1].tv_sec;
399+
mtime->tv_nsec = (*times)[1].tv_nsec;
400+
#else
401+
atime->tv_sec = times->actime;
402+
atime->tv_nsec = 0;
403+
mtime->tv_sec = times->modtime;
404+
mtime->tv_nsec = 0;
405+
#endif
406+
}
407+
408+
/* --------------------------------------------------------------------------------------------- */
409+
410+
void
411+
vfs_get_timesbuf_from_stat (const struct stat *s, mc_timesbuf_t *times)
412+
{
413+
#ifdef HAVE_UTIMENSAT
414+
#ifdef HAVE_STRUCT_STAT_ST_MTIM
415+
/* POSIX IEEE Std 1003.1-2008 should be the preferred way
416+
*
417+
* AIX has internal type st_timespec_t conflicting with timespec, so assign per field, for details see:
418+
* https://github.com/libuv/libuv/pull/4404
419+
*/
420+
(*times)[0].tv_sec = s->st_atim.tv_sec;
421+
(*times)[0].tv_nsec = s->st_atim.tv_nsec;
422+
(*times)[1].tv_sec = s->st_mtim.tv_sec;
423+
(*times)[1].tv_nsec = s->st_mtim.tv_nsec;
424+
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC
425+
/* Modern BSD solution */
426+
(*times)[0] = s->st_atimespec;
427+
(*times)[1] = s->st_mtimespec;
428+
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
429+
/* Legacy BSD solution */
430+
(*times)[0].tv_sec = s->st_atime;
431+
(*times)[0].tv_nsec = s->st_atimensec;
432+
(*times)[1].tv_sec = s->st_mtime;
433+
(*times)[1].tv_nsec = s->st_mtimensec;
434+
#else
435+
#error "Found utimensat for nanosecond timestamps, but unsupported struct stat format!"
436+
#endif
437+
#else
438+
times->actime = s->st_atime;
439+
times->modtime = s->st_mtime;
440+
#endif
441+
}
442+
443+
/* --------------------------------------------------------------------------------------------- */
444+
445+
void
446+
vfs_copy_stat_times (const struct stat *src, struct stat *dst)
447+
{
448+
dst->st_atime = src->st_atime;
449+
dst->st_mtime = src->st_mtime;
450+
dst->st_ctime = src->st_ctime;
451+
452+
#ifdef HAVE_STRUCT_STAT_ST_MTIM
453+
dst->st_atim.tv_nsec = src->st_atim.tv_nsec;
454+
dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec;
455+
dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec;
456+
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC
457+
dst->st_atimespec.tv_nsec = src->st_atimespec.tv_nsec;
458+
dst->st_mtimespec.tv_nsec = src->st_mtimespec.tv_nsec;
459+
dst->st_ctimespec.tv_nsec = src->st_ctimespec.tv_nsec;
460+
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
461+
dst->st_atimensec = src->st_atimensec;
462+
dst->st_mtimensec = src->st_mtimensec;
463+
dst->st_ctimensec = src->st_ctimensec;
464+
#endif
465+
}
466+
467+
/* --------------------------------------------------------------------------------------------- */
468+
469+
void
470+
vfs_zero_stat_times (struct stat *s)
471+
{
472+
const struct stat empty = { 0 };
473+
474+
vfs_copy_stat_times (&empty, s);
475+
}
476+
477+
/* --------------------------------------------------------------------------------------------- */

lib/vfs/utilvfs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,13 @@ size_t vfs_parse_ls_lga_get_final_spaces (void);
6060
gboolean vfs_parse_month (const char *str, struct tm *tim);
6161
int vfs_parse_filedate (int idx, time_t * t);
6262

63+
int vfs_utime (const char *path, mc_timesbuf_t *times);
64+
void vfs_get_timespecs_from_timesbuf (mc_timesbuf_t *times, mc_timespec_t *atime,
65+
mc_timespec_t *mtime);
66+
void vfs_get_timesbuf_from_stat (const struct stat *s, mc_timesbuf_t *times);
67+
void vfs_copy_stat_times (const struct stat *src, struct stat *dst);
68+
void vfs_zero_stat_times (struct stat *s);
69+
6370
/*** inline functions ****************************************************************************/
71+
6472
#endif

lib/vfs/vfs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ typedef struct timespec mc_timesbuf_t[2];
9595
typedef struct utimbuf mc_timesbuf_t;
9696
#endif
9797

98+
typedef struct mc_timespec
99+
{
100+
time_t tv_sec;
101+
long tv_nsec;
102+
} mc_timespec_t;
103+
98104
/*** enums ***************************************************************************************/
99105

100106
typedef enum

src/filemanager/cmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ compare_files (const vfs_path_t *vpath1, const vfs_path_t *vpath2, off_t size)
210210
#else
211211
/* Don't have mmap() :( Even more ugly :) */
212212
char buf1[BUFSIZ], buf2[BUFSIZ];
213-
int n1, n2;
213+
ssize_t n1, n2;
214214

215215
rotate_dash (TRUE);
216216
do

src/filemanager/file.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "lib/strutil.h"
6868
#include "lib/util.h"
6969
#include "lib/vfs/vfs.h"
70+
#include "lib/vfs/utilvfs.h"
7071
#include "lib/widget.h"
7172

7273
#include "src/setup.h"
@@ -927,20 +928,6 @@ check_same_file (const char *a, const struct stat *ast, const char *b, const str
927928
return TRUE;
928929
}
929930

930-
/* --------------------------------------------------------------------------------------------- */
931-
932-
static void
933-
get_times (const struct stat *sb, mc_timesbuf_t *times)
934-
{
935-
#ifdef HAVE_UTIMENSAT
936-
(*times)[0] = sb->st_atim;
937-
(*times)[1] = sb->st_mtim;
938-
#else
939-
times->actime = sb->st_atime;
940-
times->modtime = sb->st_mtime;
941-
#endif
942-
}
943-
944931
/* --------------------------------------------------------------------------------------------- */
945932
/* {{{ Query/status report routines */
946933

@@ -1297,7 +1284,7 @@ move_file_file (const WPanel *panel, file_op_total_context_t *tctx, file_op_cont
12971284
{
12981285
mc_timesbuf_t times;
12991286

1300-
get_times (&src_stat, &times);
1287+
vfs_get_timesbuf_from_stat (&src_stat, &times);
13011288
mc_utime (dst_vpath, &times);
13021289
}
13031290
goto retry_src_remove;
@@ -2375,7 +2362,7 @@ copy_file_file (file_op_total_context_t *tctx, file_op_context_t *ctx,
23752362
}
23762363
}
23772364

2378-
get_times (&src_stat, &times);
2365+
vfs_get_timesbuf_from_stat (&src_stat, &times);
23792366

23802367
if (!ctx->do_append)
23812368
{
@@ -3232,7 +3219,7 @@ copy_dir_dir (file_op_total_context_t *tctx, file_op_context_t *ctx, const char
32323219
if (attrs_ok)
32333220
mc_fsetflags (dst_vpath, attrs);
32343221

3235-
get_times (&src_stat, &times);
3222+
vfs_get_timesbuf_from_stat (&src_stat, &times);
32363223
mc_utime (dst_vpath, &times);
32373224
}
32383225
else

0 commit comments

Comments
 (0)