blob: 54016ed74f4dc4c1c3330cab3da83dc930db410c [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
Damjan Marionf55f9b82017-05-10 21:06:28 +020048__thread uword __os_thread_index = 0;
Dave Baracha690fdb2020-01-21 12:34:55 -050049__thread uword __os_numa_index = 0;
Damjan Marionf55f9b82017-05-10 21:06:28 +020050
Dave Barachc3799992016-08-15 11:12:27 -040051clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040052clib_file_n_bytes (char *file, uword * result)
Ed Warnickecb9cada2015-12-08 15:45:58 -070053{
54 struct stat s;
55
56 if (stat (file, &s) < 0)
57 return clib_error_return_unix (0, "stat `%s'", file);
58
59 if (S_ISREG (s.st_mode))
60 *result = s.st_size;
61 else
62 *result = 0;
63
64 return /* no error */ 0;
65}
66
Dave Barachc3799992016-08-15 11:12:27 -040067clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040068clib_file_read_contents (char *file, u8 * result, uword n_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -070069{
70 int fd = -1;
71 uword n_done, n_left;
Dave Barachc3799992016-08-15 11:12:27 -040072 clib_error_t *error = 0;
73 u8 *v = result;
Ed Warnickecb9cada2015-12-08 15:45:58 -070074
75 if ((fd = open (file, 0)) < 0)
Dave Barachc3799992016-08-15 11:12:27 -040076 return clib_error_return_unix (0, "open `%s'", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
78 n_left = n_bytes;
79 n_done = 0;
80 while (n_left > 0)
81 {
82 int n_read;
83 if ((n_read = read (fd, v + n_done, n_left)) < 0)
84 {
85 error = clib_error_return_unix (0, "open `%s'", file);
86 goto done;
87 }
88
89 /* End of file. */
90 if (n_read == 0)
91 break;
92
93 n_left -= n_read;
94 n_done += n_read;
95 }
96
97 if (n_left > 0)
98 {
Dave Barachc3799992016-08-15 11:12:27 -040099 error =
100 clib_error_return (0,
101 " `%s' expected to read %wd bytes; read only %wd",
102 file, n_bytes, n_bytes - n_left);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700103 goto done;
104 }
105
Dave Barachc3799992016-08-15 11:12:27 -0400106done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700107 close (fd);
108 return error;
109}
110
Dave Barachc3799992016-08-15 11:12:27 -0400111clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -0400112clib_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700113{
114 uword n_bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400115 clib_error_t *error = 0;
116 u8 *v;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700117
Dave Barach59b25652017-09-10 15:04:27 -0400118 if ((error = clib_file_n_bytes (file, &n_bytes)))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119 return error;
120
121 v = 0;
122 vec_resize (v, n_bytes);
123
Dave Barach59b25652017-09-10 15:04:27 -0400124 error = clib_file_read_contents (file, v, n_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700125
126 if (error)
127 vec_free (v);
128 else
129 *result = v;
130
131 return error;
132}
133
Dave Barachc3799992016-08-15 11:12:27 -0400134clib_error_t *
135unix_proc_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136{
137 u8 *rv = 0;
138 uword pos;
139 int bytes, fd;
140
141 /* Unfortunately, stat(/proc/XXX) returns zero... */
142 fd = open (file, O_RDONLY);
143
144 if (fd < 0)
145 return clib_error_return_unix (0, "open `%s'", file);
146
Dave Barachc3799992016-08-15 11:12:27 -0400147 vec_validate (rv, 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148 pos = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400149 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700150 {
Dave Barachc3799992016-08-15 11:12:27 -0400151 bytes = read (fd, rv + pos, 4096);
152 if (bytes < 0)
153 {
154 close (fd);
155 vec_free (rv);
156 return clib_error_return_unix (0, "read '%s'", file);
157 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700158
Dave Barachc3799992016-08-15 11:12:27 -0400159 if (bytes == 0)
160 {
161 _vec_len (rv) = pos;
162 break;
163 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700164 pos += bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400165 vec_validate (rv, pos + 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166 }
167 *result = rv;
168 close (fd);
169 return 0;
170}
171
172void os_panic (void) __attribute__ ((weak));
173
Dave Barachc3799992016-08-15 11:12:27 -0400174void
175os_panic (void)
176{
177 abort ();
178}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179
180void os_exit (int) __attribute__ ((weak));
181
Dave Barachc3799992016-08-15 11:12:27 -0400182void
183os_exit (int code)
184{
185 exit (code);
186}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187
188void os_puts (u8 * string, uword string_length, uword is_error)
189 __attribute__ ((weak));
190
Dave Barachc3799992016-08-15 11:12:27 -0400191void
192os_puts (u8 * string, uword string_length, uword is_error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193{
Damjan Marionf55f9b82017-05-10 21:06:28 +0200194 int cpu = os_get_thread_index ();
195 int nthreads = os_get_nthreads ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700196 char buf[64];
197 int fd = is_error ? 2 : 1;
198 struct iovec iovs[2];
199 int n_iovs = 0;
200
Damjan Marionf55f9b82017-05-10 21:06:28 +0200201 if (nthreads > 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700202 {
Dave Barachc3799992016-08-15 11:12:27 -0400203 snprintf (buf, sizeof (buf), "%d: ", cpu);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700204
205 iovs[n_iovs].iov_base = buf;
206 iovs[n_iovs].iov_len = strlen (buf);
207 n_iovs++;
208 }
209
210 iovs[n_iovs].iov_base = string;
211 iovs[n_iovs].iov_len = string_length;
212 n_iovs++;
213
214 if (writev (fd, iovs, n_iovs) < 0)
215 ;
216}
217
218void os_out_of_memory (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400219void
220os_out_of_memory (void)
221{
222 os_panic ();
223}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700224
Damjan Marionf55f9b82017-05-10 21:06:28 +0200225uword os_get_nthreads (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400226uword
Damjan Marionf55f9b82017-05-10 21:06:28 +0200227os_get_nthreads (void)
Dave Barachc3799992016-08-15 11:12:27 -0400228{
229 return 1;
230}
231
232/*
233 * fd.io coding-style-patch-verification: ON
234 *
235 * Local Variables:
236 * eval: (c-set-style "gnu")
237 * End:
238 */