diff options
Diffstat (limited to '')
-rw-r--r-- | libbb/dump.c | 91 |
1 files changed, 71 insertions, 20 deletions
diff --git a/libbb/dump.c b/libbb/dump.c index ac5d47d9e..3dc53d55f 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -36,6 +36,9 @@ typedef struct priv_dumper_t { | |||
36 | off_t eaddress; /* end address */ | 36 | off_t eaddress; /* end address */ |
37 | int blocksize; | 37 | int blocksize; |
38 | smallint exitval; /* final exit value */ | 38 | smallint exitval; /* final exit value */ |
39 | #if ENABLE_PLATFORM_MINGW32 | ||
40 | FILE *fd; | ||
41 | #endif | ||
39 | 42 | ||
40 | /* former statics */ | 43 | /* former statics */ |
41 | smallint next__done; | 44 | smallint next__done; |
@@ -59,6 +62,9 @@ dumper_t* FAST_FUNC alloc_dumper(void) | |||
59 | dumper->pub.dump_length = -1; | 62 | dumper->pub.dump_length = -1; |
60 | dumper->pub.dump_vflag = FIRST; | 63 | dumper->pub.dump_vflag = FIRST; |
61 | dumper->get__ateof = 1; | 64 | dumper->get__ateof = 1; |
65 | #if ENABLE_PLATFORM_MINGW32 | ||
66 | dumper->fd = stdin; | ||
67 | #endif | ||
62 | return &dumper->pub; | 68 | return &dumper->pub; |
63 | } | 69 | } |
64 | 70 | ||
@@ -335,7 +341,11 @@ static void do_skip(priv_dumper_t *dumper, const char *fname) | |||
335 | { | 341 | { |
336 | struct stat sbuf; | 342 | struct stat sbuf; |
337 | 343 | ||
344 | #if ENABLE_PLATFORM_MINGW32 | ||
345 | xfstat(fileno(dumper->fd), &sbuf, fname); | ||
346 | #else | ||
338 | xfstat(STDIN_FILENO, &sbuf, fname); | 347 | xfstat(STDIN_FILENO, &sbuf, fname); |
348 | #endif | ||
339 | if (S_ISREG(sbuf.st_mode) | 349 | if (S_ISREG(sbuf.st_mode) |
340 | && dumper->pub.dump_skip >= sbuf.st_size | 350 | && dumper->pub.dump_skip >= sbuf.st_size |
341 | ) { | 351 | ) { |
@@ -344,7 +354,11 @@ static void do_skip(priv_dumper_t *dumper, const char *fname) | |||
344 | dumper->pub.address += sbuf.st_size; | 354 | dumper->pub.address += sbuf.st_size; |
345 | return; | 355 | return; |
346 | } | 356 | } |
357 | #if ENABLE_PLATFORM_MINGW32 | ||
358 | if (fseeko(dumper->fd, dumper->pub.dump_skip, SEEK_SET)) { | ||
359 | #else | ||
347 | if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { | 360 | if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { |
361 | #endif | ||
348 | bb_simple_perror_msg_and_die(fname); | 362 | bb_simple_perror_msg_and_die(fname); |
349 | } | 363 | } |
350 | dumper->pub.address += dumper->pub.dump_skip; | 364 | dumper->pub.address += dumper->pub.dump_skip; |
@@ -360,13 +374,23 @@ static NOINLINE int next(priv_dumper_t *dumper) | |||
360 | if (fname) { | 374 | if (fname) { |
361 | dumper->argv++; | 375 | dumper->argv++; |
362 | if (NOT_LONE_DASH(fname)) { | 376 | if (NOT_LONE_DASH(fname)) { |
377 | #if ENABLE_PLATFORM_MINGW32 | ||
378 | dumper->fd = fopen(fname, "r"); | ||
379 | if (!dumper->fd) { | ||
380 | #else | ||
363 | if (!freopen(fname, "r", stdin)) { | 381 | if (!freopen(fname, "r", stdin)) { |
382 | #endif | ||
364 | bb_simple_perror_msg(fname); | 383 | bb_simple_perror_msg(fname); |
365 | dumper->exitval = 1; | 384 | dumper->exitval = 1; |
366 | dumper->next__done = 1; | 385 | dumper->next__done = 1; |
367 | continue; | 386 | continue; |
368 | } | 387 | } |
369 | } | 388 | } |
389 | #if ENABLE_PLATFORM_MINGW32 | ||
390 | else { | ||
391 | dumper->fd = stdin; | ||
392 | } | ||
393 | #endif | ||
370 | } else { | 394 | } else { |
371 | if (dumper->next__done) | 395 | if (dumper->next__done) |
372 | return 0; /* no next file */ | 396 | return 0; /* no next file */ |
@@ -421,13 +445,25 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
421 | dumper->eaddress = dumper->pub.address + nread; | 445 | dumper->eaddress = dumper->pub.address + nread; |
422 | return dumper->get__curp; | 446 | return dumper->get__curp; |
423 | } | 447 | } |
448 | #if ENABLE_PLATFORM_MINGW32 | ||
449 | n = fread(dumper->get__curp + nread, sizeof(unsigned char), | ||
450 | dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), dumper->fd); | ||
451 | #else | ||
424 | n = fread(dumper->get__curp + nread, sizeof(unsigned char), | 452 | n = fread(dumper->get__curp + nread, sizeof(unsigned char), |
425 | dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin); | 453 | dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin); |
454 | #endif | ||
426 | if (n == 0) { | 455 | if (n == 0) { |
456 | #if ENABLE_PLATFORM_MINGW32 | ||
457 | if (ferror(dumper->fd)) { | ||
458 | #else | ||
427 | if (ferror(stdin)) { | 459 | if (ferror(stdin)) { |
460 | #endif | ||
428 | bb_simple_perror_msg(dumper->argv[-1]); | 461 | bb_simple_perror_msg(dumper->argv[-1]); |
429 | } | 462 | } |
430 | dumper->get__ateof = 1; | 463 | dumper->get__ateof = 1; |
464 | #if ENABLE_PLATFORM_MINGW32 | ||
465 | fclose(dumper->fd); | ||
466 | #endif | ||
431 | continue; | 467 | continue; |
432 | } | 468 | } |
433 | dumper->get__ateof = 0; | 469 | dumper->get__ateof = 0; |
@@ -478,37 +514,52 @@ static void bpad(PR *pr) | |||
478 | continue; | 514 | continue; |
479 | } | 515 | } |
480 | 516 | ||
481 | static const char conv_str[] ALIGN1 = | ||
482 | "\0" "\\""0""\0" | ||
483 | "\007""\\""a""\0" | ||
484 | "\b" "\\""b""\0" | ||
485 | "\f" "\\""f""\0" | ||
486 | "\n" "\\""n""\0" | ||
487 | "\r" "\\""r""\0" | ||
488 | "\t" "\\""t""\0" | ||
489 | "\v" "\\""v""\0" | ||
490 | ; | ||
491 | |||
492 | static void conv_c(PR *pr, unsigned char *p) | 517 | static void conv_c(PR *pr, unsigned char *p) |
493 | { | 518 | { |
494 | const char *str = conv_str; | 519 | const char *str; |
495 | 520 | unsigned char ch; | |
496 | do { | 521 | |
497 | if (*p == *str) { | 522 | ch = *p; |
498 | ++str; | 523 | if (ch == 0 || (ch -= 6, (signed char)ch > 0 && ch <= 7)) { |
499 | goto strpr; /* map e.g. '\n' to "\\n" */ | 524 | /* map chars 0,7..13 to "\0","\{a,b,t,n,v,f,r}" */ |
500 | } | 525 | str = c_escape_conv_str00 + 3 * ch; |
501 | str += 4; | 526 | goto strpr; |
502 | } while (*str); | 527 | } |
503 | 528 | ||
504 | if (isprint_asciionly(*p)) { | 529 | if (isprint_asciionly(*p)) { |
505 | *pr->cchar = 'c'; | 530 | *pr->cchar = 'c'; |
506 | printf(pr->fmt, *p); | 531 | printf(pr->fmt, *p); |
507 | } else { | 532 | } else { |
533 | #if defined(__i386__) || defined(__x86_64__) | ||
534 | /* Abuse partial register operations */ | ||
535 | uint32_t buf; | ||
536 | unsigned n = *p; | ||
537 | asm ( //00000000 00000000 00000000 aabbbccc | ||
538 | "\n shll $10,%%eax" //00000000 000000aa bbbccc00 00000000 | ||
539 | "\n shrw $5,%%ax" //00000000 000000aa 00000bbb ccc00000 | ||
540 | "\n shrb $5,%%al" //00000000 000000aa 00000bbb 00000ccc | ||
541 | "\n shll $8,%%eax" //000000aa 00000bbb 00000ccc 00000000 | ||
542 | "\n bswapl %%eax" //00000000 00000ccc 00000bbb 000000aa | ||
543 | "\n addl $0x303030,%%eax" | ||
544 | "\n" : "=a" (n) | ||
545 | : "0" (n) | ||
546 | ); | ||
547 | buf = n; | ||
548 | str = (void*)&buf; | ||
549 | #elif 1 | ||
508 | char buf[4]; | 550 | char buf[4]; |
509 | /* gcc-8.0.1 needs lots of casts to shut up */ | 551 | /* gcc-8.0.1 needs lots of casts to shut up */ |
510 | sprintf(buf, "%03o", (unsigned)(uint8_t)*p); | 552 | sprintf(buf, "%03o", (unsigned)(uint8_t)*p); |
511 | str = buf; | 553 | str = buf; |
554 | #else // use faster version? +20 bytes of code relative to sprintf() method | ||
555 | char buf[4]; | ||
556 | buf[3] = '\0'; | ||
557 | ch = *p; | ||
558 | buf[2] = '0' + (ch & 7); ch >>= 3; | ||
559 | buf[1] = '0' + (ch & 7); ch >>= 3; | ||
560 | buf[0] = '0' + ch; | ||
561 | str = buf; | ||
562 | #endif | ||
512 | strpr: | 563 | strpr: |
513 | *pr->cchar = 's'; | 564 | *pr->cchar = 's'; |
514 | printf(pr->fmt, str); | 565 | printf(pr->fmt, str); |