blob: 2918fc3232826923cf47ad82843a064499c28e23 [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>
Damjan Marion40f48102023-08-07 01:07:09 +020041#include <vppinfra/format.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070042
43#include <sys/stat.h>
44#include <sys/types.h>
45#include <sys/uio.h> /* writev */
46#include <fcntl.h>
47#include <stdio.h> /* for sprintf */
Damjan Marion40f48102023-08-07 01:07:09 +020048#include <limits.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070049
Damjan Mariondae1c7e2020-10-17 13:32:25 +020050__clib_export __thread uword __os_thread_index = 0;
51__clib_export __thread uword __os_numa_index = 0;
Damjan Marionf55f9b82017-05-10 21:06:28 +020052
Dave Barachc3799992016-08-15 11:12:27 -040053clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040054clib_file_n_bytes (char *file, uword * result)
Ed Warnickecb9cada2015-12-08 15:45:58 -070055{
56 struct stat s;
57
58 if (stat (file, &s) < 0)
59 return clib_error_return_unix (0, "stat `%s'", file);
60
61 if (S_ISREG (s.st_mode))
62 *result = s.st_size;
63 else
64 *result = 0;
65
66 return /* no error */ 0;
67}
68
Dave Barachc3799992016-08-15 11:12:27 -040069clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040070clib_file_read_contents (char *file, u8 * result, uword n_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -070071{
72 int fd = -1;
73 uword n_done, n_left;
Dave Barachc3799992016-08-15 11:12:27 -040074 clib_error_t *error = 0;
75 u8 *v = result;
Ed Warnickecb9cada2015-12-08 15:45:58 -070076
77 if ((fd = open (file, 0)) < 0)
Dave Barachc3799992016-08-15 11:12:27 -040078 return clib_error_return_unix (0, "open `%s'", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -070079
80 n_left = n_bytes;
81 n_done = 0;
82 while (n_left > 0)
83 {
84 int n_read;
85 if ((n_read = read (fd, v + n_done, n_left)) < 0)
86 {
87 error = clib_error_return_unix (0, "open `%s'", file);
88 goto done;
89 }
90
91 /* End of file. */
92 if (n_read == 0)
93 break;
94
95 n_left -= n_read;
96 n_done += n_read;
97 }
98
99 if (n_left > 0)
100 {
Dave Barachc3799992016-08-15 11:12:27 -0400101 error =
102 clib_error_return (0,
103 " `%s' expected to read %wd bytes; read only %wd",
104 file, n_bytes, n_bytes - n_left);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105 goto done;
106 }
107
Dave Barachc3799992016-08-15 11:12:27 -0400108done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700109 close (fd);
110 return error;
111}
112
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200113__clib_export clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -0400114clib_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115{
116 uword n_bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400117 clib_error_t *error = 0;
118 u8 *v;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119
Dave Barach59b25652017-09-10 15:04:27 -0400120 if ((error = clib_file_n_bytes (file, &n_bytes)))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700121 return error;
122
123 v = 0;
124 vec_resize (v, n_bytes);
125
Dave Barach59b25652017-09-10 15:04:27 -0400126 error = clib_file_read_contents (file, v, n_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127
128 if (error)
129 vec_free (v);
130 else
131 *result = v;
132
133 return error;
134}
135
Damjan Marion40f48102023-08-07 01:07:09 +0200136__clib_export u8 *
137clib_file_get_resolved_basename (char *fmt, ...)
138{
139 va_list va;
140 char *p, buffer[PATH_MAX];
141 u8 *link, *s = 0;
142 int r;
143
144 va_start (va, fmt);
145 link = va_format (0, fmt, &va);
146 va_end (va);
147 vec_add1 (link, 0);
148
149 r = readlink ((char *) link, buffer, sizeof (buffer) - 1);
150 vec_free (link);
Damjan Marion08600cc2023-10-04 18:03:18 +0200151 buffer[r] = 0;
Damjan Marion40f48102023-08-07 01:07:09 +0200152
153 if (r < 1)
154 return 0;
155
156 p = buffer + r - 1;
157 while (p > buffer && p[-1] != '/')
158 p--;
159
160 while (p[0])
161 vec_add1 (s, p++[0]);
162
Damjan Marion08600cc2023-10-04 18:03:18 +0200163 vec_add1 (s, 0);
Damjan Marion40f48102023-08-07 01:07:09 +0200164 return s;
165}
166
Dave Barachc3799992016-08-15 11:12:27 -0400167clib_error_t *
168unix_proc_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700169{
170 u8 *rv = 0;
171 uword pos;
172 int bytes, fd;
173
174 /* Unfortunately, stat(/proc/XXX) returns zero... */
175 fd = open (file, O_RDONLY);
176
177 if (fd < 0)
178 return clib_error_return_unix (0, "open `%s'", file);
179
Dave Barachc3799992016-08-15 11:12:27 -0400180 vec_validate (rv, 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 pos = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400182 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183 {
Dave Barachc3799992016-08-15 11:12:27 -0400184 bytes = read (fd, rv + pos, 4096);
185 if (bytes < 0)
186 {
187 close (fd);
188 vec_free (rv);
189 return clib_error_return_unix (0, "read '%s'", file);
190 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191
Dave Barachc3799992016-08-15 11:12:27 -0400192 if (bytes == 0)
193 {
Damjan Marion8bea5892022-04-04 22:40:45 +0200194 vec_set_len (rv, pos);
Dave Barachc3799992016-08-15 11:12:27 -0400195 break;
196 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197 pos += bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400198 vec_validate (rv, pos + 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199 }
200 *result = rv;
201 close (fd);
202 return 0;
203}
204
205void os_panic (void) __attribute__ ((weak));
206
Damjan Marion4a251d02021-05-06 17:28:12 +0200207__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400208os_panic (void)
209{
210 abort ();
211}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700212
213void os_exit (int) __attribute__ ((weak));
214
Dave Barachc3799992016-08-15 11:12:27 -0400215void
216os_exit (int code)
217{
218 exit (code);
219}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700220
221void os_puts (u8 * string, uword string_length, uword is_error)
222 __attribute__ ((weak));
223
Dave Barachc3799992016-08-15 11:12:27 -0400224void
225os_puts (u8 * string, uword string_length, uword is_error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700226{
Damjan Marionf55f9b82017-05-10 21:06:28 +0200227 int cpu = os_get_thread_index ();
228 int nthreads = os_get_nthreads ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229 char buf[64];
230 int fd = is_error ? 2 : 1;
231 struct iovec iovs[2];
232 int n_iovs = 0;
233
Damjan Marionf55f9b82017-05-10 21:06:28 +0200234 if (nthreads > 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700235 {
Dave Barachc3799992016-08-15 11:12:27 -0400236 snprintf (buf, sizeof (buf), "%d: ", cpu);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237
238 iovs[n_iovs].iov_base = buf;
239 iovs[n_iovs].iov_len = strlen (buf);
240 n_iovs++;
241 }
242
243 iovs[n_iovs].iov_base = string;
244 iovs[n_iovs].iov_len = string_length;
245 n_iovs++;
246
247 if (writev (fd, iovs, n_iovs) < 0)
248 ;
249}
250
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200251__clib_export __clib_weak void
Dave Barachc3799992016-08-15 11:12:27 -0400252os_out_of_memory (void)
253{
254 os_panic ();
255}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700256
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200257__clib_export __clib_weak uword
Damjan Marionf55f9b82017-05-10 21:06:28 +0200258os_get_nthreads (void)
Dave Barachc3799992016-08-15 11:12:27 -0400259{
260 return 1;
261}
262
263/*
264 * fd.io coding-style-patch-verification: ON
265 *
266 * Local Variables:
267 * eval: (c-set-style "gnu")
268 * End:
269 */