summaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorGreg Hackmann <ghackmann@google.com>2013-12-18 00:35:07 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2013-12-18 00:35:07 +0000
commit2f77ecb81366d9c269d608e33ec0a1ee9795dffe (patch)
tree7e8525f745c7f9f0b30915fdaf8deac294c4ba8a /toolbox
parentec5b104ca2ec459348f7b035fad878c65e4ec2f7 (diff)
parent796be8f1432fd02d83f2dae9dbcf11a0976df3b5 (diff)
downloadsystem_core-2f77ecb81366d9c269d608e33ec0a1ee9795dffe.zip
system_core-2f77ecb81366d9c269d608e33ec0a1ee9795dffe.tar.gz
system_core-2f77ecb81366d9c269d608e33ec0a1ee9795dffe.tar.bz2
am 796be8f1: am b1a82bcb: am f1da46d2: am d27498cb: Merge "toolbox: date: use RTC subsystem on devices without /dev/alarm"
* commit '796be8f1432fd02d83f2dae9dbcf11a0976df3b5': toolbox: date: use RTC subsystem on devices without /dev/alarm
Diffstat (limited to 'toolbox')
-rw-r--r--toolbox/date.c94
1 files changed, 80 insertions, 14 deletions
diff --git a/toolbox/date.c b/toolbox/date.c
index fc8e4f8..ed307c0 100644
--- a/toolbox/date.c
+++ b/toolbox/date.c
@@ -6,15 +6,87 @@
#include <errno.h>
#include <time.h>
#include <linux/android_alarm.h>
+#include <linux/rtc.h>
#include <sys/ioctl.h>
+static int settime_alarm(struct timespec *ts) {
+ int fd, ret;
+
+ fd = open("/dev/alarm", O_RDWR);
+ if (fd < 0)
+ return fd;
+
+ ret = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+ close(fd);
+ return ret;
+}
+
+static int settime_alarm_tm(struct tm *tm) {
+ time_t t;
+ struct timespec ts;
+
+ t = mktime(tm);
+ ts.tv_sec = t;
+ ts.tv_nsec = 0;
+ return settime_alarm(&ts);
+}
+
+static int settime_alarm_timeval(struct timeval *tv) {
+ struct timespec ts;
+
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ return settime_alarm(&ts);
+}
+
+static int settime_rtc_tm(struct tm *tm) {
+ int fd, ret;
+ struct timeval tv;
+ struct rtc_time rtc;
+
+ fd = open("/dev/rtc0", O_RDWR);
+ if (fd < 0)
+ return fd;
+
+ tv.tv_sec = mktime(tm);
+ tv.tv_usec = 0;
+
+ ret = settimeofday(&tv, NULL);
+ if (ret < 0)
+ goto done;
+
+ memset(&rtc, 0, sizeof(rtc));
+ rtc.tm_sec = tm->tm_sec;
+ rtc.tm_min = tm->tm_min;
+ rtc.tm_hour = tm->tm_hour;
+ rtc.tm_mday = tm->tm_mday;
+ rtc.tm_mon = tm->tm_mon;
+ rtc.tm_year = tm->tm_year;
+ rtc.tm_wday = tm->tm_wday;
+ rtc.tm_yday = tm->tm_yday;
+ rtc.tm_isdst = tm->tm_isdst;
+
+ ret = ioctl(fd, RTC_SET_TIME, rtc);
+done:
+ close(fd);
+ return ret;
+}
+
+static int settime_rtc_timeval(struct timeval *tv) {
+ struct tm tm, *err;
+ time_t t = tv->tv_sec;
+
+ err = gmtime_r(&t, &tm);
+ if (!err)
+ return -1;
+
+ return settime_rtc_tm(&tm);
+}
+
static void settime(char *s) {
struct tm tm;
int day = atoi(s);
int hour;
- time_t t;
- int fd;
- struct timespec ts;
while (*s && *s != '.')
s++;
@@ -32,12 +104,8 @@ static void settime(char *s) {
tm.tm_sec = (hour % 100);
tm.tm_isdst = -1;
- t = mktime(&tm);
-
- fd = open("/dev/alarm", O_RDWR);
- ts.tv_sec = t;
- ts.tv_nsec = 0;
- ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+ if (settime_alarm_tm(&tm) < 0)
+ settime_rtc_tm(&tm);
}
int date_main(int argc, char *argv[])
@@ -115,11 +183,9 @@ int date_main(int argc, char *argv[])
//tv.tv_usec = 0;
strtotimeval(argv[optind], &tv);
printf("time %s -> %lu.%lu\n", argv[optind], tv.tv_sec, tv.tv_usec);
- fd = open("/dev/alarm", O_RDWR);
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
- //res = settimeofday(&tv, NULL);
+ res = settime_alarm_timeval(&tv);
+ if (res < 0)
+ res = settime_rtc_timeval(&tv);
if(res < 0) {
fprintf(stderr,"settimeofday failed %s\n", strerror(errno));
return 1;