[BACK]Return to os.c CVS log [TXT][DIR] 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
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1, OPENBSD_7_0_BASE, OPENBSD_7_0, OPENBSD_6_9_BASE, OPENBSD_6_9, OPENBSD_6_8_BASE, OPENBSD_6_8, OPENBSD_6_7_BASE, OPENBSD_6_7, OPENBSD_6_6_BASE, OPENBSD_6_6, HEAD
Changes since 1.17: +0 -1 lines

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));
}