blob: b8e595759b15e1fa63645a76d302339f7ecf06bf [file] [log] [blame]
The Android Open Source Project8ac3a132009-01-20 14:04:01 -08001
2/*
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include <fcntl.h>
21#include <unistd.h>
22#include <malloc.h>
23#include <errno.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27
28void *read_file(char *filename, ssize_t *_size)
29{
30 int ret, fd;
31 struct stat sb;
32 ssize_t size;
33 void *buffer = NULL;
34
35 /* open the file */
36 fd = open(filename, O_RDONLY);
37 if (fd < 0)
38 return NULL;
39
40 /* find out how big it is */
41 if (fstat(fd, &sb) < 0)
42 goto bail;
43 size = sb.st_size;
44
45 /* allocate memory for it to be read into */
46 buffer = malloc(size);
47 if (!buffer)
48 goto bail;
49
50 /* slurp it into our buffer */
51 ret = read(fd, buffer, size);
The Android Open Source Project261ed752009-02-19 10:57:36 -080052 if (ret != size) {
53 free(buffer);
54 buffer = NULL;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080055 goto bail;
The Android Open Source Project261ed752009-02-19 10:57:36 -080056 }
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080057
58 /* let the caller know how big it is */
59 *_size = size;
60
61bail:
62 close(fd);
63 return buffer;
64}
The Android Open Source Project261ed752009-02-19 10:57:36 -080065
66char *truncate_sysfs_path(char *path, int count, char *buffer, size_t bufflen)
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080067{
The Android Open Source Project261ed752009-02-19 10:57:36 -080068 char* p;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080069
The Android Open Source Project261ed752009-02-19 10:57:36 -080070 strlcpy(buffer, path, bufflen);
71 p = buffer + strlen(buffer);
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080072
The Android Open Source Project261ed752009-02-19 10:57:36 -080073 for ( ; count > 0; count-- ) {
74 while (p > buffer && p[-1] != '/') {
75 p--;
76 }
77 if (p == buffer)
78 break;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080079
The Android Open Source Project261ed752009-02-19 10:57:36 -080080 p -= 1;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080081 }
The Android Open Source Project261ed752009-02-19 10:57:36 -080082 p[0] = '\0';
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080083
84 return buffer;
85}
86
The Android Open Source Project261ed752009-02-19 10:57:36 -080087/* used to read the first line of a /sys file into a heap-allocated buffer
88 * this assumes that reading the file returns a list of zero-terminated strings,
89 * each could also have a terminating \n before the 0
90 *
91 * returns NULL on error, of a new string on success, which must be freed by the
92 * caller.
93 */
94char *read_first_line_of(const char* filepath)
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080095{
The Android Open Source Project261ed752009-02-19 10:57:36 -080096 char *p, *q, *line;
97 size_t len;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080098 ssize_t sz;
99
The Android Open Source Project261ed752009-02-19 10:57:36 -0800100 p = read_file((char*)filepath, &sz);
101 if (p == NULL)
102 goto FAIL;
103
104 /* search end of first line */
105 q = memchr(p, sz, '\0');
106 if (q == NULL)
107 q = p + sz; /* let's be flexible */
108
109 len = (size_t)(q - p); /* compute line length */
110 if (len == 0)
111 goto FAIL;
112
113 if (p[len-1] == '\n') { /* strip trailing \n */
114 len -= 1;
115 if (len == 0)
116 goto FAIL;
117 }
118
119 line = malloc(len+1);
120 if (line == NULL)
121 goto FAIL;
122
123 memcpy(line, p, len);
124 line[len] = 0;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800125 free(p);
The Android Open Source Project261ed752009-02-19 10:57:36 -0800126
127 return line;
128
129FAIL:
130 if (p != NULL)
131 free(p);
132
133 return NULL;
134}
135
136char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
137{
138 char filename[255], *line;
139
140 snprintf(filename, sizeof filename, "/sys%s/%s", devpath, var);
141
142 line = read_first_line_of(filename);
143 if (line == NULL)
144 return NULL;
145
146 snprintf(buffer, maxlen, "%s", line);
147 free(line);
148
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800149 return buffer;
150}
151