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 extern volatile sig_atomic_t sigs; 31 32 /* 33 * Like read() system call, but is deliberately interruptible. 34 */ 35 int 36 iread(int fd, unsigned char *buf, unsigned int len) 37 { 38 int n; 39 40 start: 41 flush(0); 42 n = read(fd, buf, len); 43 if (n < 0) { 44 /* 45 * Certain values of errno indicate we should just retry the 46 * read. 47 */ 48 if (errno == EINTR) 49 return (READ_INTR); 50 if (errno == EAGAIN) 51 goto start; 52 return (-1); 53 } 54 return (n); 55 } 56 57 /* 58 * errno_message: Return an error message based on the value of "errno". 59 */ 60 char * 61 errno_message(char *filename) 62 { 63 return (easprintf("%s: %s", filename, strerror(errno))); 64 } 65 66 static off_t 67 muldiv(off_t val, off_t num, off_t den) 68 { 69 double v = (((double)val) * num) / den; 70 return ((off_t)(v + 0.5)); 71 } 72 73 /* 74 * Return the ratio of two off_t, as a percentage. 75 * {{ Assumes a off_t is a long int. }} 76 */ 77 int 78 percentage(off_t num, off_t den) 79 { 80 return ((int)muldiv(num, (off_t)100, den)); 81 } 82 83 /* 84 * Return the specified percentage of a off_t. 85 */ 86 off_t 87 percent_pos(off_t pos, int percent, long fraction) 88 { 89 /* 90 * Change percent (parts per 100) to perden 91 * (parts per NUM_FRAC_DENOM). 92 */ 93 off_t perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100); 94 95 if (perden == 0) 96 return (0); 97 return (muldiv(pos, perden, (off_t)NUM_FRAC_DENOM)); 98 } 99