blob: 2928369d52e579099c54c314623fcb90e99ead10 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2005 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38#include <vppinfra/error.h>
39#include <vppinfra/os.h>
40#include <vppinfra/unix.h>
41
42#include <sys/stat.h>
43#include <sys/types.h>
44#include <sys/uio.h> /* writev */
45#include <fcntl.h>
46#include <stdio.h> /* for sprintf */
47
Dave Barachc3799992016-08-15 11:12:27 -040048clib_error_t *
49unix_file_n_bytes (char *file, uword * result)
Ed Warnickecb9cada2015-12-08 15:45:58 -070050{
51 struct stat s;
52
53 if (stat (file, &s) < 0)
54 return clib_error_return_unix (0, "stat `%s'", file);
55
56 if (S_ISREG (s.st_mode))
57 *result = s.st_size;
58 else
59 *result = 0;
60
61 return /* no error */ 0;
62}
63
Dave Barachc3799992016-08-15 11:12:27 -040064clib_error_t *
65unix_file_read_contents (char *file, u8 * result, uword n_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -070066{
67 int fd = -1;
68 uword n_done, n_left;
Dave Barachc3799992016-08-15 11:12:27 -040069 clib_error_t *error = 0;
70 u8 *v = result;
Ed Warnickecb9cada2015-12-08 15:45:58 -070071
72 if ((fd = open (file, 0)) < 0)
Dave Barachc3799992016-08-15 11:12:27 -040073 return clib_error_return_unix (0, "open `%s'", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -070074
75 n_left = n_bytes;
76 n_done = 0;
77 while (n_left > 0)
78 {
79 int n_read;
80 if ((n_read = read (fd, v + n_done, n_left)) < 0)
81 {
82 error = clib_error_return_unix (0, "open `%s'", file);
83 goto done;
84 }
85
86 /* End of file. */
87 if (n_read == 0)
88 break;
89
90 n_left -= n_read;
91 n_done += n_read;
92 }
93
94 if (n_left > 0)
95 {
Dave Barachc3799992016-08-15 11:12:27 -040096 error =
97 clib_error_return (0,
98 " `%s' expected to read %wd bytes; read only %wd",
99 file, n_bytes, n_bytes - n_left);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700100 goto done;
101 }
102
Dave Barachc3799992016-08-15 11:12:27 -0400103done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104 close (fd);
105 return error;
106}
107
Dave Barachc3799992016-08-15 11:12:27 -0400108clib_error_t *
109unix_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700110{
111 uword n_bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400112 clib_error_t *error = 0;
113 u8 *v;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700114
115 if ((error = unix_file_n_bytes (file, &n_bytes)))
116 return error;
117
118 v = 0;
119 vec_resize (v, n_bytes);
120
121 error = unix_file_read_contents (file, v, n_bytes);
122
123 if (error)
124 vec_free (v);
125 else
126 *result = v;
127
128 return error;
129}
130
Dave Barachc3799992016-08-15 11:12:27 -0400131clib_error_t *
132unix_proc_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133{
134 u8 *rv = 0;
135 uword pos;
136 int bytes, fd;
137
138 /* Unfortunately, stat(/proc/XXX) returns zero... */
139 fd = open (file, O_RDONLY);
140
141 if (fd < 0)
142 return clib_error_return_unix (0, "open `%s'", file);
143
Dave Barachc3799992016-08-15 11:12:27 -0400144 vec_validate (rv, 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700145 pos = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400146 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147 {
Dave Barachc3799992016-08-15 11:12:27 -0400148 bytes = read (fd, rv + pos, 4096);
149 if (bytes < 0)
150 {
151 close (fd);
152 vec_free (rv);
153 return clib_error_return_unix (0, "read '%s'", file);
154 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700155
Dave Barachc3799992016-08-15 11:12:27 -0400156 if (bytes == 0)
157 {
158 _vec_len (rv) = pos;
159 break;
160 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161 pos += bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400162 vec_validate (rv, pos + 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163 }
164 *result = rv;
165 close (fd);
166 return 0;
167}
168
169void os_panic (void) __attribute__ ((weak));
170
Dave Barachc3799992016-08-15 11:12:27 -0400171void
172os_panic (void)
173{
174 abort ();
175}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176
177void os_exit (int) __attribute__ ((weak));
178
Dave Barachc3799992016-08-15 11:12:27 -0400179void
180os_exit (int code)
181{
182 exit (code);
183}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700184
185void os_puts (u8 * string, uword string_length, uword is_error)
186 __attribute__ ((weak));
187
Dave Barachc3799992016-08-15 11:12:27 -0400188void
189os_puts (u8 * string, uword string_length, uword is_error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191 int cpu = os_get_cpu_number ();
Dave Barachc3799992016-08-15 11:12:27 -0400192 int ncpus = os_get_ncpus ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193 char buf[64];
194 int fd = is_error ? 2 : 1;
195 struct iovec iovs[2];
196 int n_iovs = 0;
197
Dave Barach01d86c72016-08-08 15:13:42 -0400198 if (ncpus > 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199 {
Dave Barachc3799992016-08-15 11:12:27 -0400200 snprintf (buf, sizeof (buf), "%d: ", cpu);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201
202 iovs[n_iovs].iov_base = buf;
203 iovs[n_iovs].iov_len = strlen (buf);
204 n_iovs++;
205 }
206
207 iovs[n_iovs].iov_base = string;
208 iovs[n_iovs].iov_len = string_length;
209 n_iovs++;
210
211 if (writev (fd, iovs, n_iovs) < 0)
212 ;
213}
214
215void os_out_of_memory (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400216void
217os_out_of_memory (void)
218{
219 os_panic ();
220}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700221
222uword os_get_cpu_number (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400223uword
224os_get_cpu_number (void)
225{
226 return 0;
227}
Dave Barach01d86c72016-08-08 15:13:42 -0400228
229uword os_get_ncpus (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400230uword
231os_get_ncpus (void)
232{
233 return 1;
234}
235
236/*
237 * fd.io coding-style-patch-verification: ON
238 *
239 * Local Variables:
240 * eval: (c-set-style "gnu")
241 * End:
242 */