blob: f693102c65a14d49525eb2704d4c38fcda20fa3a [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;
49
Dave Barachc3799992016-08-15 11:12:27 -040050clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040051clib_file_n_bytes (char *file, uword * result)
Ed Warnickecb9cada2015-12-08 15:45:58 -070052{
53 struct stat s;
54
55 if (stat (file, &s) < 0)
56 return clib_error_return_unix (0, "stat `%s'", file);
57
58 if (S_ISREG (s.st_mode))
59 *result = s.st_size;
60 else
61 *result = 0;
62
63 return /* no error */ 0;
64}
65
Dave Barachc3799992016-08-15 11:12:27 -040066clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -040067clib_file_read_contents (char *file, u8 * result, uword n_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -070068{
69 int fd = -1;
70 uword n_done, n_left;
Dave Barachc3799992016-08-15 11:12:27 -040071 clib_error_t *error = 0;
72 u8 *v = result;
Ed Warnickecb9cada2015-12-08 15:45:58 -070073
74 if ((fd = open (file, 0)) < 0)
Dave Barachc3799992016-08-15 11:12:27 -040075 return clib_error_return_unix (0, "open `%s'", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -070076
77 n_left = n_bytes;
78 n_done = 0;
79 while (n_left > 0)
80 {
81 int n_read;
82 if ((n_read = read (fd, v + n_done, n_left)) < 0)
83 {
84 error = clib_error_return_unix (0, "open `%s'", file);
85 goto done;
86 }
87
88 /* End of file. */
89 if (n_read == 0)
90 break;
91
92 n_left -= n_read;
93 n_done += n_read;
94 }
95
96 if (n_left > 0)
97 {
Dave Barachc3799992016-08-15 11:12:27 -040098 error =
99 clib_error_return (0,
100 " `%s' expected to read %wd bytes; read only %wd",
101 file, n_bytes, n_bytes - n_left);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 goto done;
103 }
104
Dave Barachc3799992016-08-15 11:12:27 -0400105done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700106 close (fd);
107 return error;
108}
109
Dave Barachc3799992016-08-15 11:12:27 -0400110clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -0400111clib_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700112{
113 uword n_bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400114 clib_error_t *error = 0;
115 u8 *v;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116
Dave Barach59b25652017-09-10 15:04:27 -0400117 if ((error = clib_file_n_bytes (file, &n_bytes)))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700118 return error;
119
120 v = 0;
121 vec_resize (v, n_bytes);
122
Dave Barach59b25652017-09-10 15:04:27 -0400123 error = clib_file_read_contents (file, v, n_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124
125 if (error)
126 vec_free (v);
127 else
128 *result = v;
129
130 return error;
131}
132
Dave Barachc3799992016-08-15 11:12:27 -0400133clib_error_t *
134unix_proc_file_contents (char *file, u8 ** result)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135{
136 u8 *rv = 0;
137 uword pos;
138 int bytes, fd;
139
140 /* Unfortunately, stat(/proc/XXX) returns zero... */
141 fd = open (file, O_RDONLY);
142
143 if (fd < 0)
144 return clib_error_return_unix (0, "open `%s'", file);
145
Dave Barachc3799992016-08-15 11:12:27 -0400146 vec_validate (rv, 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147 pos = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400148 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149 {
Dave Barachc3799992016-08-15 11:12:27 -0400150 bytes = read (fd, rv + pos, 4096);
151 if (bytes < 0)
152 {
153 close (fd);
154 vec_free (rv);
155 return clib_error_return_unix (0, "read '%s'", file);
156 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157
Dave Barachc3799992016-08-15 11:12:27 -0400158 if (bytes == 0)
159 {
160 _vec_len (rv) = pos;
161 break;
162 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163 pos += bytes;
Dave Barachc3799992016-08-15 11:12:27 -0400164 vec_validate (rv, pos + 4095);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700165 }
166 *result = rv;
167 close (fd);
168 return 0;
169}
170
171void os_panic (void) __attribute__ ((weak));
172
Dave Barachc3799992016-08-15 11:12:27 -0400173void
174os_panic (void)
175{
176 abort ();
177}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700178
179void os_exit (int) __attribute__ ((weak));
180
Dave Barachc3799992016-08-15 11:12:27 -0400181void
182os_exit (int code)
183{
184 exit (code);
185}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700186
187void os_puts (u8 * string, uword string_length, uword is_error)
188 __attribute__ ((weak));
189
Dave Barachc3799992016-08-15 11:12:27 -0400190void
191os_puts (u8 * string, uword string_length, uword is_error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700192{
Damjan Marionf55f9b82017-05-10 21:06:28 +0200193 int cpu = os_get_thread_index ();
194 int nthreads = os_get_nthreads ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 char buf[64];
196 int fd = is_error ? 2 : 1;
197 struct iovec iovs[2];
198 int n_iovs = 0;
199
Damjan Marionf55f9b82017-05-10 21:06:28 +0200200 if (nthreads > 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201 {
Dave Barachc3799992016-08-15 11:12:27 -0400202 snprintf (buf, sizeof (buf), "%d: ", cpu);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203
204 iovs[n_iovs].iov_base = buf;
205 iovs[n_iovs].iov_len = strlen (buf);
206 n_iovs++;
207 }
208
209 iovs[n_iovs].iov_base = string;
210 iovs[n_iovs].iov_len = string_length;
211 n_iovs++;
212
213 if (writev (fd, iovs, n_iovs) < 0)
214 ;
215}
216
217void os_out_of_memory (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400218void
219os_out_of_memory (void)
220{
221 os_panic ();
222}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223
Damjan Marionf55f9b82017-05-10 21:06:28 +0200224uword os_get_nthreads (void) __attribute__ ((weak));
Dave Barachc3799992016-08-15 11:12:27 -0400225uword
Damjan Marionf55f9b82017-05-10 21:06:28 +0200226os_get_nthreads (void)
Dave Barachc3799992016-08-15 11:12:27 -0400227{
228 return 1;
229}
230
231/*
232 * fd.io coding-style-patch-verification: ON
233 *
234 * Local Variables:
235 * eval: (c-set-style "gnu")
236 * End:
237 */