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

Annotation of src/usr.bin/less/os.c, Revision 1.1.1.4

1.1       etheisen    1: /*
1.1.1.4 ! shadchin    2:  * Copyright (C) 1984-2012  Mark Nudelman
1.1       etheisen    3:  *
1.1.1.2   millert     4:  * You may distribute under the terms of either the GNU General Public
                      5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.1.1.4 ! shadchin    7:  * For more information, see the README file.
1.1       etheisen    8:  */
                      9:
                     10:
                     11: /*
                     12:  * Operating system dependent routines.
                     13:  *
                     14:  * Most of the stuff in here is based on Unix, but an attempt
                     15:  * has been made to make things work on other operating systems.
                     16:  * This will sometimes result in a loss of functionality, unless
                     17:  * someone rewrites code specifically for the new operating system.
                     18:  *
                     19:  * The makefile provides defines to decide whether various
                     20:  * Unix features are present.
                     21:  */
                     22:
                     23: #include "less.h"
                     24: #include <signal.h>
                     25: #if HAVE_TIME_H
                     26: #include <time.h>
                     27: #endif
                     28: #if HAVE_ERRNO_H
                     29: #include <errno.h>
                     30: #endif
                     31: #if HAVE_VALUES_H
                     32: #include <values.h>
                     33: #endif
                     34:
                     35: #if HAVE_TIME_T
                     36: #define time_type      time_t
                     37: #else
                     38: #define        time_type       long
                     39: #endif
                     40:
1.1.1.4 ! shadchin   41: extern volatile sig_atomic_t sigs;
1.1.1.2   millert    42:
1.1       etheisen   43: /*
                     44:  * Like read() system call, but is deliberately interruptible.
                     45:  */
                     46:        public int
                     47: iread(fd, buf, len)
                     48:        int fd;
                     49:        char *buf;
                     50:        unsigned int len;
                     51: {
                     52:        register int n;
                     53:
1.1.1.3   shadchin   54: start:
1.1.1.2   millert    55: #if MSDOS_COMPILER==WIN32C
                     56:        if (ABORT_SIGS())
                     57:                return (READ_INTR);
                     58: #else
                     59: #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
1.1       etheisen   60:        if (kbhit())
                     61:        {
                     62:                int c;
                     63:
                     64:                c = getch();
                     65:                if (c == '\003')
                     66:                        return (READ_INTR);
                     67:                ungetch(c);
                     68:        }
                     69: #endif
1.1.1.2   millert    70: #endif
1.1       etheisen   71:
                     72:        flush();
1.1.1.2   millert    73: #if MSDOS_COMPILER==DJGPPC
                     74:        if (isatty(fd))
                     75:        {
                     76:                /*
                     77:                 * Don't try reading from a TTY until a character is
                     78:                 * available, because that makes some background programs
                     79:                 * believe DOS is busy in a way that prevents those
                     80:                 * programs from working while "less" waits.
                     81:                 */
                     82:                fd_set readfds;
                     83:
                     84:                FD_ZERO(&readfds);
                     85:                FD_SET(fd, &readfds);
                     86:                if (select(fd+1, &readfds, 0, 0, 0) == -1)
                     87:                        return (-1);
                     88:        }
                     89: #endif
1.1       etheisen   90:        n = read(fd, buf, len);
1.1.1.2   millert    91: #if 1
                     92:        /*
                     93:         * This is a kludge to workaround a problem on some systems
                     94:         * where terminating a remote tty connection causes read() to
                     95:         * start returning 0 forever, instead of -1.
                     96:         */
                     97:        {
                     98:                extern int ignore_eoi;
                     99:                if (!ignore_eoi)
                    100:                {
                    101:                        static int consecutive_nulls = 0;
                    102:                        if (n == 0)
                    103:                                consecutive_nulls++;
                    104:                        else
                    105:                                consecutive_nulls = 0;
                    106:                        if (consecutive_nulls > 20)
                    107:                                quit(QUIT_ERROR);
                    108:                }
                    109:        }
                    110: #endif
1.1       etheisen  111:        if (n < 0)
1.1.1.3   shadchin  112:        {
                    113: #if HAVE_ERRNO
                    114:                /*
                    115:                 * Certain values of errno indicate we should just retry the read.
                    116:                 */
                    117: #if MUST_DEFINE_ERRNO
                    118:                extern int errno;
                    119: #endif
                    120: #ifdef EINTR
                    121:                if (errno == EINTR)
1.1.1.4 ! shadchin  122:                        return (READ_INTR);
1.1.1.3   shadchin  123: #endif
                    124: #ifdef EAGAIN
                    125:                if (errno == EAGAIN)
                    126:                        goto start;
                    127: #endif
                    128: #endif
1.1       etheisen  129:                return (-1);
1.1.1.3   shadchin  130:        }
1.1       etheisen  131:        return (n);
                    132: }
                    133:
                    134: /*
                    135:  * Return the current time.
                    136:  */
                    137: #if HAVE_TIME
                    138:        public long
                    139: get_time()
                    140: {
                    141:        time_type t;
                    142:
                    143:        time(&t);
                    144:        return (t);
                    145: }
                    146: #endif
                    147:
                    148:
                    149: #if !HAVE_STRERROR
                    150: /*
                    151:  * Local version of strerror, if not available from the system.
                    152:  */
                    153:        static char *
                    154: strerror(err)
                    155:        int err;
                    156: {
                    157: #if HAVE_SYS_ERRLIST
                    158:        static char buf[16];
                    159:        extern char *sys_errlist[];
                    160:        extern int sys_nerr;
                    161:
                    162:        if (err < sys_nerr)
                    163:                return sys_errlist[err];
1.1.1.4 ! shadchin  164:        snprintf(buf, sizeof(buf), "Error %d", err);
1.1       etheisen  165:        return buf;
                    166: #else
                    167:        return ("cannot open");
                    168: #endif
                    169: }
                    170: #endif
                    171:
                    172: /*
                    173:  * errno_message: Return an error message based on the value of "errno".
                    174:  */
                    175:        public char *
                    176: errno_message(filename)
                    177:        char *filename;
                    178: {
                    179:        register char *p;
                    180:        register char *m;
1.1.1.4 ! shadchin  181:        size_t len;
1.1       etheisen  182: #if HAVE_ERRNO
1.1.1.2   millert   183: #if MUST_DEFINE_ERRNO
1.1       etheisen  184:        extern int errno;
1.1.1.2   millert   185: #endif
1.1       etheisen  186:        p = strerror(errno);
                    187: #else
                    188:        p = "cannot open";
                    189: #endif
1.1.1.3   shadchin  190:        len = strlen(filename) + strlen(p) + 3;
                    191:        m = (char *) ecalloc(len, sizeof(char));
                    192:        SNPRINTF2(m, len, "%s: %s", filename, p);
1.1       etheisen  193:        return (m);
                    194: }
                    195:
1.1.1.3   shadchin  196: /* #define HAVE_FLOAT 0 */
                    197:
                    198:        static POSITION
                    199: muldiv(val, num, den)
                    200:        POSITION val, num, den;
                    201: {
                    202: #if HAVE_FLOAT
                    203:        double v = (((double) val) * num) / den;
                    204:        return ((POSITION) (v + 0.5));
                    205: #else
                    206:        POSITION v = ((POSITION) val) * num;
                    207:
                    208:        if (v / num == val)
                    209:                /* No overflow */
                    210:                return (POSITION) (v / den);
                    211:        else
                    212:                /* Above calculation overflows;
                    213:                 * use a method that is less precise but won't overflow. */
                    214:                return (POSITION) (val / (den / num));
                    215: #endif
                    216: }
                    217:
1.1       etheisen  218: /*
1.1.1.2   millert   219:  * Return the ratio of two POSITIONS, as a percentage.
                    220:  * {{ Assumes a POSITION is a long int. }}
1.1       etheisen  221:  */
1.1.1.2   millert   222:        public int
                    223: percentage(num, den)
                    224:        POSITION num, den;
1.1       etheisen  225: {
1.1.1.3   shadchin  226:        return (int) muldiv(num,  (POSITION) 100, den);
1.1       etheisen  227: }
1.1.1.2   millert   228:
                    229: /*
                    230:  * Return the specified percentage of a POSITION.
                    231:  */
                    232:        public POSITION
1.1.1.3   shadchin  233: percent_pos(pos, percent, fraction)
1.1.1.2   millert   234:        POSITION pos;
                    235:        int percent;
1.1.1.3   shadchin  236:        long fraction;
1.1       etheisen  237: {
1.1.1.3   shadchin  238:        /* Change percent (parts per 100) to perden (parts per NUM_FRAC_DENOM). */
                    239:        POSITION perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100);
1.1       etheisen  240:
1.1.1.3   shadchin  241:        if (perden == 0)
1.1.1.2   millert   242:                return (0);
1.1.1.3   shadchin  243:        return (POSITION) muldiv(pos, perden, (POSITION) NUM_FRAC_DENOM);
1.1.1.2   millert   244: }
                    245:
                    246: #if !HAVE_STRCHR
                    247: /*
                    248:  * strchr is used by regexp.c.
                    249:  */
                    250:        char *
                    251: strchr(s, c)
                    252:        char *s;
                    253:        int c;
                    254: {
                    255:        for ( ;  *s != '\0';  s++)
                    256:                if (*s == c)
                    257:                        return (s);
                    258:        if (c == '\0')
                    259:                return (s);
                    260:        return (NULL);
                    261: }
                    262: #endif
                    263:
                    264: #if !HAVE_MEMCPY
                    265:        VOID_POINTER
                    266: memcpy(dst, src, len)
                    267:        VOID_POINTER dst;
                    268:        VOID_POINTER src;
                    269:        int len;
                    270: {
                    271:        char *dstp = (char *) dst;
                    272:        char *srcp = (char *) src;
                    273:        int i;
                    274:
                    275:        for (i = 0;  i < len;  i++)
                    276:                dstp[i] = srcp[i];
                    277:        return (dst);
1.1       etheisen  278: }
                    279: #endif
                    280:
1.1.1.2   millert   281: #ifdef _OSK_MWC32
                    282:
1.1       etheisen  283: /*
1.1.1.2   millert   284:  * This implements an ANSI-style intercept setup for Microware C 3.2
1.1       etheisen  285:  */
1.1.1.2   millert   286:        public int
                    287: os9_signal(type, handler)
                    288:        int type;
                    289:        RETSIGTYPE (*handler)();
1.1       etheisen  290: {
1.1.1.2   millert   291:        intercept(handler);
1.1       etheisen  292: }
1.1.1.2   millert   293:
                    294: #include <sgstat.h>
                    295:
                    296:        int
                    297: isatty(f)
                    298:        int f;
                    299: {
                    300:        struct sgbuf sgbuf;
                    301:
                    302:        if (_gs_opt(f, &sgbuf) < 0)
                    303:                return -1;
                    304:        return (sgbuf.sg_class == 0);
                    305: }
                    306:
                    307: #endif