Return to os.c CVS log | Up to [local] / src / usr.bin / less |
File: [local] / src / usr.bin / less / os.c (download)
Revision 1.18, Tue Sep 3 23:08:42 2019 UTC (4 years, 8 months ago) by deraadt
less uses a correct raceless signal method of indicating signal events in a volatile sig_atomic_t variable, and then processing events in the mainloop. But only one variable was used for 3 signals, with |= bit operations which are signal interruptable! Rewrite the code to use 3 independent variables and cleanup how the mainloop observes indications. ok schwarze |
/* * Copyright (C) 1984-2012 Mark Nudelman * Modified for use with illumos by Garrett D'Amore. * Copyright 2014 Garrett D'Amore <garrett@damore.org> * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. * * For more information, see the README file. */ /* * Operating system dependent routines. * * Most of the stuff in here is based on Unix, but an attempt * has been made to make things work on other operating systems. * This will sometimes result in a loss of functionality, unless * someone rewrites code specifically for the new operating system. * * The makefile provides defines to decide whether various * Unix features are present. */ #include <errno.h> #include <signal.h> #include <time.h> #include "less.h" /* * Like read() system call, but is deliberately interruptible. */ int iread(int fd, unsigned char *buf, unsigned int len) { int n; start: flush(0); n = read(fd, buf, len); if (n == -1) { /* * Certain values of errno indicate we should just retry the * read. */ if (errno == EINTR) return (READ_INTR); if (errno == EAGAIN) goto start; return (-1); } return (n); } /* * errno_message: Return an error message based on the value of "errno". */ char * errno_message(char *filename) { return (easprintf("%s: %s", filename, strerror(errno))); } static off_t muldiv(off_t val, off_t num, off_t den) { double v = (((double)val) * num) / den; return ((off_t)(v + 0.5)); } /* * Return the ratio of two off_t, as a percentage. * {{ Assumes a off_t is a long int. }} */ int percentage(off_t num, off_t den) { return ((int)muldiv(num, (off_t)100, den)); } /* * Return the specified percentage of a off_t. */ off_t percent_pos(off_t pos, int percent, long fraction) { /* * Change percent (parts per 100) to perden * (parts per NUM_FRAC_DENOM). */ off_t perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100); if (perden == 0) return (0); return (muldiv(pos, perden, (off_t)NUM_FRAC_DENOM)); }