1
1
/*
2
2
* The PCI Utilities -- Show Bus Tree
3
3
*
4
- * Copyright (c) 1997--2018 Martin Mares <[email protected] >
4
+ * Copyright (c) 1997--2020 Martin Mares <[email protected] >
5
5
*
6
6
* Can be freely distributed and used under the terms of the GNU GPL.
7
7
*/
8
8
9
+ #include <stdarg.h>
9
10
#include <stdio.h>
10
11
#include <string.h>
11
12
@@ -154,29 +155,54 @@ print_it(char *line, char *p)
154
155
155
156
static void show_tree_bridge (struct bridge * , char * , char * );
156
157
158
+ #define LINE_BUF_SIZE 1024
159
+
160
+ static char * FORMAT_CHECK (printf , 3 , 4 )
161
+ tree_printf (char * line , char * p , char * fmt , ...)
162
+ {
163
+ va_list args ;
164
+ char * end = line + LINE_BUF_SIZE - 2 ;
165
+
166
+ if (p >= end )
167
+ return p ;
168
+
169
+ va_start (args , fmt );
170
+ int res = vsnprintf (p , end - p , fmt , args );
171
+ if (res < 0 )
172
+ {
173
+ /* Ancient C libraries return -1 on overflow */
174
+ p += strlen (p );
175
+ }
176
+ else
177
+ p += res ;
178
+
179
+ va_end (args );
180
+ return p ;
181
+ }
182
+
157
183
static void
158
184
show_tree_dev (struct device * d , char * line , char * p )
159
185
{
160
186
struct pci_dev * q = d -> dev ;
161
187
struct bridge * b ;
162
188
char namebuf [256 ];
163
189
164
- p += sprintf ( p , "%02x.%x" , q -> dev , q -> func );
190
+ p = tree_printf ( line , p , "%02x.%x" , q -> dev , q -> func );
165
191
for (b = & host_bridge ; b ; b = b -> chain )
166
192
if (b -> br_dev == d )
167
193
{
168
194
if (b -> secondary == b -> subordinate )
169
- p += sprintf ( p , "-[%02x]-" , b -> secondary );
195
+ p = tree_printf ( line , p , "-[%02x]-" , b -> secondary );
170
196
else
171
- p += sprintf ( p , "-[%02x-%02x]-" , b -> secondary , b -> subordinate );
197
+ p = tree_printf ( line , p , "-[%02x-%02x]-" , b -> secondary , b -> subordinate );
172
198
show_tree_bridge (b , line , p );
173
199
return ;
174
200
}
175
201
if (verbose )
176
- p += sprintf ( p , " %s" ,
177
- pci_lookup_name (pacc , namebuf , sizeof (namebuf ),
178
- PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE ,
179
- q -> vendor_id , q -> device_id ));
202
+ p = tree_printf ( line , p , " %s" ,
203
+ pci_lookup_name (pacc , namebuf , sizeof (namebuf ),
204
+ PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE ,
205
+ q -> vendor_id , q -> device_id ));
180
206
print_it (line , p );
181
207
}
182
208
@@ -187,23 +213,20 @@ show_tree_bus(struct bus *b, char *line, char *p)
187
213
print_it (line , p );
188
214
else if (!b -> first_dev -> bus_next )
189
215
{
190
- * p ++ = '-' ;
191
- * p ++ = '-' ;
216
+ p = tree_printf (line , p , "--" );
192
217
show_tree_dev (b -> first_dev , line , p );
193
218
}
194
219
else
195
220
{
196
221
struct device * d = b -> first_dev ;
197
222
while (d -> bus_next )
198
223
{
199
- p [0 ] = '+' ;
200
- p [1 ] = '-' ;
201
- show_tree_dev (d , line , p + 2 );
224
+ char * p2 = tree_printf (line , p , "+-" );
225
+ show_tree_dev (d , line , p2 );
202
226
d = d -> bus_next ;
203
227
}
204
- p [0 ] = '\\' ;
205
- p [1 ] = '-' ;
206
- show_tree_dev (d , line , p + 2 );
228
+ p = tree_printf (line , p , "\\-" );
229
+ show_tree_dev (d , line , p );
207
230
}
208
231
}
209
232
@@ -214,7 +237,7 @@ show_tree_bridge(struct bridge *b, char *line, char *p)
214
237
if (!b -> first_bus -> sibling )
215
238
{
216
239
if (b == & host_bridge )
217
- p += sprintf ( p , "[%04x:%02x]-" , b -> domain , b -> first_bus -> number );
240
+ p = tree_printf ( line , p , "[%04x:%02x]-" , b -> domain , b -> first_bus -> number );
218
241
show_tree_bus (b -> first_bus , line , p );
219
242
}
220
243
else
@@ -224,19 +247,19 @@ show_tree_bridge(struct bridge *b, char *line, char *p)
224
247
225
248
while (u -> sibling )
226
249
{
227
- k = p + sprintf ( p , "+-[%04x:%02x]-" , u -> domain , u -> number );
250
+ k = tree_printf ( line , p , "+-[%04x:%02x]-" , u -> domain , u -> number );
228
251
show_tree_bus (u , line , k );
229
252
u = u -> sibling ;
230
253
}
231
- k = p + sprintf ( p , "\\-[%04x:%02x]-" , u -> domain , u -> number );
254
+ k = tree_printf ( line , p , "\\-[%04x:%02x]-" , u -> domain , u -> number );
232
255
show_tree_bus (u , line , k );
233
256
}
234
257
}
235
258
236
259
void
237
260
show_forest (struct pci_filter * filter )
238
261
{
239
- char line [256 ];
262
+ char line [LINE_BUF_SIZE ];
240
263
if (filter == NULL )
241
264
show_tree_bridge (& host_bridge , line , line );
242
265
else
@@ -248,7 +271,7 @@ show_forest(struct pci_filter *filter)
248
271
{
249
272
struct pci_dev * d = b -> br_dev -> dev ;
250
273
char * p = line ;
251
- p += sprintf (line , "%04x:%02x:" , d -> domain_16 , d -> bus );
274
+ p = tree_printf (line , p , "%04x:%02x:" , d -> domain_16 , d -> bus );
252
275
show_tree_dev (b -> br_dev , line , p );
253
276
}
254
277
}
0 commit comments