summaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorGreg Hackmann <ghackmann@google.com>2013-12-17 14:00:03 -0800
committerGreg Hackmann <ghackmann@google.com>2013-12-17 14:45:39 -0800
commit4a7bc60071901dce2af85ec56a088604b6c228ce (patch)
treebbc9afa27dc2c8e47dffc8f7b6425f4b821bf7fb /toolbox
parentc057503aaf53c25e67d5bf36c33cd15ec9188c5d (diff)
downloadsystem_core-4a7bc60071901dce2af85ec56a088604b6c228ce.tar.gz
system_core-4a7bc60071901dce2af85ec56a088604b6c228ce.tar.bz2
system_core-4a7bc60071901dce2af85ec56a088604b6c228ce.zip
toolbox: date: use RTC subsystem on devices without /dev/alarm
Change-Id: I48c0fd1f4cffef936afb8d48d6d93babf006004d Signed-off-by: Greg Hackmann <ghackmann@google.com>
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 fc8e4f8d6..ed307c08b 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;