aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-06-07 09:04:40 +0100
committerRon Yorston <rmy@pobox.com>2021-06-07 11:30:52 +0100
commitac0170d5c908343ed3fe6a222bfda2689909b27f (patch)
tree33eb6948b3e7609b3e1a1d6d92acecbccf1ab71a
parent9ba9333e913c617e995b2e1d37dc738b77304158 (diff)
downloadbusybox-w32-ac0170d5c908343ed3fe6a222bfda2689909b27f.tar.gz
busybox-w32-ac0170d5c908343ed3fe6a222bfda2689909b27f.tar.bz2
busybox-w32-ac0170d5c908343ed3fe6a222bfda2689909b27f.zip
libbb: allow dumping of /dev/fd file descriptors
xxd and hexdump use library code to dump binary data. This code uses freopen(3) which can't handle /dev/fd file descriptors. Rewrite it using fopen(3).
-rw-r--r--libbb/dump.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/libbb/dump.c b/libbb/dump.c
index fb7849e7d..196ccfe65 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -37,6 +37,9 @@ typedef struct priv_dumper_t {
37 off_t address; /* address/offset in stream */ 37 off_t address; /* address/offset in stream */
38 int blocksize; 38 int blocksize;
39 smallint exitval; /* final exit value */ 39 smallint exitval; /* final exit value */
40#if ENABLE_PLATFORM_MINGW32
41 FILE *fd;
42#endif
40 43
41 /* former statics */ 44 /* former statics */
42 smallint next__done; 45 smallint next__done;
@@ -58,6 +61,9 @@ dumper_t* FAST_FUNC alloc_dumper(void)
58 dumper->pub.dump_length = -1; 61 dumper->pub.dump_length = -1;
59 dumper->pub.dump_vflag = FIRST; 62 dumper->pub.dump_vflag = FIRST;
60 dumper->get__ateof = 1; 63 dumper->get__ateof = 1;
64#if ENABLE_PLATFORM_MINGW32
65 dumper->fd = stdin;
66#endif
61 return &dumper->pub; 67 return &dumper->pub;
62} 68}
63 69
@@ -328,7 +334,11 @@ static void do_skip(priv_dumper_t *dumper, const char *fname)
328{ 334{
329 struct stat sbuf; 335 struct stat sbuf;
330 336
337#if ENABLE_PLATFORM_MINGW32
338 xfstat(fileno(dumper->fd), &sbuf, fname);
339#else
331 xfstat(STDIN_FILENO, &sbuf, fname); 340 xfstat(STDIN_FILENO, &sbuf, fname);
341#endif
332 if (S_ISREG(sbuf.st_mode) 342 if (S_ISREG(sbuf.st_mode)
333 && dumper->pub.dump_skip >= sbuf.st_size 343 && dumper->pub.dump_skip >= sbuf.st_size
334 ) { 344 ) {
@@ -337,7 +347,11 @@ static void do_skip(priv_dumper_t *dumper, const char *fname)
337 dumper->address += sbuf.st_size; 347 dumper->address += sbuf.st_size;
338 return; 348 return;
339 } 349 }
350#if ENABLE_PLATFORM_MINGW32
351 if (fseeko(dumper->fd, dumper->pub.dump_skip, SEEK_SET)) {
352#else
340 if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { 353 if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) {
354#endif
341 bb_simple_perror_msg_and_die(fname); 355 bb_simple_perror_msg_and_die(fname);
342 } 356 }
343 dumper->address += dumper->pub.dump_skip; 357 dumper->address += dumper->pub.dump_skip;
@@ -353,12 +367,22 @@ static NOINLINE int next(priv_dumper_t *dumper)
353 if (fname) { 367 if (fname) {
354 dumper->argv++; 368 dumper->argv++;
355 if (NOT_LONE_DASH(fname)) { 369 if (NOT_LONE_DASH(fname)) {
370#if ENABLE_PLATFORM_MINGW32
371 dumper->fd = fopen(fname, "r");
372 if (!dumper->fd) {
373#else
356 if (!freopen(fname, "r", stdin)) { 374 if (!freopen(fname, "r", stdin)) {
375#endif
357 bb_simple_perror_msg(fname); 376 bb_simple_perror_msg(fname);
358 dumper->exitval = 1; 377 dumper->exitval = 1;
359 continue; 378 continue;
360 } 379 }
361 } 380 }
381#if ENABLE_PLATFORM_MINGW32
382 else {
383 dumper->fd = stdin;
384 }
385#endif
362 } else { 386 } else {
363 if (dumper->next__done) 387 if (dumper->next__done)
364 return 0; /* no next file */ 388 return 0; /* no next file */
@@ -413,13 +437,25 @@ static unsigned char *get(priv_dumper_t *dumper)
413 dumper->eaddress = dumper->address + nread; 437 dumper->eaddress = dumper->address + nread;
414 return dumper->get__curp; 438 return dumper->get__curp;
415 } 439 }
440#if ENABLE_PLATFORM_MINGW32
441 n = fread(dumper->get__curp + nread, sizeof(unsigned char),
442 dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), dumper->fd);
443#else
416 n = fread(dumper->get__curp + nread, sizeof(unsigned char), 444 n = fread(dumper->get__curp + nread, sizeof(unsigned char),
417 dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin); 445 dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin);
446#endif
418 if (n == 0) { 447 if (n == 0) {
448#if ENABLE_PLATFORM_MINGW32
449 if (ferror(dumper->fd)) {
450#else
419 if (ferror(stdin)) { 451 if (ferror(stdin)) {
452#endif
420 bb_simple_perror_msg(dumper->argv[-1]); 453 bb_simple_perror_msg(dumper->argv[-1]);
421 } 454 }
422 dumper->get__ateof = 1; 455 dumper->get__ateof = 1;
456#if ENABLE_PLATFORM_MINGW32
457 fclose(dumper->fd);
458#endif
423 continue; 459 continue;
424 } 460 }
425 dumper->get__ateof = 0; 461 dumper->get__ateof = 0;