FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
unix-misc.c
Go to the documentation of this file.
1 /*
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 
48 __thread uword __os_thread_index = 0;
49 __thread uword __os_numa_index = 0;
50 
52 clib_file_n_bytes (char *file, uword * result)
53 {
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 
68 clib_file_read_contents (char *file, u8 * result, uword n_bytes)
69 {
70  int fd = -1;
71  uword n_done, n_left;
72  clib_error_t *error = 0;
73  u8 *v = result;
74 
75  if ((fd = open (file, 0)) < 0)
76  return clib_error_return_unix (0, "open `%s'", file);
77 
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  {
99  error =
101  " `%s' expected to read %wd bytes; read only %wd",
102  file, n_bytes, n_bytes - n_left);
103  goto done;
104  }
105 
106 done:
107  close (fd);
108  return error;
109 }
110 
111 clib_error_t *
112 clib_file_contents (char *file, u8 ** result)
113 {
114  uword n_bytes;
115  clib_error_t *error = 0;
116  u8 *v;
117 
118  if ((error = clib_file_n_bytes (file, &n_bytes)))
119  return error;
120 
121  v = 0;
122  vec_resize (v, n_bytes);
123 
124  error = clib_file_read_contents (file, v, n_bytes);
125 
126  if (error)
127  vec_free (v);
128  else
129  *result = v;
130 
131  return error;
132 }
133 
134 clib_error_t *
135 unix_proc_file_contents (char *file, u8 ** result)
136 {
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 
147  vec_validate (rv, 4095);
148  pos = 0;
149  while (1)
150  {
151  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  }
158 
159  if (bytes == 0)
160  {
161  _vec_len (rv) = pos;
162  break;
163  }
164  pos += bytes;
165  vec_validate (rv, pos + 4095);
166  }
167  *result = rv;
168  close (fd);
169  return 0;
170 }
171 
172 void os_panic (void) __attribute__ ((weak));
173 
174 void
175 os_panic (void)
176 {
177  abort ();
178 }
179 
180 void os_exit (int) __attribute__ ((weak));
181 
182 void
183 os_exit (int code)
184 {
185  exit (code);
186 }
187 
188 void os_puts (u8 * string, uword string_length, uword is_error)
189  __attribute__ ((weak));
190 
191 void
192 os_puts (u8 * string, uword string_length, uword is_error)
193 {
194  int cpu = os_get_thread_index ();
195  int nthreads = os_get_nthreads ();
196  char buf[64];
197  int fd = is_error ? 2 : 1;
198  struct iovec iovs[2];
199  int n_iovs = 0;
200 
201  if (nthreads > 1)
202  {
203  snprintf (buf, sizeof (buf), "%d: ", cpu);
204 
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 
218 void os_out_of_memory (void) __attribute__ ((weak));
219 void
221 {
222  os_panic ();
223 }
224 
225 uword os_get_nthreads (void) __attribute__ ((weak));
226 uword
228 {
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  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
unsigned char u8
Definition: types.h:56
clib_error_t * clib_file_contents(char *file, u8 **result)
Definition: unix-misc.c:112
#define clib_error_return(e, args...)
Definition: error.h:99
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:281
void os_exit(int)
Definition: unix-misc.c:183
#define clib_error_return_unix(e, args...)
Definition: error.h:102
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
clib_error_t * clib_file_read_contents(char *file, u8 *result, uword n_bytes)
Definition: unix-misc.c:68
uword os_get_nthreads(void)
Definition: unix-misc.c:227
void os_puts(u8 *string, uword string_length, uword is_error)
Definition: unix-misc.c:192
u64 uword
Definition: types.h:112
clib_error_t * unix_proc_file_contents(char *file, u8 **result)
Definition: unix-misc.c:135
static_always_inline uword os_get_thread_index(void)
Definition: os.h:63
clib_error_t * clib_file_n_bytes(char *file, uword *result)
Definition: unix-misc.c:52
void os_panic(void)
Definition: unix-misc.c:175
void os_out_of_memory(void)
Definition: unix-misc.c:220