Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/coreutils/head.c


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/coreutils/head.c

    r3232 r3621  
    1212/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
    1313
     14//kbuild:lib-$(CONFIG_HEAD) += head.o
     15
    1416//usage:#define head_trivial_usage
    1517//usage:       "[OPTIONS] [FILE]..."
     
    1921//usage:     "\n    -n N[kbm]   Print first N lines"
    2022//usage:    IF_FEATURE_FANCY_HEAD(
    21 //usage:     "\n    -c N[kbm]   Print first N bytes"
     23//usage:     "\n    -n -N[kbm]  Print all except N last lines"
     24//usage:     "\n    -c [-]N[kbm]    Print first N bytes"
    2225//usage:     "\n    -q      Never print headers"
    2326//usage:     "\n    -v      Always print headers"
     
    3538/* This is a NOEXEC applet. Be very careful! */
    3639
     40#if !ENABLE_FEATURE_FANCY_HEAD
     41# define print_first_N(fp,count,bytes) print_first_N(fp,count)
     42#endif
     43static void
     44print_first_N(FILE *fp, unsigned long count, bool count_bytes)
     45{
     46#if !ENABLE_FEATURE_FANCY_HEAD
     47    const int count_bytes = 0;
     48#endif
     49    while (count) {
     50        int c = getc(fp);
     51        if (c == EOF)
     52            break;
     53        if (count_bytes || (c == '\n'))
     54            --count;
     55        putchar(c);
     56    }
     57}
     58
     59#if ENABLE_FEATURE_FANCY_HEAD
     60static void
     61print_except_N_last_bytes(FILE *fp, unsigned count)
     62{
     63    unsigned char *circle = xmalloc(++count);
     64    unsigned head = 0;
     65    for(;;) {
     66        int c;
     67        c = getc(fp);
     68        if (c == EOF)
     69            goto ret;
     70        circle[head++] = c;
     71        if (head == count)
     72            break;
     73    }
     74    for (;;) {
     75        int c;
     76        if (head == count)
     77            head = 0;
     78        putchar(circle[head]);
     79        c = getc(fp);
     80        if (c == EOF)
     81            goto ret;
     82        circle[head] = c;
     83        head++;
     84    }
     85 ret:
     86    free(circle);
     87}
     88
     89static void
     90print_except_N_last_lines(FILE *fp, unsigned count)
     91{
     92    char **circle = xzalloc((++count) * sizeof(circle[0]));
     93    unsigned head = 0;
     94    for(;;) {
     95        char *c;
     96        c = xmalloc_fgets(fp);
     97        if (!c)
     98            goto ret;
     99        circle[head++] = c;
     100        if (head == count)
     101            break;
     102    }
     103    for (;;) {
     104        char *c;
     105        if (head == count)
     106            head = 0;
     107        fputs(circle[head], stdout);
     108        c = xmalloc_fgets(fp);
     109        if (!c)
     110            goto ret;
     111        free(circle[head]);
     112        circle[head++] = c;
     113    }
     114 ret:
     115    head = 0;
     116    for(;;) {
     117        free(circle[head++]);
     118        if (head == count)
     119            break;
     120    }
     121    free(circle);
     122}
     123#else
     124/* Must never be called */
     125void print_except_N_last_bytes(FILE *fp, unsigned count);
     126void print_except_N_last_lines(FILE *fp, unsigned count);
     127#endif
     128
     129#if !ENABLE_FEATURE_FANCY_HEAD
     130# define eat_num(negative_N,p) eat_num(p)
     131#endif
     132static unsigned long
     133eat_num(bool *negative_N, const char *p)
     134{
     135#if ENABLE_FEATURE_FANCY_HEAD
     136    if (*p == '-') {
     137        *negative_N = 1;
     138        p++;
     139    }
     140#endif
     141    return xatoul_sfx(p, bkm_suffixes);
     142}
     143
    37144static const char head_opts[] ALIGN1 =
    38145    "n:"
     
    42149    ;
    43150
    44 static const struct suffix_mult head_suffixes[] = {
    45     { "b", 512 },
    46     { "k", 1024 },
    47     { "m", 1024*1024 },
    48     { "", 0 }
    49 };
    50 
    51151#define header_fmt_str "\n==> %s <==\n"
    52152
     
    55155{
    56156    unsigned long count = 10;
    57     unsigned long i;
    58 #if ENABLE_FEATURE_FANCY_HEAD
    59     int count_bytes = 0;
     157#if ENABLE_FEATURE_FANCY_HEAD
    60158    int header_threshhold = 1;
     159    bool count_bytes = 0;
     160    bool negative_N = 0;
     161#else
     162# define header_threshhold 1
     163# define count_bytes       0
     164# define negative_N        0
    61165#endif
    62166    FILE *fp;
     
    64168    char *p;
    65169    int opt;
    66     int c;
    67170    int retval = EXIT_SUCCESS;
    68171
     
    74177        --argc;
    75178        ++argv;
    76         p = (*argv) + 1;
     179        p = argv[0] + 1;
    77180        goto GET_COUNT;
    78181    }
     
    98201 GET_COUNT:
    99202#endif
    100             count = xatoul_sfx(p, head_suffixes);
     203            count = eat_num(&negative_N, p);
    101204            break;
    102205        default:
     
    111214
    112215    fmt = header_fmt_str + 1;
    113 #if ENABLE_FEATURE_FANCY_HEAD
    114216    if (argc <= header_threshhold) {
     217#if ENABLE_FEATURE_FANCY_HEAD
    115218        header_threshhold = 0;
    116     }
    117219#else
    118     if (argc <= 1) {
    119220        fmt += 11; /* "" */
    120     }
    121     /* Now define some things here to avoid #ifdefs in the code below.
    122      * These should optimize out of the if conditions below. */
    123 #define header_threshhold   1
    124 #define count_bytes         0
    125 #endif
     221#endif
     222    }
     223    if (negative_N) {
     224        if (count >= INT_MAX / sizeof(char*))
     225            bb_error_msg("count is too big: %lu", count);
     226    }
    126227
    127228    do {
     
    134235                printf(fmt, *argv);
    135236            }
    136             i = count;
    137             while (i && ((c = getc(fp)) != EOF)) {
    138                 if (count_bytes || (c == '\n')) {
    139                     --i;
     237            if (negative_N) {
     238                if (count_bytes) {
     239                    print_except_N_last_bytes(fp, count);
     240                } else {
     241                    print_except_N_last_lines(fp, count);
    140242                }
    141                 putchar(c);
    142             }
     243            } else {
     244                print_first_N(fp, count, count_bytes);
     245            }
     246            die_if_ferror_stdout();
    143247            if (fclose_if_not_stdin(fp)) {
    144248                bb_simple_perror_msg(*argv);
    145249                retval = EXIT_FAILURE;
    146250            }
    147             die_if_ferror_stdout();
    148251        } else {
    149252            retval = EXIT_FAILURE;
Note: See TracChangeset for help on using the changeset viewer.