/* * Copyright Jan Engelhardt, 2012 * * This file is part of libHX. libHX is free software; you can * redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation; * either version 2.1 or (at your option) any later version. */ #include #include #include #include #include #include #include "internal.h" #define MICROSECOND 100000 #define NANOSECOND 1000000000 #define NANOSECOND_LL 1000000000LL #ifdef HAVE_STRUCT_TIMESPEC_TV_NSEC EXPORT_SYMBOL bool HX_timespec_isneg(const struct timespec *x) { return (x->tv_sec < 0) || (x->tv_nsec < 0); } EXPORT_SYMBOL struct timespec * HX_timespec_neg(struct timespec *r, const struct timespec *a) { if (a->tv_sec != 0) { r->tv_sec = -a->tv_sec; r->tv_nsec = a->tv_nsec; } else { r->tv_sec = 0; r->tv_nsec = -a->tv_nsec; } return r; } EXPORT_SYMBOL struct timespec *HX_timespec_add(struct timespec *r, const struct timespec *a, const struct timespec *b) { long aa = a->tv_sec * NANOSECOND_LL + ((a->tv_sec >= 0) ? a->tv_nsec : -a->tv_nsec); long bb = b->tv_sec * NANOSECOND_LL + ((b->tv_sec >= 0) ? b->tv_nsec : -b->tv_nsec); long rr = aa + bb; r->tv_sec = rr / NANOSECOND; r->tv_nsec = ((r->tv_sec < 0) ? -rr : rr) % NANOSECOND; return r; } EXPORT_SYMBOL struct timespec *HX_timespec_sub(struct timespec *r, const struct timespec *a, const struct timespec *b) { struct timespec b2; return HX_timespec_add(r, a, HX_timespec_neg(&b2, b)); } EXPORT_SYMBOL struct timespec * HX_timespec_mul(struct timespec *r, const struct timespec *a, int f) { long long t; t = a->tv_sec * NANOSECOND_LL + ((a->tv_sec >= 0) ? a->tv_nsec : -a->tv_nsec); t *= f; r->tv_sec = t / NANOSECOND; r->tv_nsec = t % NANOSECOND; if (r->tv_sec < 0 && r->tv_nsec < 0) r->tv_nsec = -r->tv_nsec; return r; } EXPORT_SYMBOL struct timespec * HX_timespec_mulf(struct timespec *r, const struct timespec *a, double f) { double t; t = (a->tv_sec * NANOSECOND_LL + ((a->tv_sec >= 0) ? a->tv_nsec : -a->tv_nsec)) * f; r->tv_sec = t / NANOSECOND; /* * This is quite the same as r->tv_nsec = fmod(t, NANOSECOND), * except that without the library call, we are faster. */ r->tv_nsec = t - r->tv_sec * NANOSECOND_LL; if (r->tv_sec < 0 && r->tv_nsec < 0) r->tv_nsec = -r->tv_nsec; return r; } #endif #ifdef HAVE_STRUCT_TIMEVAL_TV_USEC EXPORT_SYMBOL struct timeval *HX_timeval_sub(struct timeval *delta, const struct timeval *future, const struct timeval *past) { struct timespec d, f, p; f.tv_sec = future->tv_sec; f.tv_nsec = future->tv_usec * 1000; p.tv_sec = past->tv_sec; p.tv_nsec = past->tv_usec * 1000; HX_timespec_sub(&d, &f, &p); delta->tv_sec = d.tv_sec; delta->tv_usec = d.tv_nsec / 1000; return delta; } #endif EXPORT_SYMBOL long HX_time_compare(const struct stat *a, const struct stat *b, char sel) { long r; #if defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) if (sel == 'm') return ((r = a->st_mtime - b->st_mtime) != 0) ? r : a->st_mtimensec - b->st_mtimensec; #ifdef HAVE_STRUCT_STAT_ST_OTIMENSEC else if (sel == 'o') return ((r = a->st_otime - b->st_otime) != 0) ? r : a->st_otimensec - b->st_otimensec; #endif else if (sel == 'a') return ((r = a->st_atime - b->st_atime) != 0) ? r : a->st_atimensec - b->st_atimensec; else if (sel == 'c') return ((r = a->st_ctime - b->st_ctime) != 0) ? r : a->st_ctimensec - b->st_ctimensec; #elif defined(HAVE_STRUCT_STAT_ST_MTIM) if (sel == 'm') return ((r = a->st_mtim.tv_sec - b->st_mtim.tv_sec) != 0) ? r : a->st_mtim.tv_nsec - b->st_mtim.tv_nsec; #ifdef HAVE_STRUCT_STAT_ST_OTIM else if (sel == 'o') return ((r = a->st_otim.tv_sec - b->st_otim.tv_sec) != 0) ? r : a->st_otim.tv_nsec - b->st_otim.tv_nsec; #endif else if (sel == 'a') return ((r = a->st_atim.tv_sec - b->st_atim.tv_sec) != 0) ? r : a->st_atim.tv_nsec - b->st_atim.tv_nsec; else if (sel == 'c') return ((r = a->st_ctim.tv_sec - b->st_ctim.tv_sec) != 0) ? r : a->st_ctim.tv_nsec - b->st_ctim.tv_nsec; #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) if (sel == 'm') return ((r = a->st_mtimespec.tv_sec - b->st_mtimespec.tv_sec) != 0) ? r : a->st_mtimespec.tv_nsec - b->st_mtimespec.tv_nsec; #ifdef HAVE_STRUCT_STAT_ST_OTIMESPEC else if (sel == 'o') return ((r = a->st_otimespec.tv_sec - b->st_otimespec.tv_sec) != 0) ? r : a->st_otimespec.tv_nsec - b->st_otimespec.tv_nsec; #endif else if (sel == 'a') return ((r = a->st_atimespec.tv_sec - b->st_atimespec.tv_sec) != 0) ? r : a->st_atimespec.tv_nsec - b->st_atimespec.tv_nsec; else if (sel == 'c') return ((r = a->st_ctimespec.tv_sec - b->st_ctimespec.tv_sec) != 0) ? r : a->st_ctimespec.tv_nsec - b->st_ctimespec.tv_nsec; #elif defined(HAVE_STRUCT_STAT_ST_MTIME) if (sel == 'm') return a->st_mtime - b->st_mtime; #ifdef HAVE_STRUCT_STAT_ST_OTIME else if (sel == 'o') return a->st_otime - b->st_otime; #endif else if (sel == 'a') return a->st_atime - b->st_atime; else if (sel == 'c') return a->st_ctime - b->st_ctime; #elif defined(HAVE_STRUCT_STAT_ST_MTIM) if (sel == 'm') return a->st_mtim - b->st_mtim; #ifdef HAVE_STRUCT_STAT_ST_OTIM else if (sel == 'o') return a->st_otim - b->st_otim; #endif else if (sel == 'a') return a->st_atim - b->st_atim; else if (sel == 'c') return a->st_ctim - b->st_ctim; #else # error Tis not ending well. #endif return 0; }