From: Todd C. Miller Date: Wed, 2 Jun 2010 22:54:33 +0000 (-0400) Subject: Use timeval directly instead of converting to timespec when dealing X-Git-Tag: SUDO_1_7_3~134 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a9f9188f9a29b670da98e5b037fee273807c76ea;p=sudo Use timeval directly instead of converting to timespec when dealing with file times and time of day. --HG-- branch : 1.7 --- diff --git a/check.c b/check.c index f989bfd48..568b9aac3 100644 --- a/check.c +++ b/check.c @@ -23,6 +23,7 @@ #include #include +#include #include #ifndef __TANDEM # include @@ -46,15 +47,14 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#if TIME_WITH_SYS_TIME +# include +#endif #include #include #include -#include #include #include -#ifndef HAVE_TIMESPEC -# include -#endif #include "sudo.h" @@ -534,7 +534,7 @@ timestamp_status(timestampdir, timestampfile, user, flags) if (def_timestamp_timeout < 0 && sb.st_mtime != 0) status = TS_CURRENT; else { - /* XXX - should use timespec here */ + /* XXX - should use timeval here */ now = time(NULL); boottime = get_boottime(); if (def_timestamp_timeout && @@ -574,7 +574,7 @@ void remove_timestamp(remove) int remove; { - struct timespec ts; + struct timeval tv; char *timestampdir, *timestampfile, *path; int status; @@ -594,8 +594,8 @@ remove_timestamp(remove) remove = FALSE; } } else { - timespecclear(&ts); - if (touch(-1, path, &ts) == -1) + timerclear(&tv); + if (touch(-1, path, &tv) == -1) error(1, "can't reset %s to Epoch", path); } } diff --git a/compat.h b/compat.h index 808ada367..b5da2639c 100644 --- a/compat.h +++ b/compat.h @@ -260,24 +260,12 @@ const char *getprogname __P((void)); #endif /* HAVE___PROGNAME */ #endif /* !HAVE_GETPROGNAME */ -#ifndef timespecclear -# define timespecclear(ts) (ts)->tv_sec = (ts)->tv_nsec = 0 +#ifndef timerclear +# define timerclear(ts) (ts)->tv_sec = (ts)->tv_nsec = 0 #endif -#ifndef timespecisset -# define timespecisset(ts) ((ts)->tv_sec || (ts)->tv_nsec) +#ifndef timerisset +# define timerisset(ts) ((ts)->tv_sec || (ts)->tv_nsec) #endif -#ifndef timespecsub -# define timespecsub(minuend, subrahend, difference) \ - do { \ - (difference)->tv_sec = (minuend)->tv_sec - (subrahend)->tv_sec; \ - (difference)->tv_nsec = (minuend)->tv_nsec - (subrahend)->tv_nsec; \ - if ((difference)->tv_nsec < 0) { \ - (difference)->tv_nsec += 1000000000L; \ - (difference)->tv_sec--; \ - } \ - } while (0) -#endif - #ifndef timeradd # define timeradd(tv1, tv2, total) \ do { \ @@ -289,7 +277,6 @@ const char *getprogname __P((void)); } \ } while (0) #endif - #ifndef timersub # define timersub(minuend, subrahend, difference) \ do { \ diff --git a/config.h.in b/config.h.in index a00b62371..625f0878f 100644 --- a/config.h.in +++ b/config.h.in @@ -530,7 +530,7 @@ /* Define to 1 if you have a timespecsub macro or function that takes two arguments (not three) */ -#undef HAVE_TIMESPECSUB2 +#undef HAVE_TIMERSUB2 /* Define to 1 if you have the `tzset' function. */ #undef HAVE_TZSET @@ -770,25 +770,28 @@ #undef volatile /* - * Macros to pull sec and nsec parts of mtime from struct stat. - * We need to be able to convert between timeval and timespec - * so the last 3 digits of tv_nsec are not significant. + * Macros to convert ctime and mtime into timevals. */ +#define timespec2timeval(_ts, _tv) do { \ + (_tv)->tv_sec = (_ts)->tv_sec; \ + (_tv)->tv_usec = (_ts)->tv_nsec / 1000; \ +} while (0) + #ifdef HAVE_ST_MTIM # ifdef HAVE_ST__TIM -# define mtim_getsec(_x) ((_x).st_mtim.st__tim.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtim.st__tim.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctim.st__tim, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtim.st__tim, (_y)) # else -# define mtim_getsec(_x) ((_x).st_mtim.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtim.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctim, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtim, (_y)) # endif #else # ifdef HAVE_ST_MTIMESPEC -# define mtim_getsec(_x) ((_x).st_mtimespec.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtimespec.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctimespec, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtimespec, (_y)) # else -# define mtim_getsec(_x) ((_x).st_mtime) -# define mtim_getnsec(_x) (0) +# 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 */ #endif /* HAVE_ST_MTIM */ diff --git a/configure b/configure index 5c72cfdd9..b70d778a4 100755 --- a/configure +++ b/configure @@ -20244,8 +20244,8 @@ fi fi - { echo "$as_me:$LINENO: checking for two-parameter timespecsub" >&5 -echo $ECHO_N "checking for two-parameter timespecsub... $ECHO_C" >&6; } + { echo "$as_me:$LINENO: checking for two-parameter timersub" >&5 +echo $ECHO_N "checking for two-parameter timersub... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -20257,12 +20257,12 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -struct timespec ts1, ts2; -ts1.tv_sec = 1; ts1.tv_nsec = 0; ts2.tv_sec = 0; ts2.tv_nsec = 0; -#ifndef timespecsub -#error missing timespecsub +struct timeval ts1, ts2; +ts1.tv_sec = 1; ts1.tv_usec = 0; ts2.tv_sec = 0; ts2.tv_usec = 0; +#ifndef timersub +#error missing timersub #endif -timespecsub(&ts1, &ts2); +timersub(&ts1, &ts2); ; return 0; } @@ -20285,7 +20285,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF -#define HAVE_TIMESPECSUB2 1 +#define HAVE_TIMERSUB2 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 diff --git a/configure.in b/configure.in index 99366165f..b41af6b19 100644 --- a/configure.in +++ b/configure.in @@ -1922,14 +1922,14 @@ if test X"$ac_cv_type_struct_timespec" != X"no"; then AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)] [AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))], [AC_CHECK_MEMBER([struct stat.st_mtimespec], AC_DEFINE([HAVE_ST_MTIMESPEC]))]) - AC_MSG_CHECKING([for two-parameter timespecsub]) + AC_MSG_CHECKING([for two-parameter timersub]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -#include ]], [[struct timespec ts1, ts2; -ts1.tv_sec = 1; ts1.tv_nsec = 0; ts2.tv_sec = 0; ts2.tv_nsec = 0; -#ifndef timespecsub -#error missing timespecsub +#include ]], [[struct timeval ts1, ts2; +ts1.tv_sec = 1; ts1.tv_usec = 0; ts2.tv_sec = 0; ts2.tv_usec = 0; +#ifndef timersub +#error missing timersub #endif -timespecsub(&ts1, &ts2);]])], [AC_DEFINE(HAVE_TIMESPECSUB2) +timersub(&ts1, &ts2);]])], [AC_DEFINE(HAVE_TIMERSUB2) AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) fi dnl @@ -2786,7 +2786,7 @@ AH_TEMPLATE(HAVE_ST_MTIM, [Define to 1 if your struct stat has an st_mtim member AH_TEMPLATE(HAVE_ST_MTIMESPEC, [Define to 1 if your struct stat has an st_mtimespec member]) AH_TEMPLATE(HAVE_TERMIOS_H, [Define to 1 if you have the header file and the `tcgetattr' function.]) AH_TEMPLATE(HAVE_TIMESPEC, [Define to 1 if you have struct timespec in sys/time.h]) -AH_TEMPLATE(HAVE_TIMESPECSUB2, [Define to 1 if you have a timespecsub macro or function that takes two arguments (not three)]) +AH_TEMPLATE(HAVE_TIMERSUB2, [Define to 1 if you have a timersub macro or function that takes two arguments (not three)]) AH_TEMPLATE(HAVE___PROGNAME, [Define to 1 if your crt0.o defines the __progname symbol for you.]) AH_TEMPLATE(HOST_IN_LOG, [Define to 1 if you want the hostname to be entered into the log file.]) AH_TEMPLATE(IGNORE_DOT_PATH, [Define to 1 if you want to ignore '.' and empty PATH elements]) @@ -2820,25 +2820,28 @@ AH_TOP([#ifndef _SUDO_CONFIG_H #define _SUDO_CONFIG_H]) AH_BOTTOM([/* - * Macros to pull sec and nsec parts of mtime from struct stat. - * We need to be able to convert between timeval and timespec - * so the last 3 digits of tv_nsec are not significant. + * Macros to convert ctime and mtime into timevals. */ +#define timespec2timeval(_ts, _tv) do { \ + (_tv)->tv_sec = (_ts)->tv_sec; \ + (_tv)->tv_usec = (_ts)->tv_nsec / 1000; \ +} while (0) + #ifdef HAVE_ST_MTIM # ifdef HAVE_ST__TIM -# define mtim_getsec(_x) ((_x).st_mtim.st__tim.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtim.st__tim.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctim.st__tim, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtim.st__tim, (_y)) # else -# define mtim_getsec(_x) ((_x).st_mtim.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtim.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctim, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtim, (_y)) # endif #else # ifdef HAVE_ST_MTIMESPEC -# define mtim_getsec(_x) ((_x).st_mtimespec.tv_sec) -# define mtim_getnsec(_x) (((_x).st_mtimespec.tv_nsec / 1000) * 1000) +# define ctim_get(_x, _y) timespec2timeval(&(_x)->st_ctimespec, (_y)) +# define mtim_get(_x, _y) timespec2timeval(&(_x)->st_mtimespec, (_y)) # else -# define mtim_getsec(_x) ((_x).st_mtime) -# define mtim_getnsec(_x) (0) +# 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 */ #endif /* HAVE_ST_MTIM */ diff --git a/fileops.c b/fileops.c index 5e9d31dd6..c2dc152fb 100644 --- a/fileops.c +++ b/fileops.c @@ -57,25 +57,25 @@ * Update the access and modify times on an fd or file. */ int -touch(fd, path, tsp) +touch(fd, path, tvp) int fd; char *path; - struct timespec *tsp; + struct timeval *tvp; { struct timeval times[2]; - if (tsp != NULL) { - times[0].tv_sec = times[1].tv_sec = tsp->tv_sec; - times[0].tv_usec = times[1].tv_usec = tsp->tv_nsec / 1000; + if (tvp != NULL) { + times[0].tv_sec = times[1].tv_sec = tvp->tv_sec; + times[0].tv_usec = times[1].tv_usec = tvp->tv_usec; } #if defined(HAVE_FUTIME) || defined(HAVE_FUTIMES) if (fd != -1) - return(futimes(fd, tsp ? times : NULL)); + return(futimes(fd, tvp ? times : NULL)); else #endif if (path != NULL) - return(utimes(path, tsp ? times : NULL)); + return(utimes(path, tvp ? times : NULL)); else return(-1); } diff --git a/gettime.c b/gettime.c index f6de47532..1f498dbc4 100644 --- a/gettime.c +++ b/gettime.c @@ -22,9 +22,6 @@ #if TIME_WITH_SYS_TIME # include #endif -#ifndef HAVE_TIMESPEC -# include -#endif #include @@ -33,19 +30,15 @@ * timespecs in struct stat or, otherwise, using time(). */ int -gettime(ts) - struct timespec *ts; +gettime(tv) + struct timeval *tv; { int rval; #if defined(HAVE_GETTIMEOFDAY) && (defined(HAVE_ST_MTIM) || defined(HAVE_ST_MTIMESPEC)) - struct timeval tv; - - rval = gettimeofday(&tv, NULL); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; + rval = gettimeofday(tv, NULL); #else - rval = (int)time(&ts->tv_sec); - ts->tv_nsec = 0; + rval = (int)time(&tv->tv_sec); + tv->tv_usec = 0; #endif return (rval); } diff --git a/sudo.h b/sudo.h index a181c3cd5..4db6d1adf 100644 --- a/sudo.h +++ b/sudo.h @@ -241,13 +241,13 @@ void dump_auth_methods __P((void)); void init_envtables __P((void)); void read_env_file __P((const char *, int)); int lock_file __P((int, int)); -int touch __P((int, char *, struct timespec *)); +int touch __P((int, char *, struct timeval *)); int user_is_exempt __P((void)); void set_fqdn __P((void)); char *sudo_getepw __P((const struct passwd *)); int pam_prep_user __P((struct passwd *)); void zero_bytes __P((volatile void *, size_t)); -int gettime __P((struct timespec *)); +int gettime __P((struct timeval *)); FILE *open_sudoers __P((const char *, int, int *)); void display_privs __P((struct sudo_nss_list *, struct passwd *)); int display_cmnd __P((struct sudo_nss_list *, struct passwd *)); diff --git a/sudo_edit.c b/sudo_edit.c index 04d5d7434..44989d452 100644 --- a/sudo_edit.c +++ b/sudo_edit.c @@ -49,9 +49,6 @@ #if TIME_WITH_SYS_TIME # include #endif -#ifndef HAVE_TIMESPEC -# include -#endif #include "sudo.h" @@ -74,13 +71,13 @@ sudo_edit(argc, argv, envp) const char *tmpdir; char **nargv, **ap, *editor, *cp; char buf[BUFSIZ]; - int error, i, ac, ofd, tfd, nargc, rval, tmplen, wasblank; + int rc, i, ac, ofd, tfd, nargc, rval, tmplen, wasblank; struct stat sb; - struct timespec ts1, ts2; + struct timeval tv, tv1, tv2; struct tempfile { char *tfile; char *ofile; - struct timespec omtim; + struct timeval omtim; off_t osize; } *tf; @@ -113,23 +110,23 @@ sudo_edit(argc, argv, envp) tf = emalloc2(argc - 1, sizeof(*tf)); zero_bytes(tf, (argc - 1) * sizeof(*tf)); for (i = 0, ap = argv + 1; i < argc - 1 && *ap != NULL; i++, ap++) { - error = -1; + rc = -1; set_perms(PERM_RUNAS); if ((ofd = open(*ap, O_RDONLY, 0644)) != -1 || errno == ENOENT) { if (ofd == -1) { zero_bytes(&sb, sizeof(sb)); /* new file */ - error = 0; + rc = 0; } else { #ifdef HAVE_FSTAT - error = fstat(ofd, &sb); + rc = fstat(ofd, &sb); #else - error = stat(tf[i].ofile, &sb); + rc = stat(tf[i].ofile, &sb); #endif } } set_perms(PERM_ROOT); - if (error || (ofd != -1 && !S_ISREG(sb.st_mode))) { - if (error) + if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) { + if (rc) warning("%s", *ap); else warningx("%s: not a regular file", *ap); @@ -140,8 +137,7 @@ sudo_edit(argc, argv, envp) continue; } tf[i].ofile = *ap; - tf[i].omtim.tv_sec = mtim_getsec(sb); - tf[i].omtim.tv_nsec = mtim_getnsec(sb); + mtim_get(&sb, &tf[i].omtim); tf[i].osize = sb.st_size; if ((cp = strrchr(tf[i].ofile, '/')) != NULL) cp++; @@ -176,14 +172,12 @@ sudo_edit(argc, argv, envp) */ (void) touch(tfd, NULL, &tf[i].omtim); #ifdef HAVE_FSTAT - error = fstat(tfd, &sb); + rc = fstat(tfd, &sb); #else - error = stat(tf[i].tfile, &sb); + rc = stat(tf[i].tfile, &sb); #endif - if (!error) { - tf[i].omtim.tv_sec = mtim_getsec(sb); - tf[i].omtim.tv_nsec = mtim_getnsec(sb); - } + if (!rc) + mtim_get(&sb, &tf[i].omtim); close(tfd); } if (argc == 1) @@ -221,7 +215,7 @@ sudo_edit(argc, argv, envp) * Fork and exec the editor with the invoking user's creds, * keeping track of the time spent in the editor. */ - gettime(&ts1); + gettime(&tv1); kidpid = fork(); if (kidpid == -1) { warning("fork"); @@ -257,7 +251,7 @@ sudo_edit(argc, argv, envp) break; } } while (pid != -1 || errno == EINTR); - gettime(&ts2); + gettime(&tv2); if (pid == -1 || !WIFEXITED(i)) rval = 1; else @@ -265,18 +259,18 @@ sudo_edit(argc, argv, envp) /* Copy contents of temp files to real ones */ for (i = 0; i < argc - 1; i++) { - error = -1; + rc = -1; set_perms(PERM_USER); if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) { #ifdef HAVE_FSTAT - error = fstat(tfd, &sb); + rc = fstat(tfd, &sb); #else - error = stat(tf[i].tfile, &sb); + rc = stat(tf[i].tfile, &sb); #endif } set_perms(PERM_ROOT); - if (error || !S_ISREG(sb.st_mode)) { - if (error) + if (rc || !S_ISREG(sb.st_mode)) { + if (rc) warning("%s", tf[i].tfile); else warningx("%s: not a regular file", tf[i].tfile); @@ -285,18 +279,18 @@ sudo_edit(argc, argv, envp) close(tfd); continue; } - if (tf[i].osize == sb.st_size && tf[i].omtim.tv_sec == mtim_getsec(sb) - && tf[i].omtim.tv_nsec == mtim_getnsec(sb)) { + mtim_get(&sb, &tv); + if (tf[i].osize == sb.st_size && timercmp(&tf[i].omtim, &tv, ==)) { /* * If mtime and size match but the user spent no measurable * time in the editor we can't tell if the file was changed. */ -#ifdef HAVE_TIMESPECSUB2 - timespecsub(&ts1, &ts2); +#ifdef HAVE_TIMERSUB2 + timersub(&tv1, &tv2); #else - timespecsub(&ts1, &ts2, &ts2); + timersub(&tv1, &tv2, &tv2); #endif - if (timespecisset(&ts2)) { + if (timerisset(&tv2)) { warningx("%s unchanged", tf[i].ofile); unlink(tf[i].tfile); close(tfd); diff --git a/visudo.c b/visudo.c index c6a0838bf..c93b817b8 100644 --- a/visudo.c +++ b/visudo.c @@ -76,9 +76,6 @@ #else # include #endif -#ifndef HAVE_TIMESPEC -# include -#endif #include "sudo.h" #include "interfaces.h" @@ -267,8 +264,8 @@ edit_sudoers(sp, editor, args, lineno) char *cp; /* scratch char pointer */ char buf[PATH_MAX*2]; /* buffer used for copying files */ char linestr[64]; /* string version of lineno */ - struct timespec ts1, ts2; /* time before and after edit */ - struct timespec orig_mtim; /* starting mtime of sudoers file */ + struct timeval tv, tv1, tv2; /* time before and after edit */ + struct timeval 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 */ @@ -280,8 +277,7 @@ edit_sudoers(sp, editor, args, lineno) #endif error(1, "can't stat %s", sp->path); orig_size = sb.st_size; - orig_mtim.tv_sec = mtim_getsec(sb); - orig_mtim.tv_nsec = mtim_getnsec(sb); + mtim_get(&sb, &orig_mtim); /* Create the temp file if needed and set timestamp. */ if (sp->tpath == NULL) { @@ -347,9 +343,9 @@ edit_sudoers(sp, editor, args, lineno) * XPG4 specifies that vi's exit value is a function of the * number of errors during editing (?!?!). */ - gettime(&ts1); + gettime(&tv1); if (run_command(editor, av) != -1) { - gettime(&ts2); + gettime(&tv2); /* * Sanity checks. */ @@ -371,19 +367,20 @@ edit_sudoers(sp, editor, args, lineno) /* Set modified bit if use changed the file. */ modified = TRUE; + mtim_get(&sb, &tv); if (orig_size == sb.st_size && - orig_mtim.tv_sec == mtim_getsec(sb) && - orig_mtim.tv_nsec == mtim_getnsec(sb)) { + orig_mtim.tv_sec == tv.tv_sec && + orig_mtim.tv_usec == tv.tv_usec) { /* * If mtime and size match but the user spent no measurable * time in the editor we can't tell if the file was changed. */ -#ifdef HAVE_TIMESPECSUB2 - timespecsub(&ts1, &ts2); +#ifdef HAVE_TIMERSUB2 + timersub(&tv1, &tv2); #else - timespecsub(&ts1, &ts2, &ts2); + timersub(&tv1, &tv2, &tv2); #endif - if (timespecisset(&ts2)) + if (timerisset(&tv2)) modified = FALSE; }