source: MondoRescue/branches/3.3/mindi-busybox/libbb/rtc.c@ 3647

Last change on this file since 3647 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 2.1 KB
Line 
1/*
2 * Common RTC functions
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7#include "libbb.h"
8#include "rtc_.h"
9
10#if ENABLE_FEATURE_HWCLOCK_ADJTIME_FHS
11# define ADJTIME_PATH "/var/lib/hwclock/adjtime"
12#else
13# define ADJTIME_PATH "/etc/adjtime"
14#endif
15
16int FAST_FUNC rtc_adjtime_is_utc(void)
17{
18 int utc = 0;
19 FILE *f = fopen_for_read(ADJTIME_PATH);
20
21 if (f) {
22 char buffer[128];
23
24 while (fgets(buffer, sizeof(buffer), f)) {
25 if (is_prefixed_with(buffer, "UTC")) {
26 utc = 1;
27 break;
28 }
29 }
30 fclose(f);
31 }
32
33 return utc;
34}
35
36/* rtc opens are exclusive.
37 * Try to run two "hwclock -w" at the same time to see it.
38 * Users wouldn't expect that to fail merely because /dev/rtc
39 * was momentarily busy, let's try a bit harder on errno == EBUSY.
40 */
41static int open_loop_on_busy(const char *name, int flags)
42{
43 int rtc;
44 /*
45 * Tested with two parallel "hwclock -w" loops.
46 * With try = 10, no failures with 2x1000000 loop iterations.
47 */
48 int try = 1000 / 20;
49 again:
50 errno = 0;
51 rtc = open(name, flags);
52 if (errno == EBUSY) {
53 usleep(20 * 1000);
54 if (--try != 0)
55 goto again;
56 /* EBUSY. Last try, exit on error instead of returning -1 */
57 return xopen(name, flags);
58 }
59 return rtc;
60}
61
62/* Never fails */
63int FAST_FUNC rtc_xopen(const char **default_rtc, int flags)
64{
65 int rtc;
66 const char *name =
67 "/dev/rtc""\0"
68 "/dev/rtc0""\0"
69 "/dev/misc/rtc""\0";
70
71 if (!*default_rtc)
72 goto try_name;
73 name = ""; /*else: we have rtc name, don't try other names */
74
75 for (;;) {
76 rtc = open_loop_on_busy(*default_rtc, flags);
77 if (rtc >= 0)
78 return rtc;
79 if (!name[0])
80 return xopen(*default_rtc, flags);
81 try_name:
82 *default_rtc = name;
83 name += strlen(name) + 1;
84 }
85}
86
87void FAST_FUNC rtc_read_tm(struct tm *ptm, int fd)
88{
89 memset(ptm, 0, sizeof(*ptm));
90 xioctl(fd, RTC_RD_TIME, ptm);
91 ptm->tm_isdst = -1; /* "not known" */
92}
93
94time_t FAST_FUNC rtc_tm2time(struct tm *ptm, int utc)
95{
96 char *oldtz = oldtz; /* for compiler */
97 time_t t;
98
99 if (utc) {
100 oldtz = getenv("TZ");
101 putenv((char*)"TZ=UTC0");
102 tzset();
103 }
104
105 t = mktime(ptm);
106
107 if (utc) {
108 unsetenv("TZ");
109 if (oldtz)
110 putenv(oldtz - 3);
111 tzset();
112 }
113
114 return t;
115}
Note: See TracBrowser for help on using the repository browser.