diff options
Diffstat (limited to 'usr.bin/less/os.c')
-rw-r--r-- | usr.bin/less/os.c | 215 |
1 files changed, 152 insertions, 63 deletions
diff --git a/usr.bin/less/os.c b/usr.bin/less/os.c index c4235f81979..ac63960df95 100644 --- a/usr.bin/less/os.c +++ b/usr.bin/less/os.c @@ -1,29 +1,11 @@ -/* $OpenBSD: os.c,v 1.5 2003/03/13 09:09:32 deraadt Exp $ */ - /* - * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman - * All rights reserved. + * Copyright (C) 1984-2002 Mark Nudelman * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice in the documentation and/or other materials provided with - * the distribution. + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * For more information about less, or for information on how to + * contact the author, see the README file. */ @@ -40,7 +22,6 @@ */ #include "less.h" -#include <limits.h> #include <signal.h> #include <setjmp.h> #if HAVE_TIME_H @@ -78,6 +59,8 @@ public int reading; static jmp_buf read_label; +extern int sigs; + /* * Like read() system call, but is deliberately interruptible. * A call to intread() from a signal handler will interrupt @@ -89,9 +72,13 @@ iread(fd, buf, len) char *buf; unsigned int len; { - int n; + register int n; -#if MSOFTC +#if MSDOS_COMPILER==WIN32C + if (ABORT_SIGS()) + return (READ_INTR); +#else +#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC if (kbhit()) { int c; @@ -102,21 +89,71 @@ iread(fd, buf, len) ungetch(c); } #endif +#endif if (SET_JUMP(read_label)) { /* * We jumped here from intread. */ reading = 0; +#if HAVE_SIGPROCMASK + { + sigset_t mask; + sigemptyset(&mask); + sigprocmask(SIG_SETMASK, &mask, NULL); + } +#else #if HAVE_SIGSETMASK sigsetmask(0); +#else +#ifdef _OSK + sigmask(~0); +#endif +#endif #endif return (READ_INTR); } flush(); reading = 1; +#if MSDOS_COMPILER==DJGPPC + if (isatty(fd)) + { + /* + * Don't try reading from a TTY until a character is + * available, because that makes some background programs + * believe DOS is busy in a way that prevents those + * programs from working while "less" waits. + */ + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + if (select(fd+1, &readfds, 0, 0, 0) == -1) + return (-1); + } +#endif n = read(fd, buf, len); +#if 1 + /* + * This is a kludge to workaround a problem on some systems + * where terminating a remote tty connection causes read() to + * start returning 0 forever, instead of -1. + */ + { + extern int ignore_eoi; + if (!ignore_eoi) + { + static int consecutive_nulls = 0; + if (n == 0) + consecutive_nulls++; + else + consecutive_nulls = 0; + if (consecutive_nulls > 20) + quit(QUIT_ERROR); + } + } +#endif reading = 0; if (n < 0) return (-1); @@ -162,7 +199,7 @@ strerror(err) if (err < sys_nerr) return sys_errlist[err]; - snprintf(buf, sizeof buf, "Error %d", err); + snprintf(buf, sizeof(buf), "Error %d", err); return buf; #else return ("cannot open"); @@ -177,11 +214,13 @@ strerror(err) errno_message(filename) char *filename; { - char *p; - char *m; - int len; + register char *p; + register char *m; + size_t len; #if HAVE_ERRNO +#if MUST_DEFINE_ERRNO extern int errno; +#endif p = strerror(errno); #else p = "cannot open"; @@ -193,48 +232,98 @@ errno_message(filename) } /* - * Return the largest possible number that can fit in a POSITION. + * Return the ratio of two POSITIONS, as a percentage. + * {{ Assumes a POSITION is a long int. }} */ -#ifdef QUAD_MAX - static POSITION -get_maxpos() + public int +percentage(num, den) + POSITION num, den; { - return (QUAD_MAX); + POSITION num100 = num * 100; + + if (num100 / 100 == num) + return (num100 / den); + else + return (num / (den / 100)); } -#else - static POSITION -get_maxpos() + +/* + * Return the specified percentage of a POSITION. + */ + public POSITION +percent_pos(pos, percent) + POSITION pos; + int percent; { - POSITION n, n2; + POSITION result100; - /* - * Keep doubling n until we overflow. - * {{ This actually only returns the largest power of two that - * can fit in a POSITION, but percentage() doesn't really need - * it any more accurate than that. }} - */ - n2 = 128; /* Hopefully no maxpos is less than 128! */ - do { - n = n2; - n2 *= 2; - } while (n2 / 2 == n); - return (n); + if (percent == 0) + return (0); + else if ((result100 = pos * percent) / percent == pos) + return (result100 / 100); + else + return (percent * (pos / 100)); +} + +#if !HAVE_STRCHR +/* + * strchr is used by regexp.c. + */ + char * +strchr(s, c) + char *s; + int c; +{ + for ( ; *s != '\0'; s++) + if (*s == c) + return (s); + if (c == '\0') + return (s); + return (NULL); } #endif +#if !HAVE_MEMCPY + VOID_POINTER +memcpy(dst, src, len) + VOID_POINTER dst; + VOID_POINTER src; + int len; +{ + char *dstp = (char *) dst; + char *srcp = (char *) src; + int i; + + for (i = 0; i < len; i++) + dstp[i] = srcp[i]; + return (dst); +} +#endif + +#ifdef _OSK_MWC32 + /* - * Return the ratio of two POSITIONs, as a percentage. + * This implements an ANSI-style intercept setup for Microware C 3.2 */ - public int -percentage(num, den) - POSITION num, den; + public int +os9_signal(type, handler) + int type; + RETSIGTYPE (*handler)(); { - static POSITION maxpos100 = 0; - - if (maxpos100 == 0) - maxpos100 = get_maxpos() / 100; - if (num > maxpos100) - return (num / (den/100)); - else - return (100*num / den); + intercept(handler); } + +#include <sgstat.h> + + int +isatty(f) + int f; +{ + struct sgbuf sgbuf; + + if (_gs_opt(f, &sgbuf) < 0) + return -1; + return (sgbuf.sg_class == 0); +} + +#endif |