1
2
3
4
5
6
7#include "libbb.h"
8#include "rtc_.h"
9
10int FAST_FUNC rtc_adjtime_is_utc(void)
11{
12 int utc = 0;
13 FILE *f = fopen_for_read(ADJTIME_PATH);
14
15 if (f) {
16 char buffer[128];
17
18 while (fgets(buffer, sizeof(buffer), f)) {
19 if (is_prefixed_with(buffer, "UTC")) {
20 utc = 1;
21 break;
22 }
23 }
24 fclose(f);
25 }
26
27 return utc;
28}
29
30
31
32
33
34
35static int open_loop_on_busy(const char *name, int flags)
36{
37 int rtc;
38
39
40
41
42 int try = 1000 / 20;
43 again:
44 errno = 0;
45 rtc = open(name, flags);
46 if (errno == EBUSY) {
47 usleep(20 * 1000);
48 if (--try != 0)
49 goto again;
50
51 return xopen(name, flags);
52 }
53 return rtc;
54}
55
56
57int FAST_FUNC rtc_xopen(const char **default_rtc, int flags)
58{
59 int rtc;
60 const char *name =
61 "/dev/rtc""\0"
62 "/dev/rtc0""\0"
63 "/dev/misc/rtc""\0";
64
65 if (!*default_rtc)
66 goto try_name;
67 name = "";
68
69 for (;;) {
70 rtc = open_loop_on_busy(*default_rtc, flags);
71 if (rtc >= 0)
72 return rtc;
73 if (!name[0])
74 return xopen(*default_rtc, flags);
75 try_name:
76 *default_rtc = name;
77 name += strlen(name) + 1;
78 }
79}
80
81void FAST_FUNC rtc_read_tm(struct tm *ptm, int fd)
82{
83 memset(ptm, 0, sizeof(*ptm));
84 xioctl(fd, RTC_RD_TIME, ptm);
85 ptm->tm_isdst = -1;
86}
87
88time_t FAST_FUNC rtc_tm2time(struct tm *ptm, int utc)
89{
90 char *oldtz = oldtz;
91 time_t t;
92
93 if (utc) {
94 oldtz = getenv("TZ");
95 putenv((char*)"TZ=UTC0");
96 tzset();
97 }
98
99 t = mktime(ptm);
100
101 if (utc) {
102 unsetenv("TZ");
103 if (oldtz)
104 putenv(oldtz - 3);
105 tzset();
106 }
107
108 return t;
109}
110