summaryrefslogtreecommitdiffstats
path: root/sys-utils/rtcwake.c
diff options
context:
space:
mode:
authorSami Kerola2015-01-10 16:39:00 +0100
committerKarel Zak2015-06-29 13:39:37 +0200
commit71d95e92c109512ec16a38702829bb7dd6bf5f18 (patch)
tree8e554d2e2d175df6461e7273ca49ba2976653d4f /sys-utils/rtcwake.c
parentreset: deprecate the script, and remove reset.033c (diff)
downloadkernel-qcow2-util-linux-71d95e92c109512ec16a38702829bb7dd6bf5f18.tar.gz
kernel-qcow2-util-linux-71d95e92c109512ec16a38702829bb7dd6bf5f18.tar.xz
kernel-qcow2-util-linux-71d95e92c109512ec16a38702829bb7dd6bf5f18.zip
rtcwake: add rtcwake_control and remove global variables
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'sys-utils/rtcwake.c')
-rw-r--r--sys-utils/rtcwake.c131
1 files changed, 69 insertions, 62 deletions
diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c
index bf99a5b8f..8b5f69cc7 100644
--- a/sys-utils/rtcwake.c
+++ b/sys-utils/rtcwake.c
@@ -54,16 +54,21 @@
#define DEFAULT_DEVICE "/dev/rtc0"
#define DEFAULT_MODE "standby"
-enum ClockMode {
+enum clock_modes {
CM_AUTO,
CM_UTC,
CM_LOCAL
};
-static char *adjfile = _PATH_ADJTIME;
-static unsigned verbose;
-static unsigned dryrun;
-enum ClockMode clock_mode = CM_AUTO;
+struct rtcwake_control {
+ char *adjfile; /* adjtime file path */
+ enum clock_modes clock_mode; /* hwclock timezone */
+ time_t sys_time; /* system time */
+ time_t rtc_time; /* hardware time */
+ unsigned int
+ verbose:1, /* verbose messaging */
+ dryrun:1; /* do not set alarm, suspend system, etc */
+};
static void __attribute__((__noreturn__)) usage(FILE *out)
{
@@ -123,11 +128,7 @@ static int is_wakeup_enabled(const char *devname)
return strcmp(buf, "enabled") == 0;
}
-/* all times should be in UTC */
-static time_t sys_time;
-static time_t rtc_time;
-
-static int get_basetimes(int fd)
+static int get_basetimes(struct rtcwake_control *ctl, int fd)
{
struct tm tm;
struct rtc_time rtc;
@@ -135,7 +136,7 @@ static int get_basetimes(int fd)
/* this process works in RTC time, except when working
* with the system clock (which always uses UTC).
*/
- if (clock_mode == CM_UTC)
+ if (ctl->clock_mode == CM_UTC)
setenv("TZ", "UTC", 1);
tzset();
@@ -146,8 +147,8 @@ static int get_basetimes(int fd)
warn(_("read rtc time failed"));
return -1;
}
- sys_time = time(0);
- if (sys_time == (time_t)-1) {
+ ctl->sys_time = time(0);
+ if (ctl->sys_time == (time_t)-1) {
warn(_("read system time failed"));
return -1;
}
@@ -163,33 +164,33 @@ static int get_basetimes(int fd)
tm.tm_mon = rtc.tm_mon;
tm.tm_year = rtc.tm_year;
tm.tm_isdst = -1; /* assume the system knows better than the RTC */
- rtc_time = mktime(&tm);
+ ctl->rtc_time = mktime(&tm);
- if (rtc_time == (time_t)-1) {
+ if (ctl->rtc_time == (time_t)-1) {
warn(_("convert rtc time failed"));
return -1;
}
- if (verbose) {
+ if (ctl->verbose) {
/* Unless the system uses UTC, either delta or tzone
* reflects a seconds offset from UTC. The value can
* help sort out problems like bugs in your C library.
*/
- printf("\tdelta = %ld\n", sys_time - rtc_time);
+ printf("\tdelta = %ld\n", ctl->sys_time - ctl->rtc_time);
printf("\ttzone = %ld\n", timezone);
printf("\ttzname = %s\n", tzname[daylight]);
- gmtime_r(&rtc_time, &tm);
+ gmtime_r(&ctl->rtc_time, &tm);
printf("\tsystime = %ld, (UTC) %s",
- (long) sys_time, asctime(gmtime(&sys_time)));
+ (long) ctl->sys_time, asctime(gmtime(&ctl->sys_time)));
printf("\trtctime = %ld, (UTC) %s",
- (long) rtc_time, asctime(&tm));
+ (long) ctl->rtc_time, asctime(&tm));
}
return 0;
}
-static int setup_alarm(int fd, time_t *wakeup)
+static int setup_alarm(struct rtcwake_control *ctl, int fd, time_t *wakeup)
{
struct tm *tm;
struct rtc_wkalrm wake;
@@ -220,11 +221,11 @@ static int setup_alarm(int fd, time_t *wakeup)
wake.enabled = 1;
/* First try the preferred RTC_WKALM_SET */
- if (!dryrun && ioctl(fd, RTC_WKALM_SET, &wake) < 0) {
+ if (!ctl->dryrun && ioctl(fd, RTC_WKALM_SET, &wake) < 0) {
wake.enabled = 0;
/* Fall back on the non-preferred way of setting wakeups; only
* works for alarms < 24 hours from now */
- if ((rtc_time + (24 * 60 * 60)) > *wakeup) {
+ if ((ctl->rtc_time + (24 * 60 * 60)) > *wakeup) {
if (ioctl(fd, RTC_ALM_SET, &wake.time) < 0) {
warn(_("set rtc alarm failed"));
return -1;
@@ -260,7 +261,7 @@ static int is_suspend_available(const char *suspend)
return rc;
}
-static void suspend_system(const char *suspend)
+static void suspend_system(struct rtcwake_control *ctl, const char *suspend)
{
FILE *f = fopen(SYS_POWER_STATE_PATH, "w");
@@ -269,7 +270,7 @@ static void suspend_system(const char *suspend)
return;
}
- if (!dryrun) {
+ if (!ctl->dryrun) {
fprintf(f, "%s\n", suspend);
fflush(f);
}
@@ -280,12 +281,12 @@ static void suspend_system(const char *suspend)
}
-static int read_clock_mode(void)
+static int read_clock_mode(struct rtcwake_control *ctl)
{
FILE *fp;
char linebuf[MAX_LINE];
- fp = fopen(adjfile, "r");
+ fp = fopen(ctl->adjfile, "r");
if (!fp)
return -1;
@@ -308,9 +309,9 @@ static int read_clock_mode(void)
}
if (strncmp(linebuf, "UTC", 3) == 0)
- clock_mode = CM_UTC;
+ ctl->clock_mode = CM_UTC;
else if (strncmp(linebuf, "LOCAL", 5) == 0)
- clock_mode = CM_LOCAL;
+ ctl->clock_mode = CM_LOCAL;
fclose(fp);
@@ -320,7 +321,7 @@ static int read_clock_mode(void)
/**
* print basic alarm settings
*/
-static int print_alarm(int fd)
+static int print_alarm(struct rtcwake_control *ctl, int fd)
{
struct rtc_wkalrm wake;
struct rtc_time rtc;
@@ -365,7 +366,7 @@ static int print_alarm(int fd)
}
/* 0 if both UTC, or expresses diff if RTC in local time */
- alarm += sys_time - rtc_time;
+ alarm += ctl->sys_time - ctl->rtc_time;
printf(_("alarm: on %s"), ctime(&alarm));
return 0;
@@ -373,6 +374,12 @@ static int print_alarm(int fd)
int main(int argc, char **argv)
{
+ struct rtcwake_control ctl = {
+ .adjfile = _PATH_ADJTIME,
+ .clock_mode = CM_AUTO,
+ 0
+ };
+
char *devname = DEFAULT_DEVICE;
unsigned seconds = 0;
char *suspend = DEFAULT_MODE;
@@ -408,7 +415,7 @@ int main(int argc, char **argv)
switch (t) {
case 'A':
/* for better compatibility with hwclock */
- adjfile = optarg;
+ ctl.adjfile = optarg;
break;
case 'a':
/* CM_AUTO is default */
@@ -419,7 +426,7 @@ int main(int argc, char **argv)
break;
case 'l':
- clock_mode = CM_LOCAL;
+ ctl.clock_mode = CM_LOCAL;
break;
/* what system power mode to use? for now handle only
@@ -450,7 +457,7 @@ int main(int argc, char **argv)
break;
case 'n':
- dryrun = 1;
+ ctl.dryrun = 1;
break;
/* alarm time, seconds-to-sleep (relative) */
@@ -466,11 +473,11 @@ int main(int argc, char **argv)
break;
case 'u':
- clock_mode = CM_UTC;
+ ctl.clock_mode = CM_UTC;
break;
case 'v':
- verbose++;
+ ctl.verbose = 1;
break;
case 'V':
@@ -484,15 +491,15 @@ int main(int argc, char **argv)
}
}
- if (clock_mode == CM_AUTO) {
- if (read_clock_mode() < 0) {
+ if (ctl.clock_mode == CM_AUTO) {
+ if (read_clock_mode(&ctl) < 0) {
printf(_("%s: assuming RTC uses UTC ...\n"),
program_invocation_short_name);
- clock_mode = CM_UTC;
+ ctl.clock_mode = CM_UTC;
}
}
- if (verbose)
- printf("%s", clock_mode == CM_UTC ? _("Using UTC time.\n") :
+ if (ctl.verbose)
+ printf("%s", ctl.clock_mode == CM_UTC ? _("Using UTC time.\n") :
_("Using local time.\n"));
if (!alarm && !seconds && strcmp(suspend,"disable") &&
@@ -527,11 +534,11 @@ int main(int argc, char **argv)
err(EXIT_FAILURE, _("cannot open %s"), devname);
/* relative or absolute alarm time, normalized to time_t */
- if (get_basetimes(fd) < 0)
+ if (get_basetimes(&ctl, fd) < 0)
exit(EXIT_FAILURE);
- if (verbose)
+ if (ctl.verbose)
printf(_("alarm %ld, sys_time %ld, rtc_time %ld, seconds %u\n"),
- alarm, sys_time, rtc_time, seconds);
+ alarm, ctl.sys_time, ctl.rtc_time, seconds);
if (strcmp(suspend, "show") && strcmp(suspend, "disable")) {
if (strcmp(suspend, "no") && strcmp(suspend, "on") &&
@@ -543,14 +550,14 @@ int main(int argc, char **argv)
* modes are not set
*/
if (alarm) {
- if (alarm < sys_time)
+ if (alarm < ctl.sys_time)
errx(EXIT_FAILURE, _("time doesn't go backward to %s"),
ctime(&alarm));
- alarm += sys_time - rtc_time;
+ alarm += ctl.sys_time - ctl.rtc_time;
} else
- alarm = rtc_time + seconds + 1;
+ alarm = ctl.rtc_time + seconds + 1;
- if (setup_alarm(fd, &alarm) < 0)
+ if (setup_alarm(&ctl, fd, &alarm) < 0)
exit(EXIT_FAILURE);
if (strcmp(suspend, "no") == 0 || strcmp(suspend, "on") == 0)
@@ -566,15 +573,15 @@ int main(int argc, char **argv)
}
if (strcmp(suspend, "no") == 0) {
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: no; leaving\n"));
- dryrun = 1; /* to skip disabling alarm at the end */
+ ctl.dryrun = 1; /* to skip disabling alarm at the end */
} else if (strcmp(suspend, "off") == 0) {
char *arg[5];
int i = 0;
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: off; executing %s\n"),
_PATH_SHUTDOWN);
arg[i++] = _PATH_SHUTDOWN;
@@ -583,7 +590,7 @@ int main(int argc, char **argv)
arg[i++] = "now";
arg[i] = NULL;
- if (!dryrun) {
+ if (!ctl.dryrun) {
execv(arg[0], arg);
warn(_("failed to execute %s"), _PATH_SHUTDOWN);
@@ -593,41 +600,41 @@ int main(int argc, char **argv)
} else if (strcmp(suspend, "on") == 0) {
unsigned long data;
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: on; reading rtc\n"));
- if (!dryrun) {
+ if (!ctl.dryrun) {
do {
t = read(fd, &data, sizeof data);
if (t < 0) {
warn(_("rtc read failed"));
break;
}
- if (verbose)
+ if (ctl.verbose)
printf("... %s: %03lx\n", devname, data);
} while (!(data & RTC_AF));
}
} else if (strcmp(suspend, "disable") == 0) {
/* just break, alarm gets disabled in the end */
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: disable; disabling alarm\n"));
} else if(strcmp(suspend,"show") == 0) {
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: show; printing alarm info\n"));
- if (print_alarm(fd))
+ if (print_alarm(&ctl, fd))
rc = EXIT_FAILURE;
- dryrun = 1; /* don't really disable alarm in the end, just show */
+ ctl.dryrun = 1; /* don't really disable alarm in the end, just show */
} else {
- if (verbose)
+ if (ctl.verbose)
printf(_("suspend mode: %s; suspending system\n"), suspend);
sync();
- suspend_system(suspend);
+ suspend_system(&ctl, suspend);
}
- if (!dryrun) {
+ if (!ctl.dryrun) {
/* try to disable the alarm with the preferred RTC_WKALM_RD and
* RTC_WKALM_SET calls, if it fails fall back to RTC_AIE_OFF
*/