[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.3

1.3     ! niklas      1: /*     $OpenBSD$       */
        !             2:
1.1       etheisen    3: /*
                      4:  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice in the documentation and/or other materials provided with
                     14:  *    the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
                     17:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     19:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
                     20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     21:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
                     22:  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
                     23:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     24:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
                     25:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
                     26:  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29:
                     30: /*
                     31:  * Operating system dependent routines.
                     32:  *
                     33:  * Most of the stuff in here is based on Unix, but an attempt
                     34:  * has been made to make things work on other operating systems.
                     35:  * This will sometimes result in a loss of functionality, unless
                     36:  * someone rewrites code specifically for the new operating system.
                     37:  *
                     38:  * The makefile provides defines to decide whether various
                     39:  * Unix features are present.
                     40:  */
                     41:
                     42: #include "less.h"
1.2       millert    43: #include <limits.h>
1.1       etheisen   44: #include <signal.h>
                     45: #include <setjmp.h>
                     46: #if HAVE_TIME_H
                     47: #include <time.h>
                     48: #endif
                     49: #if HAVE_ERRNO_H
                     50: #include <errno.h>
                     51: #endif
                     52: #if HAVE_VALUES_H
                     53: #include <values.h>
                     54: #endif
                     55:
                     56: #if HAVE_TIME_T
                     57: #define time_type      time_t
                     58: #else
                     59: #define        time_type       long
                     60: #endif
                     61:
                     62: /*
                     63:  * BSD setjmp() saves (and longjmp() restores) the signal mask.
                     64:  * This costs a system call or two per setjmp(), so if possible we clear the
                     65:  * signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
                     66:  * On other systems, setjmp() doesn't affect the signal mask and so
                     67:  * _setjmp() does not exist; we just use setjmp().
                     68:  */
                     69: #if HAVE__SETJMP && HAVE_SIGSETMASK
                     70: #define SET_JUMP       _setjmp
                     71: #define LONG_JUMP      _longjmp
                     72: #else
                     73: #define SET_JUMP       setjmp
                     74: #define LONG_JUMP      longjmp
                     75: #endif
                     76:
                     77: public int reading;
                     78:
                     79: static jmp_buf read_label;
                     80:
                     81: /*
                     82:  * Like read() system call, but is deliberately interruptible.
                     83:  * A call to intread() from a signal handler will interrupt
                     84:  * any pending iread().
                     85:  */
                     86:        public int
                     87: iread(fd, buf, len)
                     88:        int fd;
                     89:        char *buf;
                     90:        unsigned int len;
                     91: {
                     92:        register int n;
                     93:
                     94: #if MSOFTC
                     95:        if (kbhit())
                     96:        {
                     97:                int c;
                     98:
                     99:                c = getch();
                    100:                if (c == '\003')
                    101:                        return (READ_INTR);
                    102:                ungetch(c);
                    103:        }
                    104: #endif
                    105:        if (SET_JUMP(read_label))
                    106:        {
                    107:                /*
                    108:                 * We jumped here from intread.
                    109:                 */
                    110:                reading = 0;
                    111: #if HAVE_SIGSETMASK
                    112:                sigsetmask(0);
                    113: #endif
                    114:                return (READ_INTR);
                    115:        }
                    116:
                    117:        flush();
                    118:        reading = 1;
                    119:        n = read(fd, buf, len);
                    120:        reading = 0;
                    121:        if (n < 0)
                    122:                return (-1);
                    123:        return (n);
                    124: }
                    125:
                    126: /*
                    127:  * Interrupt a pending iread().
                    128:  */
                    129:        public void
                    130: intread()
                    131: {
                    132:        LONG_JUMP(read_label, 1);
                    133: }
                    134:
                    135: /*
                    136:  * Return the current time.
                    137:  */
                    138: #if HAVE_TIME
                    139:        public long
                    140: get_time()
                    141: {
                    142:        time_type t;
                    143:
                    144:        time(&t);
                    145:        return (t);
                    146: }
                    147: #endif
                    148:
                    149:
                    150: #if !HAVE_STRERROR
                    151: /*
                    152:  * Local version of strerror, if not available from the system.
                    153:  */
                    154:        static char *
                    155: strerror(err)
                    156:        int err;
                    157: {
                    158: #if HAVE_SYS_ERRLIST
                    159:        static char buf[16];
                    160:        extern char *sys_errlist[];
                    161:        extern int sys_nerr;
                    162:
                    163:        if (err < sys_nerr)
                    164:                return sys_errlist[err];
                    165:        sprintf(buf, "Error %d", err);
                    166:        return buf;
                    167: #else
                    168:        return ("cannot open");
                    169: #endif
                    170: }
                    171: #endif
                    172:
                    173: /*
                    174:  * errno_message: Return an error message based on the value of "errno".
                    175:  */
                    176:        public char *
                    177: errno_message(filename)
                    178:        char *filename;
                    179: {
                    180:        register char *p;
                    181:        register char *m;
                    182: #if HAVE_ERRNO
                    183:        extern int errno;
                    184:        p = strerror(errno);
                    185: #else
                    186:        p = "cannot open";
                    187: #endif
                    188:        m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
                    189:        sprintf(m, "%s: %s", filename, p);
                    190:        return (m);
                    191: }
                    192:
                    193: /*
1.2       millert   194:  * Return the largest possible number that can fit in a POSITION.
1.1       etheisen  195:  */
1.2       millert   196: #ifdef QUAD_MAX
                    197:        static POSITION
                    198: get_maxpos()
1.1       etheisen  199: {
1.2       millert   200:        return (QUAD_MAX);
1.1       etheisen  201: }
                    202: #else
1.2       millert   203:        static POSITION
                    204: get_maxpos()
1.1       etheisen  205: {
1.2       millert   206:        POSITION n, n2;
1.1       etheisen  207:
                    208:        /*
                    209:         * Keep doubling n until we overflow.
                    210:         * {{ This actually only returns the largest power of two that
1.2       millert   211:         *    can fit in a POSITION, but percentage() doesn't really need
1.1       etheisen  212:         *    it any more accurate than that. }}
                    213:         */
1.2       millert   214:        n2 = 128;  /* Hopefully no maxpos is less than 128! */
1.1       etheisen  215:        do {
                    216:                n = n2;
                    217:                n2 *= 2;
                    218:        } while (n2 / 2 == n);
                    219:        return (n);
                    220: }
                    221: #endif
                    222:
                    223: /*
1.2       millert   224:  * Return the ratio of two POSITIONs, as a percentage.
1.1       etheisen  225:  */
                    226:        public int
                    227: percentage(num, den)
1.2       millert   228:        POSITION num, den;
1.1       etheisen  229: {
1.2       millert   230:        static POSITION maxpos100 = 0;
1.1       etheisen  231:
1.2       millert   232:        if (maxpos100 == 0)
                    233:                maxpos100 = get_maxpos() / 100;
                    234:        if (num > maxpos100)
1.1       etheisen  235:                return (num / (den/100));
                    236:        else
                    237:                return (100*num / den);
                    238: }