am d27498cb: Merge "toolbox: date: use RTC subsystem on devices without /dev/alarm"
* commit 'd27498cbef862fccb857d7d8970418b893f550ca': toolbox: date: use RTC subsystem on devices without /dev/alarm
This commit is contained in:
commit
f1da46d293
1 changed files with 80 additions and 14 deletions
|
|
@ -6,15 +6,87 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <linux/android_alarm.h>
|
#include <linux/android_alarm.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
#include <sys/ioctl.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) {
|
static void settime(char *s) {
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int day = atoi(s);
|
int day = atoi(s);
|
||||||
int hour;
|
int hour;
|
||||||
time_t t;
|
|
||||||
int fd;
|
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
while (*s && *s != '.')
|
while (*s && *s != '.')
|
||||||
s++;
|
s++;
|
||||||
|
|
@ -32,12 +104,8 @@ static void settime(char *s) {
|
||||||
tm.tm_sec = (hour % 100);
|
tm.tm_sec = (hour % 100);
|
||||||
tm.tm_isdst = -1;
|
tm.tm_isdst = -1;
|
||||||
|
|
||||||
t = mktime(&tm);
|
if (settime_alarm_tm(&tm) < 0)
|
||||||
|
settime_rtc_tm(&tm);
|
||||||
fd = open("/dev/alarm", O_RDWR);
|
|
||||||
ts.tv_sec = t;
|
|
||||||
ts.tv_nsec = 0;
|
|
||||||
ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int date_main(int argc, char *argv[])
|
int date_main(int argc, char *argv[])
|
||||||
|
|
@ -115,11 +183,9 @@ int date_main(int argc, char *argv[])
|
||||||
//tv.tv_usec = 0;
|
//tv.tv_usec = 0;
|
||||||
strtotimeval(argv[optind], &tv);
|
strtotimeval(argv[optind], &tv);
|
||||||
printf("time %s -> %lu.%lu\n", argv[optind], tv.tv_sec, tv.tv_usec);
|
printf("time %s -> %lu.%lu\n", argv[optind], tv.tv_sec, tv.tv_usec);
|
||||||
fd = open("/dev/alarm", O_RDWR);
|
res = settime_alarm_timeval(&tv);
|
||||||
ts.tv_sec = tv.tv_sec;
|
if (res < 0)
|
||||||
ts.tv_nsec = tv.tv_usec * 1000;
|
res = settime_rtc_timeval(&tv);
|
||||||
res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
|
|
||||||
//res = settimeofday(&tv, NULL);
|
|
||||||
if(res < 0) {
|
if(res < 0) {
|
||||||
fprintf(stderr,"settimeofday failed %s\n", strerror(errno));
|
fprintf(stderr,"settimeofday failed %s\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue