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