lib/util/gethostname.c
lib/util/getline.c
lib/util/getopt_long.c
+lib/util/gettime.c
lib/util/gidlist.c
lib/util/glob.c
lib/util/inet_ntop.c
lib/util/term.c
lib/util/ttysize.c
lib/util/util.exp.in
-lib/util/utimes.c
+lib/util/utimens.c
lib/zlib/Makefile.in
lib/zlib/adler32.c
lib/zlib/compress.c
plugins/sudoers/getdate.c
plugins/sudoers/getdate.y
plugins/sudoers/getspwuid.c
-plugins/sudoers/gettime.c
plugins/sudoers/goodpath.c
plugins/sudoers/gram.c
plugins/sudoers/gram.h
/* Define to 1 if you have the `futime' function. */
#undef HAVE_FUTIME
+/* Define to 1 if you have the `futimens' function. */
+#undef HAVE_FUTIMENS
+
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the <util.h> header file. */
#undef HAVE_UTIL_H
+/* Define to 1 if you have the `utimensat' function. */
+#undef HAVE_UTIMENSAT
+
/* Define to 1 if you have the `utimes' function. */
#undef HAVE_UTIMES
fi
done
-for ac_func in utimes
+for ac_func in utimensat
do :
- ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
-if test "x$ac_cv_func_utimes" = xyes; then :
+ ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
+if test "x$ac_cv_func_utimensat" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_UTIMES 1
+#define HAVE_UTIMENSAT 1
_ACEOF
- for ac_func in futimes futimesat
+else
+
+ case " $LIBOBJS " in
+ *" utimens.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS utimens.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_utimensat; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ for ac_func in utimes
do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
+if test "x$ac_cv_func_utimes" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_UTIMES 1
_ACEOF
- break
+
+fi
+done
+
+
fi
done
+for ac_func in futimens
+do :
+ ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens"
+if test "x$ac_cv_func_futimens" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FUTIMENS 1
+_ACEOF
else
case " $LIBOBJS " in
- *" utimes.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS utimes.$ac_objext"
+ *" utimens.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS utimens.$ac_objext"
;;
esac
- for _sym in sudo_utimes; do
+ for _sym in sudo_futimens; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
- for ac_func in futime
+ for ac_func in futimes futimesat futime
do :
- ac_fn_c_check_func "$LINENO" "futime" "ac_cv_func_futime"
-if test "x$ac_cv_func_futime" = xyes; then :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_FUTIME 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
-
- for _sym in sudo_futimes; do
- COMPAT_EXP="${COMPAT_EXP}${_sym}
-"
- done
-
+ break
fi
done
$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
- SUDOERS_LIBS="${SUDOERS_LIBS} -lrt"
+ LIBS="${LIBS} -lrt"
fi
], [
AC_CHECK_FUNCS([sysinfo], [AC_CHECK_HEADERS([sys/systeminfo.h])])
])
-AC_CHECK_FUNCS([utimes], [
- AC_CHECK_FUNCS([futimes futimesat], [break])
-], [
- AC_LIBOBJ(utimes)
- SUDO_APPEND_COMPAT_EXP(sudo_utimes)
- AC_CHECK_FUNCS([futime], [SUDO_APPEND_COMPAT_EXP(sudo_futimes)])
+AC_CHECK_FUNCS([utimensat], [], [
+ AC_LIBOBJ(utimens)
+ SUDO_APPEND_COMPAT_EXP(sudo_utimensat)
+ AC_CHECK_FUNCS([utimes])
+])
+AC_CHECK_FUNCS([futimens], [], [
+ AC_LIBOBJ(utimens)
+ SUDO_APPEND_COMPAT_EXP(sudo_futimens)
+ AC_CHECK_FUNCS([futimes futimesat futime], [break])
])
SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [
AC_LIBOBJ(fnmatch)
# On Solaris, clock_gettime is in librt
AC_CHECK_LIB(rt, clock_gettime, [
AC_DEFINE(HAVE_CLOCK_GETTIME)
- SUDOERS_LIBS="${SUDOERS_LIBS} -lrt"
+ LIBS="${LIBS} -lrt"
])
])
AC_CHECK_FUNCS([getopt_long], [], [
# define S_IRWXU 0000700 /* rwx for owner */
#endif /* S_IRWXU */
+/* For futimens() and utimensat() emulation. */
+#if !defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT)
+# ifndef UTIME_OMIT
+# define UTIME_OMIT -1L
+# endif
+# ifndef UTIME_NOW
+# define UTIME_NOW -2L
+# endif
+# ifndef AT_FDCWD
+# define AT_FDCWD -100
+# endif
+#endif
+
/*
* These should be defined in <unistd.h> but not everyone has them.
*/
# define HAVE_DIRFD
#endif
-/*
- * Define futimes() in terms of futimesat() if needed.
- */
-#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
-# define futimes(_f, _tv) futimesat(_f, NULL, _tv)
-# define HAVE_FUTIMES
-#endif
-
#if !defined(HAVE_KILLPG) && !defined(killpg)
# define killpg(s) kill(-(s))
#endif
# undef getline
# define getline(_a, _b, _c) sudo_getline((_a), (_b), (_c))
#endif /* HAVE_GETLINE */
-#ifndef HAVE_UTIMES
-__dso_public int sudo_utimes(const char *file, const struct timeval *times);
-# undef utimes
-# define utimes(_a, _b) sudo_utimes((_a), (_b))
-#endif /* HAVE_UTIMES */
-#ifdef HAVE_FUTIME
-__dso_public int sudo_futimes(int fd, const struct timeval *times);
-# undef futimes
-# define futimes(_a, _b) sudo_futimes((_a), (_b))
-#endif /* HAVE_FUTIME */
+#ifndef HAVE_UTIMENSAT
+__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
+# undef utimensat
+# define utimensat(_a, _b, _c, _d) sudo_utimensat((_a), (_b), (_c), (_d))
+#endif /* HAVE_UTIMENSAT */
+#ifndef HAVE_FUTIMENS
+__dso_public int sudo_futimens(int fd, const struct timespec *times);
+# undef futimens
+# define futimens(_a, _b) sudo_futimens((_a), (_b))
+#endif /* HAVE_FUTIMENS */
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
__dso_public int sudo_snprintf(char *str, size_t n, char const *fmt, ...) __printflike(3, 4);
# undef snprintf
/*
- * Copyright (c) 2013-2014 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#endif
/*
- * Macros to extract ctime and mtime as timevals.
+ * The timespec version of st_mtime may vary on different platforms.
*/
-#ifdef HAVE_ST_MTIM
-# ifdef HAVE_ST__TIM
-# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctim.st__tim)
-# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtim.st__tim)
+#if defined(HAVE_ST_MTIM)
+# if defined(HAVE_ST__TIM)
+# define SUDO_ST_MTIM st_mtim.st__tim
# else
-# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctim)
-# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtim)
+# define SUDO_ST_MTIM st_mtim
# endif
-#else
-# ifdef HAVE_ST_MTIMESPEC
-# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctimespec)
-# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtimespec)
+#elif defined(HAVE_ST_MTIMESPEC)
+# define SUDO_ST_MTIM st_mtimespec
+#endif
+
+/*
+ * Macro to extract mtime as timespec.
+ * If there is no way to set the timestamp using nanosecond precision,
+ * we only fetch microsecond precision. Otherwise there is a mismatch
+ * between the timestamp we read and the one we wrote.
+ */
+#if defined(SUDO_ST_MTIM)
+# if defined(HAVE_FUTIMENS) && defined(HAVE_UTIMENSAT)
+# define mtim_get(_x, _y) ((_y) = (_x)->SUDO_ST_MTIM)
# else
-# define ctim_get(_x, _y) do { (_y)->tv_sec = (_x)->st_ctime; (_y)->tv_usec = 0; } while (0)
-# define mtim_get(_x, _y) do { (_y)->tv_sec = (_x)->st_mtime; (_y)->tv_usec = 0; } while (0)
-# endif /* HAVE_ST_MTIMESPEC */
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->SUDO_ST_MTIM.tv_sec; (_y).tv_nsec = ((_x)->SUDO_ST_MTIM.tv_nsec / 1000) * 1000; } while (0)
+# endif
+#else
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->st_mtime; (_y).tv_nsec = 0; } while (0)
#endif /* HAVE_ST_MTIM */
/*
__dso_public char *sudo_gethostname_v1(void);
#define sudo_gethostname() sudo_gethostname_v1()
+/* gettime.c */
+__dso_public int sudo_gettime_mono_v1(struct timespec *ts);
+#define sudo_gettime_mono(_a) sudo_gettime_mono_v1((_a))
+__dso_public int sudo_gettime_real_v1(struct timespec *ts);
+#define sudo_gettime_real(_a) sudo_gettime_real_v1((_a))
+
/* gidlist.c */
__dso_public int sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp);
#define sudo_parse_gids(_a, _b, _c) sudo_parse_gids_v1((_a), (_b), (_c))
SHELL = @SHELL@
-LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gethostname.lo gidlist.lo \
- lbuf.lo locking.lo parseln.lo progname.lo secure_path.lo setgroups.lo \
- strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo \
- sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
+LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gethostname.lo gettime.lo \
+ gidlist.lo lbuf.lo locking.lo parseln.lo progname.lo secure_path.lo \
+ setgroups.lo strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo \
+ sudo_debug.lo sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
ATOFOO_TEST_OBJS = atofoo_test.lo locale_stub.lo
$(incdir)/sudo_compat.h $(incdir)/sudo_fatal.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getopt_long.c
+gettime.lo: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \
+ $(incdir)/compat/timespec.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gettime.c
gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ttysize.c
-utimes.lo: $(srcdir)/utimes.c $(incdir)/compat/utime.h $(incdir)/sudo_compat.h \
- $(top_builddir)/config.h
- $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/utimes.c
+utimens.lo: $(srcdir)/utimens.c $(incdir)/compat/timespec.h \
+ $(incdir)/compat/utime.h $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/utimens.c
# include <mach/clock.h>
#endif
-#include "sudoers.h"
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
/* On Linux, CLOCK_MONOTONIC does not run while suspended. */
#if defined(CLOCK_BOOTTIME)
#if defined(HAVE_CLOCK_GETTIME)
int
-sudo_gettime_real(struct timespec *ts)
+sudo_gettime_real_v1(struct timespec *ts)
{
- debug_decl(sudo_gettime_real, SUDOERS_DEBUG_UTIL)
+ debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
if (clock_gettime(CLOCK_REALTIME, ts) == -1) {
struct timeval tv;
}
#else
int
-sudo_gettime_real(struct timespec *ts)
+sudo_gettime_real_v1(struct timespec *ts)
{
struct timeval tv;
- debug_decl(sudo_gettime_real, SUDOERS_DEBUG_UTIL)
+ debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
if (gettimeofday(&tv, NULL) == -1)
debug_return_int(-1);
#if defined(HAVE_CLOCK_GETTIME) && defined(SUDO_CLOCK_MONOTONIC)
int
-sudo_gettime_mono(struct timespec *ts)
+sudo_gettime_mono_v1(struct timespec *ts)
{
static int has_monoclock = -1;
- debug_decl(sudo_gettime_mono, SUDOERS_DEBUG_UTIL)
+ debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
/* Check whether the kernel/libc actually supports CLOCK_MONOTONIC. */
# ifdef _SC_MONOTONIC_CLOCK
}
#elif defined(__MACH__)
int
-sudo_gettime_mono(struct timespec *ts)
+sudo_gettime_mono_v1(struct timespec *ts)
{
uint64_t abstime, nsec;
static mach_timebase_info_data_t timebase_info;
- debug_decl(sudo_gettime_mono, SUDOERS_DEBUG_UTIL)
+ debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
if (timebase_info.denom == 0)
(void) mach_timebase_info(&timebase_info);
}
#else
int
-sudo_gettime_mono(struct timespec *ts)
+sudo_gettime_mono_v1(struct timespec *ts)
{
/* No monotonic clock available, use wall clock. */
return sudo_gettime_real(ts);
sudo_fatalx_nodebug_v1
sudo_get_ttysize_v1
sudo_gethostname_v1
+sudo_gettime_mono_v1
+sudo_gettime_real_v1
sudo_lbuf_append_quoted_v1
sudo_lbuf_append_v1
sudo_lbuf_destroy_v1
--- /dev/null
+/*
+ * Copyright (c) 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_FUTIMENS) || !defined(HAVE_UTIMENSAT)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+#endif
+#ifndef HAVE_STRUCT_TIMESPEC
+# include "compat/timespec.h"
+#endif
+#ifdef HAVE_UTIME_H
+# include <utime.h>
+#else
+# include "compat/utime.h"
+#endif
+
+#include "sudo_compat.h"
+
+#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
+# define futimes(_f, _tv) futimesat(_f, NULL, _tv)
+# define HAVE_FUTIMES
+#endif
+
+#if defined(HAVE_ST_MTIM)
+# ifdef HAVE_ST__TIM
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim.st__tim)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim.st__tim)
+# else
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim)
+# endif
+#elif defined(HAVE_ST_MTIMESPEC)
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atimespec)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtimespec)
+#else
+# define ATIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_atime; (_x)->tv_usec = 0; } while (0)
+# define MTIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_mtime; (_x)->tv_usec = 0; } while (0)
+#endif /* HAVE_ST_MTIM */
+
+/*
+ * Convert the pair of timespec structs passed to futimens() / utimensat()
+ * to a pair of timeval structs, handling UTIME_OMIT and UTIME_NOW.
+ * Returns 0 on success and -1 on failure (setting errno).
+ */
+static int
+utimens_ts_to_tv(int fd, const char *file, const struct timespec *ts,
+ struct timeval *tv)
+{
+ TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
+ if (ts[0].tv_nsec == UTIME_OMIT || ts[1].tv_nsec == UTIME_OMIT) {
+ struct stat sb;
+
+ if (fd != -1) {
+ /* For futimens() */
+ if (fstat(fd, &sb) == -1)
+ return -1;
+ } else {
+ /* For utimensat() */
+ if (stat(file, &sb) == -1)
+ return -1;
+ }
+ if (ts[0].tv_nsec == UTIME_OMIT)
+ ATIME_TO_TIMEVAL(&tv[0], &sb);
+ if (ts[1].tv_nsec == UTIME_OMIT)
+ MTIME_TO_TIMEVAL(&tv[1], &sb);
+ }
+ if (ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) {
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) == -1)
+ return -1;
+ if (ts[0].tv_nsec == UTIME_NOW)
+ tv[0] = now;
+ if (ts[1].tv_nsec == UTIME_NOW)
+ tv[1] = now;
+ }
+ return 0;
+}
+
+#if defined(HAVE_FUTIMES)
+/*
+ * Emulate futimens() via futimes()
+ */
+int
+sudo_futimens(int fd, const struct timespec *ts)
+{
+ struct timeval tv[2], *times = NULL;
+
+ if (ts != NULL) {
+ if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
+ return -1;
+ times = tv;
+ }
+ return futimes(fd, times);
+}
+#elif defined(HAVE_FUTIME)
+/*
+ * Emulate futimens() via futime()
+ */
+int
+sudo_futimens(int fd, const struct timeval *ts)
+{
+ struct utimbuf utb, *times = NULL;
+
+ if (ts != NULL) {
+ struct timeval tv[2];
+
+ if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
+ return -1;
+ utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
+ utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
+ times = &utb;
+ }
+ return futime(fd, times);
+}
+#else
+/*
+ * Nothing to do but fail.
+ */
+int
+sudo_futimens(int fd, const struct timeval *ts)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif /* HAVE_FUTIMES */
+
+#if defined(HAVE_UTIMES)
+/*
+ * Emulate utimensat() via utimes()
+ */
+int
+sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
+{
+ struct timeval tv[2], *times = NULL;
+
+ if (fd != AT_FDCWD || flag != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ts != NULL) {
+ if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
+ return -1;
+ times = tv;
+ }
+ return utimes(file, times);
+}
+#else
+/*
+ * Emulate utimensat() via utime()
+ */
+int
+sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
+{
+ struct utimbuf utb, *times = NULL;
+
+ if (fd != AT_FDCWD || flag != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ts != NULL) {
+ struct timeval tv[2];
+
+ if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
+ return -1;
+ utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
+ utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
+ times = &utb;
+ }
+ return utime(file, times);
+}
+#endif /* !HAVE_UTIMES */
+
+#endif /* !HAVE_FUTIMENS && !HAVE_UTIMENSAT */
+++ /dev/null
-/*
- * Copyright (c) 2004-2005, 2007, 2010-2011, 2013, 2014
- * Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <config.h>
-
-#if !defined(HAVE_UTIMES) || (!defined(HAVE_FUTIMES) && !defined(HAVE_FUTIMESAT))
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#ifdef TIME_WITH_SYS_TIME
-# include <time.h>
-#endif
-
-#ifdef HAVE_UTIME_H
-# include <utime.h>
-#else
-# include "compat/utime.h"
-#endif
-
-#include "sudo_compat.h"
-
-#ifndef HAVE_UTIMES
-/*
- * Emulate utimes() via utime()
- */
-int
-sudo_utimes(const char *file, const struct timeval *times)
-{
- if (times != NULL) {
- struct utimbuf utb;
-
- utb.actime = (time_t)(times[0].tv_sec + times[0].tv_usec / 1000000);
- utb.modtime = (time_t)(times[1].tv_sec + times[1].tv_usec / 1000000);
- return utime(file, &utb);
- } else
- return utime(file, NULL);
-}
-#endif /* !HAVE_UTIMES */
-
-#ifdef HAVE_FUTIME
-/*
- * Emulate futimes() via futime()
- */
-int
-sudo_futimes(int fd, const struct timeval *times)
-{
- if (times != NULL) {
- struct utimbuf utb;
-
- utb.actime = (time_t)(times[0].tv_sec + times[0].tv_usec / 1000000);
- utb.modtime = (time_t)(times[1].tv_sec + times[1].tv_usec / 1000000);
- return futime(fd, &utb);
- } else
- return futime(fd, NULL);
-}
-#endif /* HAVE_FUTIME */
-
-#endif /* !HAVE_UTIMES || (!HAVE_FUTIMES && !HAVE_FUTIMESAT) */
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo solaris_audit.lo sssd.lo:;
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
- $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo strtonum.lo utimes.lo:;
+ $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo strtonum.lo utimens.lo:;
# Parse OBJS lines
my %objs;
toke_util.lo
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
- gettime.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
+ goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
iolog_path.lo locale.lo logging.lo logwrap.lo parse.lo \
policy.lo prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
timestamp.lo @SUDOERS_OBJS@
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getspwuid.c
-gettime.lo: $(srcdir)/gettime.c $(devdir)/def_data.h \
- $(incdir)/compat/stdbool.h $(incdir)/compat/timespec.h \
- $(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
- $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
- $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
- $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
- $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
- $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
- $(top_builddir)/config.h $(top_builddir)/pathnames.h
- $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gettime.c
goodpath.lo: $(srcdir)/goodpath.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/tsgetgrpw.c
visudo.o: $(srcdir)/visudo.c $(devdir)/def_data.h $(devdir)/gram.h \
$(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
- $(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
- $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
- $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
- $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
- $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/redblack.h \
- $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
- $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
- $(top_builddir)/pathnames.h
+ $(incdir)/compat/timespec.h $(incdir)/sudo_alloc.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/redblack.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/sudoers_version.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/visudo.c
visudo_json.o: $(srcdir)/visudo_json.c $(devdir)/def_data.h $(devdir)/gram.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \
#include "sudoers.h"
/*
- * Fill in a struct timeval with the time the system booted.
+ * Fill in a struct timespec with the time the system booted.
* Returns 1 on success and 0 on failure.
*/
#if defined(__linux__)
bool
-get_boottime(struct timeval *tv)
+get_boottime(struct timespec *ts)
{
char *line = NULL;
size_t linesize = 0;
if (strncmp(line, "btime ", 6) == 0) {
long long llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
if (llval > 0) {
- tv->tv_sec = (time_t)llval;
- tv->tv_usec = 0;
+ ts->tv_sec = (time_t)llval;
+ ts->tv_nsec = 0;
found = true;
break;
}
#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
bool
-get_boottime(struct timeval *tv)
+get_boottime(struct timespec *ts)
{
size_t size;
int mib[2];
+ struct timeval tv;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
- size = sizeof(*tv);
- if (sysctl(mib, 2, tv, &size, NULL, 0) != -1)
+ size = sizeof(tv);
+ if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1) {
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
debug_return_bool(true);
+ }
debug_return_bool(false);
}
#elif defined(HAVE_GETUTXID)
bool
-get_boottime(struct timeval *tv)
+get_boottime(struct timespec *ts)
{
struct utmpx *ut, key;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
memset(&key, 0, sizeof(key));
key.ut_type = BOOT_TIME;
setutxent();
- if ((ut = getutxid(&key)) != NULL) {
- tv->tv_sec = ut->ut_tv.tv_sec;
- tv->tv_usec = ut->ut_tv.tv_usec;
- }
+ if ((ut = getutxid(&key)) != NULL)
+ TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts);
endutxent();
debug_return_bool(ut != NULL);
}
#elif defined(HAVE_GETUTID)
bool
-get_boottime(struct timeval *tv)
+get_boottime(struct timespec *ts)
{
struct utmp *ut, key;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
key.ut_type = BOOT_TIME;
setutent();
if ((ut = getutid(&key)) != NULL) {
- tv->tv_sec = ut->ut_time;
- tv->tv_usec = 0;
+ ts->tv_sec = ut->ut_time;
+ ts->tv_nsec = 0;
}
endutent();
debug_return_bool(ut != NULL);
#else
bool
-get_boottime(struct timeval *tv)
+get_boottime(struct timespec *ts)
{
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
debug_return_bool(false);
void remove_timestamp(bool);
bool set_lectured(void);
-/* gettime.c */
-int sudo_gettime_real(struct timespec *ts);
-int sudo_gettime_mono(struct timespec *ts);
-
/* sudo_auth.c */
bool sudo_auth_needs_end_session(void);
int verify_user(struct passwd *pw, char *prompt, int validated);
char *get_timestr(time_t, int);
/* boottime.c */
-bool get_boottime(struct timeval *);
+bool get_boottime(struct timespec *);
/* iolog.c */
bool io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]);
/* Ignore and clear time stamp file if mtime predates boot time. */
if (fstat(fd, &sb) == 0) {
- struct timeval boottime, mtime;
+ struct timespec boottime, mtime;
- mtim_get(&sb, &mtime);
- if (get_boottime(&boottime) && sudo_timevalcmp(&mtime, &boottime, <)) {
+ mtim_get(&sb, mtime);
+ if (get_boottime(&boottime) && sudo_timespeccmp(&mtime, &boottime, <)) {
ignore_result(ftruncate(fd, (off_t)0));
status = TS_MISSING;
goto done;
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
+#ifndef HAVE_STRUCT_TIMESPEC
+# include "compat/timespec.h"
+#endif
#include "sudoers.h"
#include "parse.h"
char *cp; /* scratch char pointer */
char buf[PATH_MAX*2]; /* buffer used for copying files */
char linestr[64]; /* string version of lineno */
- struct timeval tv, times[2]; /* time before and after edit */
- struct timeval orig_mtim; /* starting mtime of sudoers file */
+ struct timespec ts, times[2]; /* time before and after edit */
+ struct timespec orig_mtim; /* starting mtime of sudoers file */
off_t orig_size; /* starting size of sudoers file */
ssize_t nread; /* number of bytes read */
struct stat sb; /* stat buffer */
if (fstat(sp->fd, &sb) == -1)
sudo_fatal(U_("unable to stat %s"), sp->path);
orig_size = sb.st_size;
- mtim_get(&sb, &orig_mtim);
+ mtim_get(&sb, orig_mtim);
/* Create the temp file if needed and set timestamp. */
if (sp->tpath == NULL) {
(void) close(tfd);
}
times[0].tv_sec = times[1].tv_sec = orig_mtim.tv_sec;
- times[0].tv_usec = times[1].tv_usec = orig_mtim.tv_usec;
- (void) utimes(sp->tpath, times);
+ times[0].tv_nsec = times[1].tv_nsec = orig_mtim.tv_nsec;
+ (void) utimensat(AT_FDCWD, sp->tpath, times, 0);
/* Does the editor support +lineno? */
if (lineno > 0)
* XPG4 specifies that vi's exit value is a function of the
* number of errors during editing (?!?!).
*/
- if (gettimeofday(×[0], NULL) == -1) {
+ if (sudo_gettime_real(×[0]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto done;
}
if (run_command(editor, av) != -1) {
- if (gettimeofday(×[1], NULL) == -1) {
+ if (sudo_gettime_real(×[1]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto done;
}
/* Set modified bit if the user changed the file. */
modified = true;
- mtim_get(&sb, &tv);
- if (orig_size == sb.st_size && sudo_timevalcmp(&orig_mtim, &tv, ==)) {
+ mtim_get(&sb, ts);
+ if (orig_size == sb.st_size && sudo_timespeccmp(&orig_mtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
- if (sudo_timevalcmp(×[0], ×[1], !=))
+ if (sudo_timespeccmp(×[0], ×[1], !=))
modified = false;
}
$(top_builddir)/pathnames.h ./sudo_usage.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo.c
sudo_edit.o: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \
- $(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
- $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
- $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
- $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
- $(srcdir)/sudo_exec.h $(top_builddir)/config.h \
- $(top_builddir)/pathnames.h
+ $(incdir)/compat/timespec.h $(incdir)/sudo_alloc.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_edit.c
sudo_noexec.lo: $(srcdir)/sudo_noexec.c $(incdir)/sudo_compat.h \
$(top_builddir)/config.h
int fd_src, fd_dst, i, oflags_dst, post, ret = SESH_ERR_FAILURE;
ssize_t nread, nwritten;
struct stat sb;
- struct timeval times[2];
+ struct timespec times[2];
char buf[BUFSIZ];
debug_decl(sesh_sudoedit, SUDO_DEBUG_EDIT)
if (fd_src == -1 || fstat(fd_src, &sb) != 0)
memset(&sb, 0, sizeof(sb));
/* Make mtime on temp file match src. */
- mtim_get(&sb, ×[0]);
+ mtim_get(&sb, times[0]);
times[1].tv_sec = times[0].tv_sec;
- times[1].tv_usec = times[0].tv_usec;
-#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIME)
- (void) futimes(fd_dst, times);
-#else
- (void) utimes(path_dst, times);
-#endif
+ times[1].tv_nsec = times[0].tv_nsec;
+ if (futimens(fd_dst, times) == -1) {
+ if (utimensat(AT_FDCWD, path_dst, times, 0) == -1)
+ sudo_warn("%s", path_dst);
+ }
}
close(fd_dst);
}
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
+#ifndef HAVE_STRUCT_TIMESPEC
+# include "compat/timespec.h"
+#endif
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
#endif
struct tempfile {
char *tfile;
char *ofile;
- struct timeval omtim;
+ struct timespec omtim;
off_t osize;
};
int i, j, tfd, ofd, rc;
char buf[BUFSIZ];
ssize_t nwritten, nread;
- struct timeval times[2];
+ struct timespec times[2];
struct stat sb;
debug_decl(sudo_edit_create_tfiles, SUDO_DEBUG_EDIT)
}
tf[j].ofile = files[i];
tf[j].osize = sb.st_size;
- mtim_get(&sb, &tf[j].omtim);
+ mtim_get(&sb, tf[j].omtim);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", user_details.uid);
if (seteuid(user_details.uid) != 0)
* We always update the stashed mtime because the time
* resolution of the filesystem the temporary file is on may
* not match that of the filesystem where the file to be edited
- * resides. It is OK if futimes() fails since we only use the
+ * resides. It is OK if futimens() fails since we only use the
* info to determine whether or not a file has been modified.
*/
times[0].tv_sec = times[1].tv_sec = tf[j].omtim.tv_sec;
- times[0].tv_usec = times[1].tv_usec = tf[j].omtim.tv_usec;
-#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIME)
- (void) futimes(tfd, times);
-#else
- (void) utimes(tf[j].tfile, times);
-#endif
+ times[0].tv_nsec = times[1].tv_nsec = tf[j].omtim.tv_nsec;
+ if (futimens(tfd, times) == -1) {
+ if (utimensat(AT_FDCWD, tf[j].tfile, times, 0) == -1)
+ sudo_warn("%s", tf[j].tfile);
+ }
rc = fstat(tfd, &sb);
if (!rc)
- mtim_get(&sb, &tf[j].omtim);
+ mtim_get(&sb, tf[j].omtim);
close(tfd);
j++;
}
*/
static int
sudo_edit_copy_tfiles(struct command_details *command_details,
- struct tempfile *tf, int nfiles, struct timeval *times)
+ struct tempfile *tf, int nfiles, struct timespec *times)
{
int i, tfd, ofd, rc, errors = 0;
char buf[BUFSIZ];
ssize_t nwritten, nread;
- struct timeval tv;
+ struct timespec ts;
struct stat sb;
debug_decl(sudo_edit_copy_tfiles, SUDO_DEBUG_EDIT)
errors++;
continue;
}
- mtim_get(&sb, &tv);
- if (tf[i].osize == sb.st_size && sudo_timevalcmp(&tf[i].omtim, &tv, ==)) {
+ mtim_get(&sb, ts);
+ if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
- if (sudo_timevalcmp(×[0], ×[1], !=)) {
+ if (sudo_timespeccmp(×[0], ×[1], !=)) {
sudo_warnx(U_("%s unchanged"), tf[i].ofile);
unlink(tf[i].tfile);
close(tfd);
if (stat(ofile, &sb) == -1)
memset(&sb, 0, sizeof(sb)); /* new file */
tf[i].osize = sb.st_size;
- mtim_get(&sb, &tf[i].omtim);
+ mtim_get(&sb, tf[i].omtim);
/*
* The temp file must be created by the sesh helper,
* which uses O_EXCL | O_NOFOLLOW to make this safe.
static int
selinux_edit_copy_tfiles(struct command_details *command_details,
- struct tempfile *tf, int nfiles, struct timeval *times)
+ struct tempfile *tf, int nfiles, struct timespec *times)
{
char **sesh_args, **sesh_ap;
int i, rc, sesh_nargs, rval = 1;
struct command_details saved_command_details;
- struct timeval tv;
+ struct timespec ts;
struct stat sb;
debug_decl(selinux_edit_copy_tfiles, SUDO_DEBUG_EDIT)
/* Construct args for sesh -e 1 */
for (i = 0; i < nfiles; i++) {
if (stat(tf[i].tfile, &sb) == 0) {
- mtim_get(&sb, &tv);
- if (tf[i].osize == sb.st_size && sudo_timevalcmp(&tf[i].omtim, &tv, ==)) {
+ mtim_get(&sb, ts);
+ if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
- if (sudo_timevalcmp(×[0], ×[1], !=)) {
+ if (sudo_timespeccmp(×[0], ×[1], !=)) {
sudo_warnx(U_("%s unchanged"), tf[i].ofile);
unlink(tf[i].tfile);
continue;
char **nargv = NULL, **ap, **files = NULL;
int errors, i, ac, nargc, rval;
int editor_argc = 0, nfiles = 0;
- struct timeval times[2];
+ struct timespec times[2];
struct tempfile *tf = NULL;
debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
* Run the editor with the invoking user's creds,
* keeping track of the time spent in the editor.
*/
- if (gettimeofday(×[0], NULL) == -1) {
+ if (sudo_gettime_real(×[0]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto cleanup;
}
command_details->groups = user_details.groups;
command_details->argv = nargv;
rval = run_command(command_details);
- if (gettimeofday(×[1], NULL) == -1) {
+ if (sudo_gettime_real(×[1]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto cleanup;
}