Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/libbb/time.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/libbb/time.c
r1765 r2725 3 3 * Utility routines. 4 4 * 5 * Copyright (C) 2007 Den is Vlasenko5 * Copyright (C) 2007 Denys Vlasenko 6 6 * 7 * Licensed under GPL version 2, see file LICENSE in this tarball for details.7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 10 9 #include "libbb.h" 11 10 11 void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) 12 { 13 char end = '\0'; 14 const char *last_colon = strrchr(date_str, ':'); 15 16 if (last_colon != NULL) { 17 /* Parse input and assign appropriately to ptm */ 18 #if ENABLE_DESKTOP 19 const char *endp; 20 #endif 21 22 /* HH:MM */ 23 if (sscanf(date_str, "%u:%u%c", 24 &ptm->tm_hour, 25 &ptm->tm_min, 26 &end) >= 2) { 27 /* no adjustments needed */ 28 } else 29 /* mm.dd-HH:MM */ 30 if (sscanf(date_str, "%u.%u-%u:%u%c", 31 &ptm->tm_mon, &ptm->tm_mday, 32 &ptm->tm_hour, &ptm->tm_min, 33 &end) >= 4) { 34 /* Adjust month from 1-12 to 0-11 */ 35 ptm->tm_mon -= 1; 36 } else 37 /* yyyy.mm.dd-HH:MM */ 38 if (sscanf(date_str, "%u.%u.%u-%u:%u%c", &ptm->tm_year, 39 &ptm->tm_mon, &ptm->tm_mday, 40 &ptm->tm_hour, &ptm->tm_min, 41 &end) >= 5) { 42 ptm->tm_year -= 1900; /* Adjust years */ 43 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ 44 } else 45 /* yyyy-mm-dd HH:MM */ 46 if (sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year, 47 &ptm->tm_mon, &ptm->tm_mday, 48 &ptm->tm_hour, &ptm->tm_min, 49 &end) >= 5) { 50 ptm->tm_year -= 1900; /* Adjust years */ 51 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ 52 } else 53 #if ENABLE_DESKTOP /* strptime is BIG: ~1k in uclibc, ~10k in glibc */ 54 /* month_name d HH:MM:SS YYYY. Supported by GNU date */ 55 if ((endp = strptime(date_str, "%b %d %T %Y", ptm)) != NULL 56 && *endp == '\0' 57 ) { 58 return; /* don't fall through to end == ":" check */ 59 } else 60 #endif 61 //TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes) 62 { 63 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 64 } 65 if (end == ':') { 66 /* xxx:SS */ 67 if (sscanf(last_colon + 1, "%u%c", &ptm->tm_sec, &end) == 1) 68 end = '\0'; 69 /* else end != NUL and we error out */ 70 } 71 } else if (date_str[0] == '@') { 72 time_t t = bb_strtol(date_str + 1, NULL, 10); 73 if (!errno) { 74 struct tm *lt = localtime(&t); 75 if (lt) { 76 *ptm = *lt; 77 return; 78 } 79 } 80 end = '1'; 81 } else { 82 /* Googled the following on an old date manpage: 83 * 84 * The canonical representation for setting the date/time is: 85 * cc Century (either 19 or 20) 86 * yy Year in abbreviated form (e.g. 89, 06) 87 * mm Numeric month, a number from 1 to 12 88 * dd Day, a number from 1 to 31 89 * HH Hour, a number from 0 to 23 90 * MM Minutes, a number from 0 to 59 91 * .SS Seconds, a number from 0 to 61 (with leap seconds) 92 * Everything but the minutes is optional 93 * 94 * This coincides with the format of "touch -t TIME" 95 */ 96 int len = strchrnul(date_str, '.') - date_str; 97 98 /* MM[.SS] */ 99 if (len == 2 && sscanf(date_str, "%2u%2u%2u%2u""%2u%c" + 12, 100 &ptm->tm_min, 101 &end) >= 1) { 102 } else 103 /* HHMM[.SS] */ 104 if (len == 4 && sscanf(date_str, "%2u%2u%2u""%2u%2u%c" + 9, 105 &ptm->tm_hour, 106 &ptm->tm_min, 107 &end) >= 2) { 108 } else 109 /* ddHHMM[.SS] */ 110 if (len == 6 && sscanf(date_str, "%2u%2u""%2u%2u%2u%c" + 6, 111 &ptm->tm_mday, 112 &ptm->tm_hour, 113 &ptm->tm_min, 114 &end) >= 3) { 115 } else 116 /* mmddHHMM[.SS] */ 117 if (len == 8 && sscanf(date_str, "%2u""%2u%2u%2u%2u%c" + 3, 118 &ptm->tm_mon, 119 &ptm->tm_mday, 120 &ptm->tm_hour, 121 &ptm->tm_min, 122 &end) >= 4) { 123 /* Adjust month from 1-12 to 0-11 */ 124 ptm->tm_mon -= 1; 125 } else 126 /* yymmddHHMM[.SS] */ 127 if (len == 10 && sscanf(date_str, "%2u%2u%2u%2u%2u%c", 128 &ptm->tm_year, 129 &ptm->tm_mon, 130 &ptm->tm_mday, 131 &ptm->tm_hour, 132 &ptm->tm_min, 133 &end) >= 5) { 134 /* Adjust month from 1-12 to 0-11 */ 135 ptm->tm_mon -= 1; 136 } else 137 /* ccyymmddHHMM[.SS] */ 138 if (len == 12 && sscanf(date_str, "%4u%2u%2u%2u%2u%c", 139 &ptm->tm_year, 140 &ptm->tm_mon, 141 &ptm->tm_mday, 142 &ptm->tm_hour, 143 &ptm->tm_min, 144 &end) >= 5) { 145 ptm->tm_year -= 1900; /* Adjust years */ 146 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ 147 } else { 148 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 149 } 150 if (end == '.') { 151 /* xxx.SS */ 152 if (sscanf(strchr(date_str, '.') + 1, "%u%c", 153 &ptm->tm_sec, &end) == 1) 154 end = '\0'; 155 /* else end != NUL and we error out */ 156 } 157 } 158 if (end != '\0') { 159 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 160 } 161 } 162 163 time_t FAST_FUNC validate_tm_time(const char *date_str, struct tm *ptm) 164 { 165 time_t t = mktime(ptm); 166 if (t == (time_t) -1L) { 167 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 168 } 169 return t; 170 } 171 12 172 #if ENABLE_MONOTONIC_SYSCALL 173 13 174 #include <sys/syscall.h> 175 /* Old glibc (< 2.3.4) does not provide this constant. We use syscall 176 * directly so this definition is safe. */ 177 #ifndef CLOCK_MONOTONIC 178 #define CLOCK_MONOTONIC 1 179 #endif 14 180 15 181 /* libc has incredibly messy way of doing this, 16 182 * typically requiring -lrt. We just skip all this mess */ 17 unsigned long long monotonic_us(void) 18 { 19 struct timespec ts; 20 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts)) 183 static void get_mono(struct timespec *ts) 184 { 185 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, ts)) 21 186 bb_error_msg_and_die("clock_gettime(MONOTONIC) failed"); 187 } 188 unsigned long long FAST_FUNC monotonic_ns(void) 189 { 190 struct timespec ts; 191 get_mono(&ts); 192 return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 193 } 194 unsigned long long FAST_FUNC monotonic_us(void) 195 { 196 struct timespec ts; 197 get_mono(&ts); 22 198 return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000; 23 199 } 24 unsigned monotonic_sec(void) 25 { 26 struct timespec ts; 27 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts)) 28 bb_error_msg_and_die("clock_gettime(MONOTONIC) failed"); 200 unsigned long long FAST_FUNC monotonic_ms(void) 201 { 202 struct timespec ts; 203 get_mono(&ts); 204 return ts.tv_sec * 1000ULL + ts.tv_nsec/1000000; 205 } 206 unsigned FAST_FUNC monotonic_sec(void) 207 { 208 struct timespec ts; 209 get_mono(&ts); 29 210 return ts.tv_sec; 30 211 } 212 31 213 #else 32 unsigned long long monotonic_us(void) 214 215 unsigned long long FAST_FUNC monotonic_ns(void) 216 { 217 struct timeval tv; 218 gettimeofday(&tv, NULL); 219 return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; 220 } 221 unsigned long long FAST_FUNC monotonic_us(void) 33 222 { 34 223 struct timeval tv; … … 36 225 return tv.tv_sec * 1000000ULL + tv.tv_usec; 37 226 } 38 39 unsigned monotonic_sec(void) 227 unsigned long long FAST_FUNC monotonic_ms(void) 228 { 229 struct timeval tv; 230 gettimeofday(&tv, NULL); 231 return tv.tv_sec * 1000ULL + tv.tv_usec / 1000; 232 } 233 unsigned FAST_FUNC monotonic_sec(void) 40 234 { 41 235 return time(NULL); 42 236 } 43 #endif 237 238 #endif
Note:
See TracChangeset
for help on using the changeset viewer.