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