summaryrefslogtreecommitdiff
path: root/usr.bin/less/os.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/less/os.c')
-rw-r--r--usr.bin/less/os.c215
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