rtcwake: fix incorrect (reversed) rtc/sys adjuestment; code shrink

function                                             old     new   delta
rtcwake_main                                         482     462     -20

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2014-05-02 12:46:15 +02:00
parent d8290c2ef0
commit a4476eb654

View File

@ -51,7 +51,6 @@
#define SYS_RTC_PATH "/sys/class/rtc/%s/device/power/wakeup" #define SYS_RTC_PATH "/sys/class/rtc/%s/device/power/wakeup"
#define SYS_POWER_PATH "/sys/power/state" #define SYS_POWER_PATH "/sys/power/state"
#define DEFAULT_MODE "standby"
static NOINLINE bool may_wakeup(const char *rtcname) static NOINLINE bool may_wakeup(const char *rtcname)
{ {
@ -122,17 +121,16 @@ static NOINLINE void setup_alarm(int fd, time_t *wakeup, time_t rtc_time)
int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rtcwake_main(int argc UNUSED_PARAM, char **argv) int rtcwake_main(int argc UNUSED_PARAM, char **argv)
{ {
time_t rtc_time;
unsigned opt; unsigned opt;
const char *rtcname = NULL; const char *rtcname = NULL;
const char *suspend; const char *suspend = "standby";
const char *opt_seconds; const char *opt_seconds;
const char *opt_time; const char *opt_time;
time_t rtc_time;
time_t sys_time; time_t sys_time;
time_t alarm_time = 0; time_t alarm_time = alarm_time;
unsigned seconds = 0; unsigned seconds = seconds; /* for compiler */
int utc = -1; int utc = -1;
int fd; int fd;
@ -148,6 +146,8 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
; ;
applet_long_options = rtcwake_longopts; applet_long_options = rtcwake_longopts;
#endif #endif
/* Must have -s or -t, exclusive */
opt_complementary = "s:t:s--t:t--s";
opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time); opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time);
/* this is the default /* this is the default
@ -156,17 +156,17 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
*/ */
if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL)) if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL))
utc = opt & RTCWAKE_OPT_UTC; utc = opt & RTCWAKE_OPT_UTC;
if (!(opt & RTCWAKE_OPT_SUSPEND_MODE)) if (opt & RTCWAKE_OPT_SECONDS) {
suspend = DEFAULT_MODE;
if (opt & RTCWAKE_OPT_SECONDS)
/* alarm time, seconds-to-sleep (relative) */ /* alarm time, seconds-to-sleep (relative) */
seconds = xatoi(opt_seconds); seconds = xatou(opt_seconds);
if (opt & RTCWAKE_OPT_TIME) } else {
/* RTCWAKE_OPT_TIME */
/* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */ /* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */
alarm_time = xatol(opt_time); if (sizeof(alarm_time) <= sizeof(long))
alarm_time = xatol(opt_time);
if (!alarm_time && !seconds) else
bb_error_msg_and_die("must provide wake time"); alarm_time = xatoll(opt_time);
}
if (utc == -1) if (utc == -1)
utc = rtc_adjtime_is_utc(); utc = rtc_adjtime_is_utc();
@ -177,8 +177,9 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
/* this RTC must exist and (if we'll sleep) be wakeup-enabled */ /* this RTC must exist and (if we'll sleep) be wakeup-enabled */
fd = rtc_xopen(&rtcname, O_RDONLY); fd = rtc_xopen(&rtcname, O_RDONLY);
if (strcmp(suspend, "on") && !may_wakeup(rtcname)) if (strcmp(suspend, "on") != 0)
bb_error_msg_and_die("%s not enabled for wakeup events", rtcname); if (!may_wakeup(rtcname))
bb_error_msg_and_die("%s not enabled for wakeup events", rtcname);
/* relative or absolute alarm time, normalized to time_t */ /* relative or absolute alarm time, normalized to time_t */
sys_time = time(NULL); sys_time = time(NULL);
@ -188,21 +189,29 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
rtc_time = rtc_tm2time(&tm_time, utc); rtc_time = rtc_tm2time(&tm_time, utc);
} }
if (opt & RTCWAKE_OPT_TIME) {
if (alarm_time) { /* Correct for RTC<->system clock difference */
if (alarm_time < sys_time) alarm_time += rtc_time - sys_time;
if (alarm_time < rtc_time)
/*
* Compat message text.
* I'd say "RTC time is already ahead of ..." instead.
*/
bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time)); bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time));
alarm_time += sys_time - rtc_time;
} else } else
alarm_time = rtc_time + seconds + 1; alarm_time = rtc_time + seconds + 1;
setup_alarm(fd, &alarm_time, rtc_time);
setup_alarm(fd, &alarm_time, rtc_time);
sync(); sync();
#if 0 /*debug*/
printf("sys_time: %s", ctime(&sys_time));
printf("rtc_time: %s", ctime(&rtc_time));
#endif
printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time)); printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time));
fflush_all(); fflush_all();
usleep(10 * 1000); usleep(10 * 1000);
if (strcmp(suspend, "on")) if (strcmp(suspend, "on") != 0)
xopen_xwrite_close(SYS_POWER_PATH, suspend); xopen_xwrite_close(SYS_POWER_PATH, suspend);
else { else {
/* "fake" suspend ... we'll do the delay ourselves */ /* "fake" suspend ... we'll do the delay ourselves */