Annotation of src/usr.bin/less/os.c, Revision 1.7
1.1 etheisen 1: /*
1.6 millert 2: * Copyright (C) 1984-2002 Mark Nudelman
1.1 etheisen 3: *
1.6 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.6 millert 7: * For more information about less, or for information on how to
8: * contact the author, see the README file.
1.1 etheisen 9: */
10:
11:
12: /*
13: * Operating system dependent routines.
14: *
15: * Most of the stuff in here is based on Unix, but an attempt
16: * has been made to make things work on other operating systems.
17: * This will sometimes result in a loss of functionality, unless
18: * someone rewrites code specifically for the new operating system.
19: *
20: * The makefile provides defines to decide whether various
21: * Unix features are present.
22: */
23:
24: #include "less.h"
25: #include <signal.h>
26: #if HAVE_TIME_H
27: #include <time.h>
28: #endif
29: #if HAVE_ERRNO_H
30: #include <errno.h>
31: #endif
32: #if HAVE_VALUES_H
33: #include <values.h>
34: #endif
35:
36: #if HAVE_TIME_T
37: #define time_type time_t
38: #else
39: #define time_type long
40: #endif
41:
1.6 millert 42: extern int sigs;
43:
1.1 etheisen 44: /*
45: * Like read() system call, but is deliberately interruptible.
46: */
47: public int
48: iread(fd, buf, len)
49: int fd;
50: char *buf;
51: unsigned int len;
52: {
1.6 millert 53: register int n;
1.1 etheisen 54:
1.6 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.6 millert 70: #endif
1.1 etheisen 71:
72: flush();
1.6 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.6 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.7 ! millert 112: return (errno == EINTR ? READ_INTR : -1);
1.1 etheisen 113: return (n);
114: }
115:
116: /*
117: * Return the current time.
118: */
119: #if HAVE_TIME
120: public long
121: get_time()
122: {
123: time_type t;
124:
125: time(&t);
126: return (t);
127: }
128: #endif
129:
130:
131: #if !HAVE_STRERROR
132: /*
133: * Local version of strerror, if not available from the system.
134: */
135: static char *
136: strerror(err)
137: int err;
138: {
139: #if HAVE_SYS_ERRLIST
140: static char buf[16];
141: extern char *sys_errlist[];
142: extern int sys_nerr;
143:
144: if (err < sys_nerr)
145: return sys_errlist[err];
1.6 millert 146: snprintf(buf, sizeof(buf), "Error %d", err);
1.1 etheisen 147: return buf;
148: #else
149: return ("cannot open");
150: #endif
151: }
152: #endif
153:
154: /*
155: * errno_message: Return an error message based on the value of "errno".
156: */
157: public char *
158: errno_message(filename)
159: char *filename;
160: {
1.6 millert 161: register char *p;
162: register char *m;
163: size_t len;
1.1 etheisen 164: #if HAVE_ERRNO
1.6 millert 165: #if MUST_DEFINE_ERRNO
1.1 etheisen 166: extern int errno;
1.6 millert 167: #endif
1.1 etheisen 168: p = strerror(errno);
169: #else
170: p = "cannot open";
171: #endif
1.5 deraadt 172: len = strlen(filename) + strlen(p) + 3;
173: m = (char *) ecalloc(len, sizeof(char));
174: snprintf(m, len, "%s: %s", filename, p);
1.1 etheisen 175: return (m);
176: }
177:
178: /*
1.6 millert 179: * Return the ratio of two POSITIONS, as a percentage.
180: * {{ Assumes a POSITION is a long int. }}
181: */
182: public int
183: percentage(num, den)
184: POSITION num, den;
185: {
186: POSITION num100 = num * 100;
187:
188: if (num100 / 100 == num)
189: return (num100 / den);
190: else
191: return (num / (den / 100));
192: }
193:
194: /*
195: * Return the specified percentage of a POSITION.
1.1 etheisen 196: */
1.6 millert 197: public POSITION
198: percent_pos(pos, percent)
199: POSITION pos;
200: int percent;
1.1 etheisen 201: {
1.6 millert 202: POSITION result100;
203:
204: if (percent == 0)
205: return (0);
206: else if ((result100 = pos * percent) / percent == pos)
207: return (result100 / 100);
208: else
209: return (percent * (pos / 100));
1.1 etheisen 210: }
1.6 millert 211:
212: #if !HAVE_STRCHR
213: /*
214: * strchr is used by regexp.c.
215: */
216: char *
217: strchr(s, c)
218: char *s;
219: int c;
1.1 etheisen 220: {
1.6 millert 221: for ( ; *s != '\0'; s++)
222: if (*s == c)
223: return (s);
224: if (c == '\0')
225: return (s);
226: return (NULL);
227: }
228: #endif
1.1 etheisen 229:
1.6 millert 230: #if !HAVE_MEMCPY
231: VOID_POINTER
232: memcpy(dst, src, len)
233: VOID_POINTER dst;
234: VOID_POINTER src;
235: int len;
236: {
237: char *dstp = (char *) dst;
238: char *srcp = (char *) src;
239: int i;
240:
241: for (i = 0; i < len; i++)
242: dstp[i] = srcp[i];
243: return (dst);
1.1 etheisen 244: }
245: #endif
246:
1.6 millert 247: #ifdef _OSK_MWC32
248:
1.1 etheisen 249: /*
1.6 millert 250: * This implements an ANSI-style intercept setup for Microware C 3.2
1.1 etheisen 251: */
1.6 millert 252: public int
253: os9_signal(type, handler)
254: int type;
255: RETSIGTYPE (*handler)();
256: {
257: intercept(handler);
258: }
259:
260: #include <sgstat.h>
261:
262: int
263: isatty(f)
264: int f;
1.1 etheisen 265: {
1.6 millert 266: struct sgbuf sgbuf;
267:
268: if (_gs_opt(f, &sgbuf) < 0)
269: return -1;
270: return (sgbuf.sg_class == 0);
271: }
1.1 etheisen 272:
1.6 millert 273: #endif