[BACK]Return to engine.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Annotation of src/usr.bin/systat/engine.c, Revision 1.30

1.30    ! tb          1: /* $OpenBSD: engine.c,v 1.29 2021/07/02 15:34:16 millert Exp $  */
1.1       canacar     2: /*
                      3:  * Copyright (c) 2001, 2007 Can Erkin Acar <canacar@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17:
                     18:
1.10      chl        19: #include <sys/ioctl.h>
1.1       canacar    20: #include <sys/types.h>
                     21: #include <sys/queue.h>
                     22:
                     23: #include <ctype.h>
                     24: #include <curses.h>
                     25: #include <signal.h>
                     26: #include <stdlib.h>
                     27: #include <string.h>
1.8       canacar    28: #include <term.h>
1.1       canacar    29: #include <unistd.h>
1.29      millert    30: #include <math.h>
1.12      lum        31: #include <err.h>
1.1       canacar    32:
1.8       canacar    33: /* XXX These are defined in term.h and conflict with our variable names */
                     34: #ifdef columns
                     35: #undef columns
                     36: #endif
                     37:
                     38: #ifdef lines
                     39: #undef lines
                     40: #endif
                     41:
1.1       canacar    42: #include "engine.h"
                     43:
1.18      deraadt    44: #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
1.1       canacar    45:
                     46: /* circular linked list of views */
1.17      krw        47: TAILQ_HEAD(view_list, view_ent) view_head =
                     48:                                  TAILQ_HEAD_INITIALIZER(view_head);
1.1       canacar    49: struct view_ent {
                     50:        field_view *view;
1.17      krw        51:        TAILQ_ENTRY(view_ent) entries;
1.1       canacar    52: };
                     53:
1.29      millert    54: static struct timespec ts_delay = { 5, 0 };
                     55: static struct itimerval it_delay = { { 0, 0 }, { 5, 0 } };
                     56:
1.1       canacar    57: int dispstart = 0;
1.25      martijn    58: int humanreadable = 0;
1.1       canacar    59: int interactive = 1;
1.15      reyk       60: int averageonly = 0;
1.1       canacar    61: int maxprint = 0;
                     62: int paused = 0;
                     63: int rawmode = 0;
                     64: int rawwidth = DEFAULT_WIDTH;
                     65: int sortdir = 1;
                     66: int columns, lines;
                     67: u_int32_t num_disp = 0;
                     68: int max_disp = -1;
                     69:
                     70: volatile sig_atomic_t gotsig_close = 0;
                     71: volatile sig_atomic_t gotsig_resize = 0;
                     72: volatile sig_atomic_t gotsig_alarm = 0;
                     73: int need_update = 0;
                     74: int need_sort = 0;
1.14      mpf        75: int separate_thousands = 0;
1.1       canacar    76:
                     77: SCREEN *screen;
                     78:
                     79: field_view *curr_view = NULL;
                     80: struct view_ent *curr_view_ent = NULL;
                     81: struct view_manager *curr_mgr = NULL;
                     82:
                     83: int curr_line = 0;
                     84: int home_line = 0;
                     85:
                     86: /* line buffer for raw mode */
                     87: char linebuf[MAX_LINE_BUF];
                     88: int linepos = 0;
                     89:
                     90: /* temp storage for state printing */
                     91: char tmp_buf[MAX_LINE_BUF];
                     92:
                     93: char cmdbuf[MAX_LINE_BUF];
                     94: int cmd_len = -1;
                     95: struct command *curr_cmd = NULL;
                     96: char *curr_message = NULL;
1.28      martijn    97: enum message_mode message_mode = MESSAGE_NONE;
                     98: int message_cont = 1;
1.1       canacar    99:
                    100: void print_cmdline(void);
                    101:
                    102:
                    103: /* screen output functions */
                    104:
                    105: char * tb_ptr = NULL;
                    106: int tb_len = 0;
                    107:
                    108: void
                    109: tb_start(void)
                    110: {
                    111:        tb_ptr = tmp_buf;
                    112:        tb_len = sizeof(tmp_buf);
                    113:        tb_ptr[0] = '\0';
                    114: }
                    115:
                    116: void
                    117: tb_end(void)
                    118: {
                    119:        tb_ptr = NULL;
                    120:        tb_len = 0;
                    121: }
                    122:
                    123: int
                    124: tbprintf(char *format, ...)
                    125: {
                    126:        int len;
                    127:        va_list arg;
                    128:
                    129:        if (tb_ptr == NULL || tb_len <= 0)
                    130:                return 0;
                    131:
                    132:        va_start(arg, format);
1.20      deraadt   133:        len = vsnprintf(tb_ptr, tb_len, format, arg);
1.1       canacar   134:        va_end(arg);
1.26      jasper    135:
1.1       canacar   136:        if (len > tb_len)
                    137:                tb_end();
                    138:        else if (len > 0) {
                    139:                tb_ptr += len;
                    140:                tb_len -= len;
                    141:        }
1.14      mpf       142:
                    143:        return len;
                    144: }
                    145:
                    146: int
                    147: tbprintft(char *format, ...)
                    148: {
                    149:        int len;
                    150:        va_list arg;
                    151:        char buf[MAX_LINE_BUF];
                    152:
                    153:        if (tb_ptr == NULL || tb_len <= 0)
                    154:                return 0;
                    155:
                    156:        va_start(arg, format);
                    157:        len = vsnprintf(buf, tb_len, format, arg);
                    158:        va_end(arg);
                    159:
                    160:        if (len > tb_len)
                    161:                tb_end();
                    162:        else if (len > 0) {
                    163:                int d, s;
                    164:                int digits, curdigit;
                    165:
                    166:                if (!separate_thousands) {
                    167:                        strlcpy(tb_ptr, buf, tb_len);
                    168:                        return len;
                    169:                }
                    170:
                    171:                /* count until we hit a non digit. (e.g. the prefix) */
                    172:                for (digits = 0; digits < len; digits++)
1.16      deraadt   173:                        if (!isdigit((unsigned char)buf[digits]))
1.14      mpf       174:                                break;
                    175:
                    176:                curdigit = digits;
                    177:                d = s = 0;
                    178:                /* insert thousands separators while copying */
                    179:                while (curdigit && d < tb_len) {
                    180:                        if (curdigit < digits && curdigit % 3 == 0)
                    181:                                tb_ptr[d++] = ',';
                    182:                        tb_ptr[d++] = buf[s++];
                    183:                        curdigit--;
                    184:                }
                    185:                /* copy the remaining non-digits */
                    186:                while (len > digits && d < tb_len) {
                    187:                        tb_ptr[d++] = buf[s++];
                    188:                        digits++;
                    189:                }
                    190:                tb_ptr[d] = '\0';
                    191:                tb_ptr += d;
                    192:                tb_len -= d;
                    193:                len = d;
                    194:        }
1.1       canacar   195:        return len;
                    196: }
                    197:
                    198: void
                    199: move_horiz(int offset)
                    200: {
                    201:        if (rawmode) {
                    202:                if (offset <= 0)
                    203:                        linepos = 0;
                    204:                else if (offset >= MAX_LINE_BUF)
                    205:                        linepos = MAX_LINE_BUF - 1;
                    206:                else
                    207:                        linepos = offset;
                    208:        } else {
                    209:                move(curr_line, offset);
                    210:        }
                    211: }
                    212:
                    213: void
                    214: print_str(int len, const char *str)
                    215: {
                    216:        if (len <= 0)
                    217:                return;
                    218:
                    219:        if (rawmode) {
1.18      deraadt   220:                int length = MINIMUM(len, MAX_LINE_BUF - linepos);
1.1       canacar   221:                if (length <= 0)
                    222:                        return;
                    223:                bcopy(str, &linebuf[linepos], length);
                    224:                linepos += length;
                    225:        } else
                    226:                addnstr(str, len);
                    227: }
                    228:
                    229: void
                    230: clear_linebuf(void)
                    231: {
                    232:        memset(linebuf, ' ', MAX_LINE_BUF);
                    233: }
                    234:
                    235: void
                    236: end_line(void)
                    237: {
                    238:        if (rawmode) {
                    239:                linebuf[rawwidth] = '\0';
                    240:                printf("%s\n", linebuf);
                    241:                clear_linebuf();
                    242:        }
                    243:        curr_line++;
                    244: }
                    245:
                    246: void
                    247: end_page(void)
                    248: {
                    249:        if (rawmode) {
                    250:                linepos = 0;
                    251:                clear_linebuf();
1.24      solene    252:                fflush(stdout);
1.1       canacar   253:        } else {
                    254:                move(home_line, 0);
                    255:                print_cmdline();
                    256:                refresh();
                    257:        }
                    258:        curr_line = 0;
                    259: }
                    260:
                    261: /* field output functions */
                    262:
                    263: void
                    264: print_fld_str(field_def *fld, const char *str)
                    265: {
1.7       canacar   266:        int len, offset;
1.1       canacar   267:        char *cpos;
                    268:
                    269:        if (str == NULL || fld == NULL)
                    270:                return;
                    271:
                    272:        if (fld->start < 0)
                    273:                return;
                    274:
                    275:        len = strlen(str);
                    276:
                    277:        if (len >= fld->width) {
                    278:                move_horiz(fld->start);
                    279:                print_str(fld->width, str);
                    280:        } else {
                    281:                switch (fld->align) {
                    282:                case FLD_ALIGN_RIGHT:
                    283:                        move_horiz(fld->start + (fld->width - len));
                    284:                        break;
                    285:                case FLD_ALIGN_CENTER:
                    286:                        move_horiz(fld->start + (fld->width - len) / 2);
                    287:                        break;
                    288:                case FLD_ALIGN_COLUMN:
                    289:                        if ((cpos = strchr(str, ':')) == NULL) {
1.7       canacar   290:                                offset = (fld->width - len) / 2;
1.1       canacar   291:                        } else {
1.7       canacar   292:                                offset = (fld->width / 2) - (cpos - str);
                    293:                                if (offset < 0)
                    294:                                        offset = 0;
                    295:                                else if (offset > (fld->width - len))
                    296:                                        offset = fld->width - len;
1.1       canacar   297:                        }
1.7       canacar   298:                        move_horiz(fld->start + offset);
1.1       canacar   299:                        break;
                    300:                default:
                    301:                        move_horiz(fld->start);
                    302:                        break;
                    303:                }
                    304:                print_str(len, str);
                    305:        }
                    306: }
                    307:
                    308: void
                    309: print_bar_title(field_def *fld)
                    310: {
                    311:        char buf[16];
1.7       canacar   312:        int len, i, d, tr, tw, val, pos, cur;
1.1       canacar   313:
                    314:        int divs[] = {20, 10, 5, 4, 3, 2, 1, 0};
                    315:
                    316:        if (fld->width < 1)
                    317:                return;
                    318:
                    319:        len = snprintf(buf, sizeof(buf), " %d\\", fld->arg);
                    320:        if (len >= sizeof(buf))
                    321:                return;
                    322:
                    323:        for (i = 0; divs[i]; i++)
                    324:                if (divs[i] * len <= fld->width)
                    325:                        break;
                    326:
                    327:        if (divs[i] == 0) {
                    328:                print_fld_str(fld, "*****");
                    329:                return;
                    330:        }
                    331:
1.7       canacar   332:        d = divs[i];
1.1       canacar   333:
                    334:        val = 0;
                    335:        pos = 0;
1.7       canacar   336:        tr = fld->arg % d;
                    337:        tw = fld->width % d;
1.1       canacar   338:
                    339:        tb_start();
                    340:        cur = 0;
1.7       canacar   341:        for(i = 0; i < d; i++) {
1.1       canacar   342:                tw += fld->width;
                    343:                tr += fld->arg;
                    344:
1.7       canacar   345:                while (tr >= d) {
1.1       canacar   346:                        val++;
1.7       canacar   347:                        tr -= d;
1.1       canacar   348:                }
1.7       canacar   349:                while (tw >= d) {
1.1       canacar   350:                        pos++;
1.7       canacar   351:                        tw -= d;
1.1       canacar   352:                }
                    353:
                    354:                len = snprintf(buf, sizeof(buf), "%d\\", val);
1.21      deraadt   355:                if (len >= sizeof(buf))
                    356:                        len = strlen(buf);
1.1       canacar   357:                while (cur < pos - len) {
                    358:                        tbprintf(" ");
                    359:                        cur++;
                    360:                }
                    361:                tbprintf("%s", buf);
                    362:                cur += len;
                    363:        }
                    364:
                    365:        print_fld_tb(fld);
                    366: }
                    367:
                    368: void
                    369: print_fld_bar(field_def *fld, int value)
                    370: {
1.19      benno     371:        int i, tw, val;
1.1       canacar   372:
                    373:        if (fld->width < 1)
                    374:                return;
                    375:
                    376:        val = 0;
                    377:        tw = fld->arg / 2;
                    378:
                    379:        tb_start();
1.19      benno     380:
1.1       canacar   381:        for(i = 0; i < fld->width; i++) {
                    382:                tw += fld->arg;
                    383:
                    384:                while (tw >= fld->width) {
                    385:                        val++;
                    386:                        tw -= fld->width;
                    387:                }
                    388:                if (val > value)
                    389:                        break;
                    390:                tbprintf("#");
                    391:        }
                    392:
                    393:        print_fld_tb(fld);
                    394: }
                    395:
                    396: void
                    397: print_fld_tb(field_def *fld)
                    398: {
                    399:        print_fld_str(fld, tmp_buf);
                    400:        tb_end();
                    401: }
                    402:
                    403: void
                    404: print_title(void)
                    405: {
                    406:        field_def **fp;
                    407:
                    408:        if (curr_view != NULL && curr_view->view != NULL) {
                    409:                for (fp = curr_view->view; *fp != NULL; fp++) {
                    410:                        switch((*fp)->align) {
                    411:                        case FLD_ALIGN_LEFT:
                    412:                        case FLD_ALIGN_RIGHT:
                    413:                        case FLD_ALIGN_CENTER:
                    414:                        case FLD_ALIGN_COLUMN:
                    415:                                print_fld_str(*fp, (*fp)->title);
                    416:                                break;
                    417:                        case FLD_ALIGN_BAR:
                    418:                                print_bar_title(*fp);
                    419:                                break;
                    420:                        }
                    421:                }
                    422:        }
                    423:        end_line();
                    424: }
                    425:
                    426: /* view related functions */
                    427: void
                    428: hide_field(field_def *fld)
                    429: {
                    430:        if (fld == NULL)
                    431:                return;
                    432:
                    433:        fld->flags |= FLD_FLAG_HIDDEN;
                    434: }
                    435:
                    436: void
                    437: show_field(field_def *fld)
                    438: {
                    439:        if (fld == NULL)
                    440:                return;
                    441:
                    442:        fld->flags &= ~((unsigned int) FLD_FLAG_HIDDEN);
                    443: }
                    444:
                    445: void
                    446: reset_fields(void)
                    447: {
                    448:        field_def **fp;
                    449:        field_def *fld;
                    450:
                    451:        if (curr_view == NULL)
                    452:                return;
                    453:
                    454:        if (curr_view->view == NULL)
                    455:                return;
                    456:
                    457:        for (fp = curr_view->view; *fp != NULL; fp++) {
                    458:                fld = *fp;
                    459:                fld->start = -1;
                    460:                fld->width = fld->norm_width;
                    461:        }
                    462: }
                    463:
                    464: void
                    465: field_setup(void)
                    466: {
                    467:        field_def **fp;
                    468:        field_def *fld;
                    469:        int st, fwid, change;
                    470:        int width = columns;
                    471:
                    472:        reset_fields();
                    473:
                    474:        dispstart = 0;
                    475:        st = 0;
                    476:
                    477:        for (fp = curr_view->view; *fp != NULL; fp++) {
                    478:                fld = *fp;
                    479:                if (fld->flags & FLD_FLAG_HIDDEN)
                    480:                        continue;
                    481:
                    482:                if (width <= 1)
                    483:                        break;
                    484:
                    485:                if (st != 1)
                    486:                        width--;
                    487:
                    488:                fld->start = 1;
                    489:                fwid = fld->width;
                    490:                st++;
                    491:                if (fwid >= width) {
                    492:                        fld->width = width;
                    493:                        width = 0;
                    494:                } else
                    495:                        width -= fwid;
                    496:        }
                    497:
                    498:        while (width > 0) {
                    499:                change = 0;
                    500:                for (fp = curr_view->view; *fp != NULL; fp++) {
                    501:                        fld = *fp;
                    502:                        if (fld->flags & FLD_FLAG_HIDDEN)
                    503:                                continue;
                    504:                        if ((fld->width < fld->max_width) &&
                    505:                            (fld->increment <= width)) {
                    506:                                int w = fld->width + fld->increment;
                    507:                                if (w > fld->max_width)
                    508:                                        w = fld->max_width;
                    509:                                width += fld->width - w;
                    510:                                fld->width = w;
                    511:                                change = 1;
                    512:                        }
                    513:                        if (width <= 0) break;
                    514:                }
                    515:                if (change == 0) break;
                    516:        }
                    517:
                    518:        st = 0;
                    519:        for (fp = curr_view->view; *fp != NULL; fp++) {
                    520:                fld = *fp;
                    521:                if (fld->flags & FLD_FLAG_HIDDEN)
                    522:                        continue;
                    523:                if (fld->start < 0) break;
                    524:                fld->start = st;
                    525:                st += fld->width + 1;
                    526:        }
                    527: }
                    528:
                    529: void
                    530: set_curr_view(struct view_ent *ve)
                    531: {
                    532:        field_view *v;
                    533:
                    534:        reset_fields();
                    535:
                    536:        if (ve == NULL) {
                    537:                curr_view_ent = NULL;
                    538:                curr_view = NULL;
                    539:                curr_mgr = NULL;
                    540:                return;
                    541:        }
                    542:
                    543:        v = ve->view;
1.26      jasper    544:
1.1       canacar   545:        if ((curr_view != NULL) && (curr_mgr != v->mgr)) {
                    546:                gotsig_alarm = 1;
                    547:                if (v->mgr != NULL && v->mgr->select_fn != NULL)
                    548:                        v->mgr->select_fn();
                    549:        }
                    550:
                    551:        curr_view_ent = ve;
                    552:        curr_view = v;
                    553:        curr_mgr = v->mgr;
                    554:        field_setup();
                    555:        need_update = 1;
                    556: }
                    557:
                    558: void
                    559: add_view(field_view *fv)
                    560: {
                    561:        struct view_ent *ent;
                    562:
                    563:        if (fv == NULL)
                    564:                return;
                    565:
                    566:        if (fv->view == NULL || fv->name == NULL || fv->mgr == NULL)
                    567:                return;
                    568:
                    569:        ent = malloc(sizeof(struct view_ent));
                    570:        if (ent == NULL)
                    571:                return;
                    572:
                    573:        ent->view = fv;
1.17      krw       574:        TAILQ_INSERT_TAIL(&view_head, ent, entries);
1.1       canacar   575:
                    576:        if (curr_view == NULL)
                    577:                set_curr_view(ent);
                    578: }
                    579:
                    580: int
1.5       canacar   581: set_view(const char *opt)
1.1       canacar   582: {
                    583:        struct view_ent *ve, *vm = NULL;
                    584:        field_view *v;
                    585:        int len;
                    586:
                    587:        if (opt == NULL || (len = strlen(opt)) == 0)
                    588:                return 1;
                    589:
1.17      krw       590:        TAILQ_FOREACH(ve, &view_head, entries) {
1.1       canacar   591:                v = ve->view;
                    592:                if (strncasecmp(opt, v->name, len) == 0) {
                    593:                        if (vm)
                    594:                                return 1;
                    595:                        vm = ve;
                    596:                }
                    597:        }
                    598:
                    599:        if (vm) {
                    600:                set_curr_view(vm);
                    601:                return 0;
                    602:        }
                    603:
                    604:        return 1;
                    605: }
                    606:
                    607: void
                    608: foreach_view(void (*callback)(field_view *))
                    609: {
                    610:        struct view_ent *ve;
                    611:
1.17      krw       612:        TAILQ_FOREACH(ve, &view_head, entries) {
1.1       canacar   613:                callback(ve->view);
                    614:        }
                    615: }
                    616:
                    617: int
                    618: set_view_hotkey(int ch)
                    619: {
                    620:        struct view_ent *ve;
                    621:        field_view *v;
                    622:        int key = tolower(ch);
                    623:
1.17      krw       624:        TAILQ_FOREACH(ve, &view_head, entries) {
1.1       canacar   625:                v = ve->view;
                    626:                if (key == v->hotkey) {
                    627:                        set_curr_view(ve);
                    628:                        return 1;
                    629:                }
                    630:        }
                    631:
                    632:        return 0;
                    633: }
                    634:
                    635: void
                    636: next_view(void)
                    637: {
                    638:        struct view_ent *ve;
                    639:
1.17      krw       640:        if (TAILQ_EMPTY(&view_head) || curr_view_ent == NULL)
1.1       canacar   641:                return;
                    642:
1.17      krw       643:        ve = TAILQ_NEXT(curr_view_ent, entries);
                    644:        if (ve == NULL)
                    645:                ve = TAILQ_FIRST(&view_head);
1.1       canacar   646:
                    647:        set_curr_view(ve);
                    648: }
                    649:
                    650: void
                    651: prev_view(void)
                    652: {
                    653:        struct view_ent *ve;
                    654:
1.17      krw       655:        if (TAILQ_EMPTY(&view_head) || curr_view_ent == NULL)
1.1       canacar   656:                return;
                    657:
1.17      krw       658:        ve = TAILQ_PREV(curr_view_ent, view_list, entries);
                    659:        if (ve == NULL)
                    660:                ve = TAILQ_LAST(&view_head, view_list);
1.1       canacar   661:
                    662:        set_curr_view(ve);
                    663: }
                    664:
                    665: /* generic field printing */
                    666:
                    667: void
                    668: print_fld_age(field_def *fld, unsigned int age)
                    669: {
                    670:        int len;
                    671:        unsigned int h, m, s;
                    672:
                    673:        if (fld == NULL)
                    674:                return;
                    675:        len = fld->width;
                    676:
                    677:        if (len < 1)
                    678:                return;
                    679:
                    680:        s = age % 60;
                    681:        m = age / 60;
                    682:        h = m / 60;
                    683:        m %= 60;
                    684:
                    685:        tb_start();
                    686:        if (tbprintf("%02u:%02u:%02u", h, m, s) <= len)
                    687:                goto ok;
1.26      jasper    688:
1.3       canacar   689:        tb_start();
1.1       canacar   690:        if (tbprintf("%u", age) <= len)
                    691:                goto ok;
                    692:
1.3       canacar   693:        tb_start();
1.1       canacar   694:        age /= 60;
                    695:        if (tbprintf("%um", age) <= len)
                    696:                goto ok;
                    697:        if (age == 0)
                    698:                goto err;
1.26      jasper    699:
1.3       canacar   700:        tb_start();
1.1       canacar   701:        age /= 60;
                    702:        if (tbprintf("%uh", age) <= len)
                    703:                goto ok;
                    704:        if (age == 0)
                    705:                goto err;
1.26      jasper    706:
1.3       canacar   707:        tb_start();
1.1       canacar   708:        age /= 24;
                    709:        if (tbprintf("%ud", age) <= len)
                    710:                goto ok;
1.26      jasper    711:
1.9       jasper    712: err:
1.1       canacar   713:        print_fld_str(fld, "*");
                    714:        tb_end();
                    715:        return;
1.26      jasper    716:
1.9       jasper    717: ok:
1.1       canacar   718:        print_fld_tb(fld);
                    719: }
                    720:
                    721: void
1.7       canacar   722: print_fld_sdiv(field_def *fld, u_int64_t size, int d)
1.1       canacar   723: {
                    724:        int len;
1.25      martijn   725:        char *mult = "KMGTPE";
                    726:        int i = -1;
1.1       canacar   727:
                    728:        if (fld == NULL)
                    729:                return;
                    730:
                    731:        len = fld->width;
                    732:        if (len < 1)
                    733:                return;
                    734:
1.25      martijn   735:        if (humanreadable) {
                    736:                while (size >= 10000 && sizeof(mult) >= i + 1) {
                    737:                        i++;
                    738:                        size /= d;
                    739:                }
                    740:                tb_start();
                    741:                if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
                    742:                        goto ok;
1.1       canacar   743:                goto err;
1.25      martijn   744:        }
                    745:        do {
                    746:                tb_start();
                    747:                if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
                    748:                        goto ok;
                    749:                i++;
                    750:                size /= d;
                    751:        } while (size != 0 && sizeof(mult) >= i);
                    752: err:
1.3       canacar   753:        tb_start();
1.1       canacar   754:        print_fld_str(fld, "*");
                    755:        tb_end();
                    756:        return;
                    757:
                    758: ok:
                    759:        print_fld_tb(fld);
                    760: }
                    761:
                    762: void
                    763: print_fld_size(field_def *fld, u_int64_t size)
                    764: {
                    765:        print_fld_sdiv(fld, size, 1024);
1.4       canacar   766: }
                    767:
                    768: void
1.7       canacar   769: print_fld_ssdiv(field_def *fld, int64_t size, int d)
1.4       canacar   770: {
                    771:        int len;
                    772:
                    773:        if (fld == NULL)
                    774:                return;
                    775:
                    776:        len = fld->width;
                    777:        if (len < 1)
                    778:                return;
                    779:
                    780:        tb_start();
1.14      mpf       781:        if (tbprintft("%lld", size) <= len)
1.4       canacar   782:                goto ok;
                    783:
                    784:        tb_start();
1.7       canacar   785:        size /= d;
1.14      mpf       786:        if (tbprintft("%lldK", size) <= len)
1.4       canacar   787:                goto ok;
                    788:        if (size == 0)
                    789:                goto err;
                    790:
                    791:        tb_start();
1.7       canacar   792:        size /= d;
1.14      mpf       793:        if (tbprintft("%lldM", size) <= len)
1.4       canacar   794:                goto ok;
                    795:        if (size == 0)
                    796:                goto err;
                    797:
                    798:        tb_start();
1.7       canacar   799:        size /= d;
1.14      mpf       800:        if (tbprintft("%lldG", size) <= len)
1.4       canacar   801:                goto ok;
                    802:        if (size == 0)
                    803:                goto err;
                    804:
                    805:        tb_start();
1.7       canacar   806:        size /= d;
1.14      mpf       807:        if (tbprintft("%lldT", size) <= len)
1.4       canacar   808:                goto ok;
                    809:
                    810: err:
                    811:        print_fld_str(fld, "*");
                    812:        tb_end();
                    813:        return;
                    814:
                    815: ok:
                    816:        print_fld_tb(fld);
                    817: }
                    818:
                    819: void
                    820: print_fld_ssize(field_def *fld, int64_t size)
                    821: {
                    822:        print_fld_ssdiv(fld, size, 1024);
1.1       canacar   823: }
                    824:
                    825: void
                    826: print_fld_rate(field_def *fld, double rate)
                    827: {
                    828:        if (rate < 0) {
                    829:                print_fld_str(fld, "*");
                    830:        } else {
                    831:                print_fld_size(fld, rate);
                    832:        }
                    833: }
                    834:
                    835: void
                    836: print_fld_bw(field_def *fld, double bw)
                    837: {
                    838:        if (bw < 0) {
                    839:                print_fld_str(fld, "*");
                    840:        } else {
                    841:                print_fld_sdiv(fld, bw, 1000);
                    842:        }
                    843: }
                    844:
                    845: void
                    846: print_fld_uint(field_def *fld, unsigned int size)
                    847: {
                    848:        int len;
                    849:
                    850:        if (fld == NULL)
                    851:                return;
                    852:
                    853:        len = fld->width;
                    854:        if (len < 1)
                    855:                return;
                    856:
                    857:        tb_start();
1.14      mpf       858:        if (tbprintft("%u", size) > len)
1.6       naddy     859:                print_fld_str(fld, "*");
                    860:        else
                    861:                print_fld_tb(fld);
                    862:        tb_end();
                    863: }
                    864:
                    865: void
                    866: print_fld_float(field_def *fld, double f, int prec)
                    867: {
                    868:        int len;
                    869:
                    870:        if (fld == NULL)
                    871:                return;
                    872:
                    873:        len = fld->width;
                    874:        if (len < 1)
                    875:                return;
                    876:
                    877:        tb_start();
                    878:        if (tbprintf("%*.*f", len, prec, f) > len)
1.1       canacar   879:                print_fld_str(fld, "*");
                    880:        else
                    881:                print_fld_tb(fld);
                    882:        tb_end();
                    883: }
                    884:
                    885:
                    886: /* ordering */
1.22      martijn   887:
                    888: int
                    889: foreach_order(void (*callback)(order_type *))
                    890: {
                    891:        order_type *o;
                    892:
                    893:        if (curr_view == NULL || curr_view->mgr == NULL ||
                    894:            curr_view->mgr->order_list == NULL)
                    895:                return -1;
                    896:        o = curr_view->mgr->order_list;
                    897:        do {
                    898:                callback(o++);
                    899:        } while (o->name != NULL);
                    900:        return 0;
                    901: }
1.1       canacar   902:
                    903: void
1.5       canacar   904: set_order(const char *opt)
1.1       canacar   905: {
                    906:        order_type *o;
                    907:
                    908:        if (curr_view == NULL || curr_view->mgr == NULL)
                    909:                return;
                    910:
                    911:        curr_view->mgr->order_curr = curr_view->mgr->order_list;
                    912:
                    913:        if (opt == NULL)
                    914:                return;
                    915:
                    916:        o = curr_view->mgr->order_list;
                    917:
                    918:        if (o == NULL)
                    919:                return;
                    920:
                    921:        for (;o->name != NULL; o++) {
                    922:                if (strcasecmp(opt, o->match) == 0) {
                    923:                        curr_view->mgr->order_curr = o;
                    924:                        return;
                    925:                }
                    926:        }
                    927: }
                    928:
                    929: int
                    930: set_order_hotkey(int ch)
                    931: {
                    932:        order_type *o;
                    933:        int key = ch;
                    934:
                    935:        if (curr_view == NULL || curr_view->mgr == NULL)
                    936:                return 0;
                    937:
                    938:        o = curr_view->mgr->order_list;
                    939:
                    940:        if (o == NULL)
                    941:                return 0;
                    942:
                    943:        for (;o->name != NULL; o++) {
                    944:                if (key == o->hotkey) {
                    945:                        if (curr_view->mgr->order_curr == o) {
                    946:                                sortdir *= -1;
                    947:                        } else {
                    948:                                curr_view->mgr->order_curr = o;
                    949:                        }
                    950:                        return 1;
                    951:                }
                    952:        }
                    953:
                    954:        return 0;
                    955: }
                    956:
                    957: void
                    958: next_order(void)
                    959: {
                    960:        order_type *o, *oc;
1.2       canacar   961:
                    962:        if (curr_view->mgr->order_list == NULL)
                    963:                return;
1.1       canacar   964:
                    965:        oc = curr_view->mgr->order_curr;
                    966:
                    967:        for (o = curr_view->mgr->order_list; o->name != NULL; o++) {
                    968:                if (oc == o) {
                    969:                        o++;
                    970:                        if (o->name == NULL)
                    971:                                break;
                    972:                        curr_view->mgr->order_curr = o;
                    973:                        return;
                    974:                }
                    975:        }
                    976:
                    977:        curr_view->mgr->order_curr = curr_view->mgr->order_list;
                    978: }
                    979:
                    980:
                    981: /* main program functions */
                    982:
                    983: int
                    984: read_view(void)
                    985: {
                    986:        if (curr_mgr == NULL)
                    987:                return (0);
                    988:
                    989:        if (paused)
                    990:                return (0);
                    991:
                    992:        if (curr_mgr->read_fn != NULL)
                    993:                return (curr_mgr->read_fn());
                    994:
                    995:        return (0);
                    996: }
                    997:
                    998:
                    999: int
                   1000: disp_update(void)
                   1001: {
1.7       canacar  1002:        int li;
1.1       canacar  1003:
                   1004:        if (maxprint < 0)
                   1005:                dispstart = 0;
                   1006:        else if (dispstart + maxprint > num_disp)
                   1007:                dispstart = num_disp - maxprint;
1.26      jasper   1008:
1.1       canacar  1009:        if (dispstart < 0)
                   1010:                dispstart = 0;
                   1011:
                   1012:        if (curr_view == NULL)
                   1013:                return 0;
                   1014:
                   1015:        if (curr_mgr != NULL) {
                   1016:                curr_line = 0;
                   1017:
                   1018:                if (curr_mgr->header_fn != NULL) {
1.7       canacar  1019:                        li = curr_mgr->header_fn();
                   1020:                        if (li < 0)
1.1       canacar  1021:                                return (1);
1.7       canacar  1022:                        curr_line = ++li;
                   1023:                        home_line = li + maxprint + 1;
1.1       canacar  1024:                }
                   1025:
                   1026:                print_title();
                   1027:
                   1028:                if (curr_mgr->print_fn != NULL)
                   1029:                        curr_mgr->print_fn();
                   1030:        }
                   1031:
                   1032:        return (0);
                   1033: }
                   1034:
                   1035: void
                   1036: sort_view(void)
                   1037: {
                   1038:        if (curr_mgr != NULL)
                   1039:                if (curr_mgr->sort_fn != NULL)
                   1040:                        curr_mgr->sort_fn();
                   1041: }
                   1042:
                   1043: void
1.7       canacar  1044: sig_close(int sig)
1.1       canacar  1045: {
                   1046:        gotsig_close = 1;
                   1047: }
                   1048:
                   1049: void
1.7       canacar  1050: sig_resize(int sig)
1.1       canacar  1051: {
                   1052:        gotsig_resize = 1;
                   1053: }
                   1054:
                   1055: void
1.7       canacar  1056: sig_alarm(int sig)
1.1       canacar  1057: {
                   1058:        gotsig_alarm = 1;
                   1059: }
                   1060:
                   1061: void
                   1062: setup_term(int dmax)
                   1063: {
                   1064:        max_disp = dmax;
                   1065:        maxprint = dmax;
                   1066:
                   1067:        if (rawmode) {
                   1068:                columns = rawwidth;
                   1069:                lines = DEFAULT_HEIGHT;
                   1070:                clear_linebuf();
                   1071:        } else {
                   1072:                if (dmax < 0)
                   1073:                        dmax = 0;
                   1074:
                   1075:                screen = newterm(NULL, stdout, stdin);
                   1076:                if (screen == NULL) {
                   1077:                        rawmode = 1;
                   1078:                        interactive = 0;
                   1079:                        setup_term(dmax);
                   1080:                        return;
                   1081:                }
                   1082:                columns = COLS;
                   1083:                lines = LINES;
                   1084:
                   1085:                if (maxprint > lines - HEADER_LINES)
                   1086:                        maxprint = lines - HEADER_LINES;
                   1087:
                   1088:                nonl();
                   1089:                keypad(stdscr, TRUE);
                   1090:                intrflush(stdscr, FALSE);
                   1091:
                   1092:                halfdelay(10);
                   1093:                noecho();
                   1094:        }
                   1095:
                   1096:        if (dmax == 0)
                   1097:                maxprint = lines - HEADER_LINES;
                   1098:
                   1099:        field_setup();
                   1100: }
                   1101:
1.8       canacar  1102: void
1.11      nicm     1103: do_resize_term(void)
1.8       canacar  1104: {
                   1105:        struct winsize ws;
                   1106:
                   1107:        if (rawmode)
                   1108:                return;
                   1109:
                   1110:        if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1)
                   1111:                return;
                   1112:
                   1113:        resizeterm(ws.ws_row, ws.ws_col);
                   1114:
                   1115:        columns = COLS;
                   1116:        lines = LINES;
                   1117:
                   1118:        maxprint = max_disp;
                   1119:
                   1120:        if (maxprint == 0 || maxprint > lines - HEADER_LINES)
                   1121:                maxprint = lines - HEADER_LINES;
                   1122:
                   1123:        clear();
                   1124:
                   1125:        field_setup();
                   1126: }
                   1127:
1.1       canacar  1128: struct command *
                   1129: command_set(struct command *cmd, const char *init)
                   1130: {
                   1131:        struct command *prev = curr_cmd;
                   1132:
                   1133:        if (cmd) {
                   1134:                if (init) {
                   1135:                        cmd_len = strlcpy(cmdbuf, init, sizeof(cmdbuf));
                   1136:                        if (cmd_len >= sizeof(cmdbuf)) {
                   1137:                                cmdbuf[0] = '\0';
                   1138:                                cmd_len = 0;
                   1139:                        }
                   1140:                } else {
                   1141:                        cmd_len = 0;
                   1142:                        cmdbuf[0] = 0;
                   1143:                }
                   1144:        }
1.27      tb       1145:        message_set(NULL);
1.1       canacar  1146:        curr_cmd = cmd;
                   1147:        need_update = 1;
                   1148:        return prev;
                   1149: }
                   1150:
1.28      martijn  1151: void
                   1152: message_toggle(enum message_mode mode)
                   1153: {
                   1154:        message_mode = message_mode != mode ? mode : MESSAGE_NONE;
                   1155:        need_update = 1;
                   1156:        message_cont = 1;
                   1157: }
                   1158:
1.1       canacar  1159: const char *
1.28      martijn  1160: message_set(const char *msg)
                   1161: {
                   1162:        free(curr_message);
                   1163:
                   1164:        if (msg) {
1.1       canacar  1165:                curr_message = strdup(msg);
1.28      martijn  1166:                message_cont = 0;
                   1167:        } else {
1.1       canacar  1168:                curr_message = NULL;
1.28      martijn  1169:                message_cont = 1;
                   1170:        }
1.1       canacar  1171:        return NULL;
                   1172: }
                   1173:
                   1174: void
                   1175: print_cmdline(void)
                   1176: {
                   1177:        if (curr_cmd) {
                   1178:                attron(A_STANDOUT);
                   1179:                mvprintw(home_line, 0, "%s: ", curr_cmd->prompt);
                   1180:                attroff(A_STANDOUT);
                   1181:                printw("%s", cmdbuf);
                   1182:        } else if (curr_message) {
                   1183:                mvprintw(home_line, 0, "> %s", curr_message);
                   1184:        }
                   1185:        clrtoeol();
                   1186: }
                   1187:
                   1188:
                   1189: void
                   1190: cmd_keyboard(int ch)
                   1191: {
                   1192:        if (curr_cmd == NULL)
                   1193:                return;
                   1194:
                   1195:        if (ch > 0 && isprint(ch)) {
                   1196:                if (cmd_len < sizeof(cmdbuf) - 1) {
                   1197:                        cmdbuf[cmd_len++] = ch;
                   1198:                        cmdbuf[cmd_len] = 0;
                   1199:                } else
                   1200:                        beep();
                   1201:        }
1.26      jasper   1202:
1.1       canacar  1203:        switch (ch) {
                   1204:        case KEY_ENTER:
                   1205:        case 0x0a:
                   1206:        case 0x0d:
                   1207:        {
                   1208:                struct command * c = command_set(NULL, NULL);
1.5       canacar  1209:                c->exec(cmdbuf);
1.1       canacar  1210:                break;
                   1211:        }
                   1212:        case KEY_BACKSPACE:
                   1213:        case KEY_DC:
                   1214:        case CTRL_H:
                   1215:                if (cmd_len > 0) {
                   1216:                        cmdbuf[--cmd_len] = 0;
                   1217:                } else
                   1218:                        beep();
                   1219:                break;
                   1220:        case 0x1b:
                   1221:        case CTRL_G:
                   1222:                if (cmd_len > 0) {
                   1223:                        cmdbuf[0] = '\0';
                   1224:                        cmd_len = 0;
                   1225:                } else
                   1226:                        command_set(NULL, NULL);
                   1227:                break;
                   1228:        default:
                   1229:                break;
                   1230:        }
                   1231: }
                   1232:
                   1233: void
                   1234: keyboard(void)
                   1235: {
                   1236:        int ch;
                   1237:
                   1238:        ch = getch();
                   1239:
                   1240:        if (curr_cmd) {
                   1241:                cmd_keyboard(ch);
                   1242:                print_cmdline();
                   1243:                return;
                   1244:        }
                   1245:
                   1246:        if (curr_mgr != NULL)
                   1247:                if (curr_mgr->key_fn != NULL)
                   1248:                        if (curr_mgr->key_fn(ch))
                   1249:                                return;
                   1250:
                   1251:        if (curr_message != NULL) {
                   1252:                if (ch > 0) {
1.27      tb       1253:                        message_set(NULL);
1.1       canacar  1254:                        need_update = 1;
                   1255:                }
                   1256:        }
                   1257:
                   1258:        switch (ch) {
                   1259:        case ' ':
                   1260:                gotsig_alarm = 1;
                   1261:                break;
                   1262:        case 'o':
                   1263:                next_order();
                   1264:                need_sort = 1;
                   1265:                break;
                   1266:        case 'p':
                   1267:                paused = !paused;
                   1268:                gotsig_alarm = 1;
                   1269:                break;
                   1270:        case 'q':
                   1271:                gotsig_close = 1;
                   1272:                break;
                   1273:        case 'r':
                   1274:                sortdir *= -1;
                   1275:                need_sort = 1;
                   1276:                break;
                   1277:        case 'v':
                   1278:                /* FALLTHROUGH */
                   1279:        case KEY_RIGHT:
                   1280:                /* FALLTHROUGH */
                   1281:        case CTRL_F:
                   1282:                next_view();
                   1283:                break;
                   1284:        case KEY_LEFT:
                   1285:                /* FALLTHROUGH */
                   1286:        case CTRL_B:
                   1287:                prev_view();
                   1288:                break;
                   1289:        case KEY_DOWN:
                   1290:                /* FALLTHROUGH */
                   1291:        case CTRL_N:
                   1292:                dispstart++;
                   1293:                need_update = 1;
                   1294:                break;
                   1295:        case KEY_UP:
                   1296:                /* FALLTHROUGH */
                   1297:        case CTRL_P:
                   1298:                dispstart--;
                   1299:                need_update = 1;
                   1300:                break;
                   1301:        case KEY_NPAGE:
                   1302:                /* FALLTHROUGH */
                   1303:        case CTRL_V:
                   1304:                dispstart += maxprint;
                   1305:                need_update = 1;
                   1306:                break;
                   1307:        case KEY_PPAGE:
                   1308:                /* FALLTHROUGH */
                   1309:        case META_V:
                   1310:                dispstart -= maxprint;
                   1311:                need_update = 1;
                   1312:                break;
                   1313:        case KEY_HOME:
                   1314:                /* FALLTHROUGH */
                   1315:        case CTRL_A:
                   1316:                dispstart = 0;
                   1317:                need_update = 1;
                   1318:                break;
                   1319:        case KEY_END:
                   1320:                /* FALLTHROUGH */
                   1321:        case CTRL_E:
                   1322:                dispstart = num_disp;
                   1323:                need_update = 1;
                   1324:                break;
                   1325:        case CTRL_L:
                   1326:                clear();
                   1327:                need_update = 1;
                   1328:                break;
                   1329:        default:
                   1330:                break;
                   1331:        }
                   1332:
                   1333:        if (set_order_hotkey(ch))
                   1334:                need_sort = 1;
                   1335:        else
                   1336:                set_view_hotkey(ch);
                   1337: }
                   1338:
                   1339: void
                   1340: engine_initialize(void)
                   1341: {
                   1342:        signal(SIGTERM, sig_close);
                   1343:        signal(SIGINT, sig_close);
                   1344:        signal(SIGQUIT, sig_close);
                   1345:        signal(SIGWINCH, sig_resize);
                   1346:        signal(SIGALRM, sig_alarm);
                   1347: }
                   1348:
                   1349: void
                   1350: engine_loop(int countmax)
                   1351: {
                   1352:        int count = 0;
                   1353:
                   1354:        for (;;) {
                   1355:                if (gotsig_alarm) {
                   1356:                        read_view();
                   1357:                        need_sort = 1;
                   1358:                        gotsig_alarm = 0;
1.29      millert  1359:                        setitimer(ITIMER_REAL, &it_delay, NULL);
1.1       canacar  1360:                }
                   1361:
                   1362:                if (need_sort) {
                   1363:                        sort_view();
                   1364:                        need_sort = 0;
                   1365:                        need_update = 1;
1.26      jasper   1366:
1.1       canacar  1367:                        /* XXX if sort took too long */
                   1368:                        if (gotsig_alarm) {
                   1369:                                gotsig_alarm = 0;
1.29      millert  1370:                                setitimer(ITIMER_REAL, &it_delay, NULL);
1.1       canacar  1371:                        }
                   1372:                }
                   1373:
                   1374:                if (need_update) {
                   1375:                        erase();
1.15      reyk     1376:                        if (!averageonly ||
                   1377:                            (averageonly && count == countmax - 1))
                   1378:                                disp_update();
1.28      martijn  1379:                        if (message_cont) {
                   1380:                                switch (message_mode) {
                   1381:                                case MESSAGE_NONE:
                   1382:                                        message_set(NULL);
                   1383:                                        break;
                   1384:                                case MESSAGE_HELP:
                   1385:                                        show_help();
                   1386:                                        break;
                   1387:                                case MESSAGE_VIEW:
                   1388:                                        show_view();
                   1389:                                        break;
                   1390:                                case MESSAGE_ORDER:
                   1391:                                        show_order();
                   1392:                                        break;
                   1393:                                }
                   1394:                        }
1.1       canacar  1395:                        end_page();
                   1396:                        need_update = 0;
                   1397:                        if (countmax && ++count >= countmax)
                   1398:                                break;
                   1399:                }
                   1400:
                   1401:                if (gotsig_close)
                   1402:                        break;
                   1403:                if (gotsig_resize) {
1.11      nicm     1404:                        do_resize_term();
1.1       canacar  1405:                        gotsig_resize = 0;
                   1406:                        need_update = 1;
                   1407:                }
                   1408:
                   1409:                if (interactive && need_update == 0)
                   1410:                        keyboard();
                   1411:                else if (interactive == 0)
1.29      millert  1412:                        nanosleep(&ts_delay, NULL);
1.1       canacar  1413:        }
                   1414:
                   1415:        if (rawmode == 0)
                   1416:                endwin();
1.12      lum      1417: }
                   1418:
                   1419: int
                   1420: check_termcap(void)
                   1421: {
                   1422:        char *term_name;
                   1423:        int status;
                   1424:        static struct termios screen_settings;
                   1425:
                   1426:        if (!interactive)
                   1427:                /* pretend we have a dumb terminal */
                   1428:                return(1);
                   1429:
                   1430:        /* get the terminal name */
                   1431:        term_name = getenv("TERM");
                   1432:        if (term_name == NULL)
                   1433:                return(1);
                   1434:
                   1435:        /* now get the termcap entry */
                   1436:        if ((status = tgetent(NULL, term_name)) != 1) {
                   1437:                if (status == -1)
                   1438:                        warnx("can't open termcap file");
                   1439:                else
1.26      jasper   1440:                        warnx("no termcap entry for a `%s' terminal",
1.12      lum      1441:                            term_name);
                   1442:
                   1443:                /* pretend it's dumb and proceed */
                   1444:                return(1);
                   1445:        }
                   1446:
                   1447:        /* "hardcopy" immediately indicates a very stupid terminal */
                   1448:        if (tgetflag("hc"))
                   1449:                return(1);
                   1450:
                   1451:         /* get necessary capabilities */
                   1452:         if (tgetstr("cl", NULL) == NULL || tgetstr("cm", NULL) == NULL)
                   1453:                return(1);
                   1454:
                   1455:        /* if stdout is not a terminal, pretend we are a dumb terminal */
                   1456:        if (tcgetattr(STDOUT_FILENO, &screen_settings) == -1)
                   1457:                return(1);
                   1458:
                   1459:        return(0);
1.29      millert  1460: }
                   1461:
                   1462: void
                   1463: refresh_delay(double delay)
                   1464: {
                   1465:        double secs, frac;
                   1466:
                   1467:        frac = modf(delay, &secs);
                   1468:        ts_delay.tv_sec = secs;
                   1469:        ts_delay.tv_nsec = frac * 1000000000.0;
                   1470:        if (!timespecisset(&ts_delay))
                   1471:                ts_delay.tv_nsec = 1000000000;
                   1472:        TIMESPEC_TO_TIMEVAL(&it_delay.it_value, &ts_delay);
1.1       canacar  1473: }