xref: /openbsd/usr.bin/less/os.c (revision d65139b4)
1 /*
2  * Copyright (C) 1984-2012  Mark Nudelman
3  * Modified for use with illumos by Garrett D'Amore.
4  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
5  *
6  * You may distribute under the terms of either the GNU General Public
7  * License or the Less License, as specified in the README file.
8  *
9  * For more information, see the README file.
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 <errno.h>
25 #include <signal.h>
26 #include <time.h>
27 
28 #include "less.h"
29 
30 
31 /*
32  * Like read() system call, but is deliberately interruptible.
33  */
34 int
iread(int fd,unsigned char * buf,unsigned int len)35 iread(int fd, unsigned char *buf, unsigned int len)
36 {
37 	int n;
38 
39 start:
40 	flush(0);
41 	n = read(fd, buf, len);
42 	if (n == -1) {
43 		/*
44 		 * Certain values of errno indicate we should just retry the
45 		 * read.
46 		 */
47 		if (errno == EINTR)
48 			return (READ_INTR);
49 		if (errno == EAGAIN)
50 			goto start;
51 		return (-1);
52 	}
53 	return (n);
54 }
55 
56 /*
57  * errno_message: Return an error message based on the value of "errno".
58  */
59 char *
errno_message(char * filename)60 errno_message(char *filename)
61 {
62 	return (easprintf("%s: %s", filename, strerror(errno)));
63 }
64 
65 static off_t
muldiv(off_t val,off_t num,off_t den)66 muldiv(off_t val, off_t num, off_t den)
67 {
68 	double v = (((double)val) * num) / den;
69 	return ((off_t)(v + 0.5));
70 }
71 
72 /*
73  * Return the ratio of two off_t, as a percentage.
74  * {{ Assumes a off_t is a long int. }}
75  */
76 int
percentage(off_t num,off_t den)77 percentage(off_t num, off_t den)
78 {
79 	return ((int)muldiv(num, (off_t)100, den));
80 }
81 
82 /*
83  * Return the specified percentage of a off_t.
84  */
85 off_t
percent_pos(off_t pos,int percent,long fraction)86 percent_pos(off_t pos, int percent, long fraction)
87 {
88 	/*
89 	 * Change percent (parts per 100) to perden
90 	 * (parts per NUM_FRAC_DENOM).
91 	 */
92 	off_t perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100);
93 
94 	if (perden == 0)
95 		return (0);
96 	return (muldiv(pos, perden, (off_t)NUM_FRAC_DENOM));
97 }
98