OSDN Git Service

Add errno includes
[android-x86/hardware-intel-libsensors.git] / utils.c
1 /*
2 // Copyright (c) 2015 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <stdlib.h>
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20 #include <utils/Log.h>
21 #include <hardware/sensors.h>
22 #include <utils/Atomic.h>
23 #include <linux/android_alarm.h>
24
25 #include "common.h"
26 #include "utils.h"
27
28 #include <errno.h>
29
30 /* Note:
31  *
32  * Some of these calls are going to fail, because not all sensors expose all
33  * possible sysfs attributes. As an optimization we may want to cache which
34  * ones are valid and immediately return in error for inexistent entries.
35  */
36 int sysfs_read(const char path[PATH_MAX], void *buf, int buf_len)
37 {
38         int fd, len;
39
40         if (!path[0] || !buf || buf_len < 1)
41                 return -1;
42
43         fd = open(path, O_RDONLY);
44
45         if (fd == -1) {
46                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
47                 return -1;
48         }
49
50         len = read(fd, buf, buf_len);
51
52         close(fd);
53
54         if (len == -1)
55                 ALOGW("Cannot read from %s (%s)\n", path, strerror(errno));
56         else
57                 ALOGV("Read %d bytes from %s\n", len, path);
58
59         return len;
60 }
61
62
63 int sysfs_write(const char path[PATH_MAX], const void *buf, const int buf_len)
64 {
65         int fd, len;
66
67         if (!path[0] || !buf || buf_len < 1)
68                 return -1;
69
70         fd = open(path, O_WRONLY);
71
72         if (fd == -1) {
73                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
74                 return -1;
75         }
76
77         len = write(fd, buf, buf_len);
78
79         close(fd);
80
81         if (len == -1)
82                 ALOGW("Cannot write to %s (%s)\n", path, strerror(errno));
83         else if (len != buf_len)
84                 ALOGW("Cannot write %d bytes to %s (%d)\n", buf_len, path, len);
85         else
86                 ALOGV("Wrote %d bytes to %s\n", buf_len, path);
87
88         return len;
89 }
90
91
92 static void str2int(const char* buf, void *v)
93 {
94         *(int*)v = atoi(buf);
95 }
96
97
98 static void str2float(const char* buf, void *v)
99 {
100         *(float*)v = strtof(buf, NULL);
101 }
102
103
104 static void str2uint64(const char* buf, void *v)
105 {
106         *(uint64_t*)v = atoll(buf);
107 }
108
109
110 int sysfs_read_num(const char path[PATH_MAX], void *v,
111                 void (*str2num)(const char* buf, void *v))
112 {
113         char buf[20];
114         int len = sysfs_read_str(path, buf, sizeof(buf));
115
116         if (len <= 0) {
117                 ALOGW("Cannot read number from %s (%s)\n", path,
118                       strerror(errno));
119                 return -1;
120         }
121
122         str2num(buf, v);
123         return 0;
124 }
125
126
127 int sysfs_read_int(const char path[PATH_MAX], int *value)
128 {
129         return sysfs_read_num(path, value, str2int);
130 }
131
132
133 int sysfs_read_float(const char path[PATH_MAX], float *value)
134 {
135         return sysfs_read_num(path, value, str2float);
136 }
137
138
139 int sysfs_read_uint64(const char path[PATH_MAX], uint64_t *value)
140 {
141         return sysfs_read_num(path, value, str2uint64);
142 }
143
144
145 int sysfs_write_int(const char path[PATH_MAX], int value)
146 {
147         char buf[20];
148         int len = snprintf(buf, sizeof(buf), "%d", value);
149
150         if (len <= 0) {
151                 ALOGE("Unexpected condition in sysfs_write_int\n");
152                 return -1;
153         }
154
155         return sysfs_write(path, buf, len);
156 }
157
158 int sysfs_write_float(const char path[PATH_MAX], float value)
159 {
160         char buf[20];
161         int len = snprintf(buf, sizeof(buf), "%g", value);
162
163         if (len <= 0) {
164                 ALOGE("Unexpected condition in sysfs_write_float\n");
165                 return -1;
166         }
167
168         return sysfs_write(path, buf, len);
169 }
170
171
172 int sysfs_write_str(const char path[PATH_MAX], const char *str)
173 {
174         if (!str || !str[0])
175                 return -1;
176
177         return sysfs_write(path, str, strlen(str));
178 }
179
180
181 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
182 {
183         int len;
184
185         if (!buf || buf_len < 1)
186                 return -1;
187
188         len = sysfs_read(path, buf, buf_len);
189
190         if (len == -1) {
191                 ALOGW("Cannot read string from %s (%s)\n", path,
192                       strerror(errno));
193                 return -1;
194         }
195
196         buf[len == 0 ? 0 : len - 1] = '\0';
197
198         ALOGV("Read %s from %s\n", buf, path);
199
200         return len;
201 }
202
203
204 int64_t get_timestamp (clockid_t clock_id)
205 {
206         struct timespec ts = {0};
207
208         if (!clock_gettime(clock_id, &ts))
209                 return 1000000000LL * ts.tv_sec + ts.tv_nsec;
210         else    /* in this case errno is set appropriately */
211                 return -1;
212 }
213
214 int64_t get_timestamp_realtime (void)
215 {
216         return get_timestamp(CLOCK_REALTIME);
217 }
218
219 int64_t get_timestamp_boot (void)
220 {
221         return get_timestamp(CLOCK_BOOTTIME);
222 }
223
224 int64_t get_timestamp_thread (void)
225 {
226         return get_timestamp(CLOCK_THREAD_CPUTIME_ID);
227 }
228
229 int64_t get_timestamp_monotonic (void)
230 {
231         return get_timestamp(CLOCK_MONOTONIC);
232 }
233
234 void set_timestamp (struct timespec *out, int64_t target_ns)
235 {
236         out->tv_sec  = target_ns / 1000000000LL;
237         out->tv_nsec = target_ns % 1000000000LL;
238 }
239