blob: 0c5d96c6bb7efaaeffbdb439b91264e84f8a2621 [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);
151
152 if (r < 1)
153 return 0;
154
155 p = buffer + r - 1;
156 while (p > buffer && p[-1] != '/')
157 p--;
158
159 while (p[0])
160 vec_add1 (s, p++[0]);
161
162 return s;
163}
164
Dave Barachc3799992016-08-15 11:12:27 -0400165clib_error_t *
166unix_proc_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700167{
168 u8 *rv = 0;
169 uword pos;
170 int bytes, fd;
171
172 /* Unfortunately, stat(/proc/XXX) returns zero... */
173 fd = open (file, O_RDONLY);
174
175 if (fd < 0)
176 return clib_error_return_unix (0, "open `%s'", file);
177
Dave Barachc3799992016-08-15 11:12:27 -0400178 vec_validate (rv, 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 pos = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400180 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 {
Dave Barachc3799992016-08-15 11:12:27 -0400182 bytes = read (fd, rv + pos, 4096);
183 if (bytes < 0)
184 {
185 close (fd);
186 vec_free (rv);
187 return clib_error_return_unix (0, "read '%s'", file);
188 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700189
Dave Barachc3799992016-08-15 11:12:27 -0400190 if (bytes == 0)
191 {
Damjan Marion8bea5892022-04-04 22:40:45 +0200192 vec_set_len (rv, pos);
Dave Barachc3799992016-08-15 11:12:27 -0400193 break;
194 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 pos += bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400196 vec_validate (rv, pos + 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197 }
198 *result = rv;
199 close (fd);
200 return 0;
201}
202
203void os_panic (void) __attribute__ ((weak));
204
Damjan Marion4a251d02021-05-06 17:28:12 +0200205__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400206os_panic (void)
207{
208 abort ();
209}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210
211void os_exit (int) __attribute__ ((weak));
212
Dave Barachc3799992016-08-15 11:12:27 -0400213void
214os_exit (int code)
215{
216 exit (code);
217}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700218
219void os_puts (u8 * string, uword string_length, uword is_error)
220 __attribute__ ((weak));
221
Dave Barachc3799992016-08-15 11:12:27 -0400222void
223os_puts (u8 * string, uword string_length, uword is_error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700224{
Damjan Marionf55f9b82017-05-10 21:06:28 +0200225 int cpu = os_get_thread_index ();
226 int nthreads = os_get_nthreads ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227 char buf[64];
228 int fd = is_error ? 2 : 1;
229 struct iovec iovs[2];
230 int n_iovs = 0;
231
Damjan Marionf55f9b82017-05-10 21:06:28 +0200232 if (nthreads > 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700233 {
Dave Barachc3799992016-08-15 11:12:27 -0400234 snprintf (buf, sizeof (buf), "%d: ", cpu);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700235
236 iovs[n_iovs].iov_base = buf;
237 iovs[n_iovs].iov_len = strlen (buf);
238 n_iovs++;
239 }
240
241 iovs[n_iovs].iov_base = string;
242 iovs[n_iovs].iov_len = string_length;
243 n_iovs++;
244
245 if (writev (fd, iovs, n_iovs) < 0)
246 ;
247}
248
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200249__clib_export __clib_weak void
Dave Barachc3799992016-08-15 11:12:27 -0400250os_out_of_memory (void)
251{
252 os_panic ();
253}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700254
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200255__clib_export __clib_weak uword
Damjan Marionf55f9b82017-05-10 21:06:28 +0200256os_get_nthreads (void)
Dave Barachc3799992016-08-15 11:12:27 -0400257{
258 return 1;
259}
260
261/*
262 * fd.io coding-style-patch-verification: ON
263 *
264 * Local Variables:
265 * eval: (c-set-style "gnu")
266 * End:
267 */