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 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 * 60 errno_message(char *filename) 61 { 62 return (easprintf("%s: %s", filename, strerror(errno))); 63 } 64 65 static off_t 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 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 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