summaryrefslogtreecommitdiffstats
path: root/sys-utils
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:35 +0100
committerKarel Zak2006-12-07 00:25:35 +0100
commit2b6fc908bc368b540845a313c3b8a867c5ad9a42 (patch)
tree6fad48a239bc90515a5dc4084d6e3c3ee1f41e29 /sys-utils
parentImported from util-linux-2.7.1 tarball. (diff)
downloadkernel-qcow2-util-linux-2b6fc908bc368b540845a313c3b8a867c5ad9a42.tar.gz
kernel-qcow2-util-linux-2b6fc908bc368b540845a313c3b8a867c5ad9a42.tar.xz
kernel-qcow2-util-linux-2b6fc908bc368b540845a313c3b8a867c5ad9a42.zip
Imported from util-linux-2.8 tarball.
Diffstat (limited to 'sys-utils')
-rw-r--r--sys-utils/Makefile30
-rw-r--r--sys-utils/arch.119
-rw-r--r--sys-utils/chroot.816
-rw-r--r--sys-utils/chroot.c25
-rw-r--r--sys-utils/cytune.c5
-rw-r--r--sys-utils/dmesg.810
-rw-r--r--sys-utils/dmesg.c16
-rw-r--r--sys-utils/hwclock.8157
-rw-r--r--sys-utils/hwclock.c876
-rw-r--r--sys-utils/kbdrate.c2
-rw-r--r--sys-utils/readprofile.c2
-rw-r--r--sys-utils/renice.c17
-rw-r--r--sys-utils/tunelp.c7
13 files changed, 848 insertions, 334 deletions
diff --git a/sys-utils/Makefile b/sys-utils/Makefile
index 9513717ee..9085fa965 100644
--- a/sys-utils/Makefile
+++ b/sys-utils/Makefile
@@ -11,35 +11,27 @@ include ../MCONFIG
MAN1= arch.1 readprofile.1
-MAN8= chroot.8 ctrlaltdel.8 cytune.8 dmesg.8 \
+MAN8= ctrlaltdel.8 cytune.8 dmesg.8 \
ipcrm.8 ipcs.8 kbdrate.8 ramsize.8 renice.8 \
rootflags.8 setsid.8 swapdev.8 tunelp.8 \
vidmode.8
-ifneq "$(CPU)" "sparc"
-MAN8:= $(MAN8) hwclock.8
-endif
-
-ifeq "$(CPU)" "intel"
-MAN8:= $(MAN8) rdev.8
-endif
-
# Where to put binaries?
# See the "install" rule for the links. . .
+BIN= arch dmesg
+
+USRBIN= cytune ipcrm ipcs renice readprofile setsid tunelp
+
SBIN= sln ctrlaltdel kbdrate
ifneq "$(CPU)" "sparc"
+MAN8:= $(MAN8) hwclock.8
SBIN:=$(SBIN) hwclock
endif
-BIN= arch dmesg
-
-USRSBIN= chroot
-
-USRBIN= cytune ipcrm ipcs renice readprofile setsid tunelp
-
ifeq "$(CPU)" "intel"
+MAN8:= $(MAN8) rdev.8
USRBIN:=$(USRBIN) rdev
endif
@@ -47,7 +39,7 @@ endif
USRINFO= ipc.info
-all: $(SBIN) $(BIN) $(USRSBIN) $(USRBIN)
+all: $(SBIN) $(BIN) $(USRBIN)
sln: sln.c
$(CC) -static $(CFLAGS) $(LDFLAGS) $< -o $@
@@ -55,7 +47,6 @@ sln: sln.c
# Rules for everything else
arch: arch.o
-chroot: chroot.o
hwclock.o: hwclock.c shhopt.h
hwclock: hwclock.o shhopt.o
ctrlaltdel: ctrlaltdel.o
@@ -68,10 +59,9 @@ readprofile: readprofile.o
setsid: setsid.o
install: all
- $(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRSBINDIR) $(USRBINDIR)
+ $(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRBINDIR)
$(INSTALLBIN) $(SBIN) $(SBINDIR)
$(INSTALLBIN) $(BIN) $(BINDIR)
- $(INSTALLBIN) $(USRSBIN) $(USRSBINDIR)
$(INSTALLBIN) $(USRBIN) $(USRBINDIR)
(cd $(USRBINDIR); ln -sf rdev swapdev)
(cd $(USRBINDIR); ln -sf rdev ramsize)
@@ -83,4 +73,4 @@ install: all
$(INSTALLMAN) $(USRINFO) $(INFODIR)
clean:
- -rm -f *.o *~ core $(SBIN) $(BIN) $(USRSBIN) $(USRBIN)
+ -rm -f *.o *~ core $(SBIN) $(BIN) $(USRBIN)
diff --git a/sys-utils/arch.1 b/sys-utils/arch.1
index a2830ed3c..9ce88db51 100644
--- a/sys-utils/arch.1
+++ b/sys-utils/arch.1
@@ -9,10 +9,25 @@ arch \- print machine architecture
.SH DESCRIPTION
.B arch
is equivalent to
-.B uname -m
+.BR "uname -m" .
On current Linux systems,
.B arch
-prints things such as "i386" or "i486".
+prints things such as "i386", "i486", "i586", "alpha", "sparc",
+"arm", "m68k", "mips", "ppc".
.SH SEE ALSO
.BR uname (1) ", " uname (2)
+.\"
+.\" Details:
+.\" arch prints the machine part of the system_utsname struct
+.\" This struct is defined in version.c, and this field is
+.\" initialized with UTS_MACHINE, which is defined as $ARCH
+.\" in the main Makefile.
+.\" That gives the possibilities
+.\" alpha arm i386 m68k mips ppc sparc sparc64
+.\"
+.\" If Makefile is not edited, ARCH is guessed by
+.\" ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
+.\" Then how come we get these i586 values?
+.\" Well, the routine check_bugs() does system_utsname.machine[1] = '0' + x86;
+.\" (called in init/main.c, defined in ./include/asm-i386/bugs.h)
diff --git a/sys-utils/chroot.8 b/sys-utils/chroot.8
deleted file mode 100644
index 4beadbfd4..000000000
--- a/sys-utils/chroot.8
+++ /dev/null
@@ -1,16 +0,0 @@
-.\" Rick Sladkey <jrs@world.std.com>
-.\" In the public domain.
-.\" Pathname modified by faith@cs.unc.edu
-.TH CHROOT 8 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
-.SH NAME
-chroot \- change root directory and execute a program there
-.SH SYNOPSIS
-.BI chroot " directory program" " [ " "arg ..." " ]"
-.SH DESCRIPTION
-.B chroot
-changes the root directory for a process to a new directory
-executes a program there.
-.SH "SEE ALSO"
-.BR chroot (2)
-.SH AUTHOR
-Rick Sladkey <jrs@world.std.com>
diff --git a/sys-utils/chroot.c b/sys-utils/chroot.c
deleted file mode 100644
index 7ddbe791f..000000000
--- a/sys-utils/chroot.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * chroot.c -- change root directory and execute a command there
- * Rick Sladkey <jrs@world.std.com>
- * In the public domain.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-int main(int argc, char *argv[])
-{
- if (argc < 3) {
- fprintf(stderr, "usage: %s directory program [arg ...]\n",
- argv[0]);
- exit(1);
- }
- if (chroot(argv[1]) < 0) {
- perror("chroot");
- exit(1);
- }
- execvp(argv[2], argv + 2);
- perror("execvp");
- exit(1);
-}
diff --git a/sys-utils/cytune.c b/sys-utils/cytune.c
index f7fe1ee38..510703b94 100644
--- a/sys-utils/cytune.c
+++ b/sys-utils/cytune.c
@@ -44,7 +44,10 @@
#include <errno.h>
#include <linux/tty.h>
#include <termios.h>
-#include <linux/tqueue.h>
+#if 0
+#include <linux/tqueue.h> /* required for old kernels */
+ /* compilation errors on other kernels */
+#endif
#include <linux/cyclades.h>
#include <signal.h>
diff --git a/sys-utils/dmesg.8 b/sys-utils/dmesg.8
index d2e4ce1bc..f453d7145 100644
--- a/sys-utils/dmesg.8
+++ b/sys-utils/dmesg.8
@@ -1,10 +1,10 @@
.\" Copyright 1993 Rickard E. Faith (faith@cs.unc.edu)
.\" May be distributed under the GNU General Public License
-.TH DMESG 8 "28 October 1993" "Linux 0.99" "Linux Programmer's Manual"
+.TH DMESG 8
.SH NAME
dmesg \- print or control the kernel ring buffer
.SH SYNOPSIS
-.BI "dmesg [ \-c ] [ \-n " level " ]"
+.BI "dmesg [ \-c ] [ \-n " level " ] [ \-s " bufsize " ]"
.SH DESCRIPTION
.B dmesg
is used to examine or control the kernel ring buffer.
@@ -22,6 +22,12 @@ file to whoever can debug their problem.
.B \-c
clear the ring buffer contents after printing.
.TP
+.BI \-s bufsize
+use a buffer of bufsize to query the kernel ring buffer. This is
+8196 by default (this matches the default kernel syslog buffer size in
+2.0.33 and 2.1.103). If you have set the kernel buffer to larger than
+the default then this option can be used to view the entire buffer.
+.TP
.BI \-n level
set the
.I level
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
index 56beb3fea..bfb488f96 100644
--- a/sys-utils/dmesg.c
+++ b/sys-utils/dmesg.c
@@ -4,6 +4,8 @@
* Copyright 1993 Theodore Ts'o (tytso@athena.mit.edu)
* This program comes with ABSOLUTELY NO WARRANTY.
* Modifications by Rick Sladkey (jrs@world.std.com)
+ * Larger buffersize 3 June 1998 by Nicolai Langfeldt, based on a patch
+ * by Peeter Joot. This was also suggested by John Hudson.
*/
#include <linux/unistd.h>
@@ -29,12 +31,13 @@ static char *progname;
void
usage()
{
- fprintf( stderr, "Usage: %s [-c] [-n level]\n", progname );
+ fprintf( stderr, "Usage: %s [-c] [-n level] [-s bufsize]\n", progname );
}
int main( int argc, char *argv[] )
{
- char buf[4096];
+ char *buf;
+ int bufsize=8196;
int i;
int n;
int c;
@@ -43,7 +46,7 @@ int main( int argc, char *argv[] )
int cmd = 3;
progname = argv[0];
- while ((c = getopt( argc, argv, "cn:" )) != EOF) {
+ while ((c = getopt( argc, argv, "cn:s:" )) != EOF) {
switch (c) {
case 'c':
cmd = 4;
@@ -52,6 +55,9 @@ int main( int argc, char *argv[] )
cmd = 8;
level = atoi(optarg);
break;
+ case 's':
+ bufsize = atoi(optarg);
+ break;
case '?':
default:
usage();
@@ -75,7 +81,9 @@ int main( int argc, char *argv[] )
exit( 0 );
}
- n = klogctl( cmd, buf, sizeof( buf ) );
+ if (bufsize < 4096) bufsize = 4096;
+ buf = (char*)malloc(bufsize);
+ n = klogctl( cmd, buf, bufsize );
if (n < 0) {
perror( "klogctl" );
exit( 1 );
diff --git a/sys-utils/hwclock.8 b/sys-utils/hwclock.8
index a7308a600..ec8b00762 100644
--- a/sys-utils/hwclock.8
+++ b/sys-utils/hwclock.8
@@ -1,18 +1,26 @@
-.TH CLOCK 8 "23 September 1996"
+.TH CLOCK 8 "02 March 1998"
.SH NAME
-clock \- query and set the ISA hardware clock (RTC)
+clock \- query and set the hardware clock (RTC)
.SH SYNOPSIS
-.B "hwclock --show [ --utc ] [ --test ] [ --debug ]"
+.B "hwclock --show"
.br
-.B "hwclock --set --date=newdate [ --utc ] [ --test ] [ --debug ]"
+.B "hwclock --set --date=newdate"
.br
-.B "hwclock --systohc [ --utc ] [ --test ] [ --debug ]"
+.B "hwclock --systohc"
.br
-.B "hwclock --hctosys [ --utc ] [ --test ] [ --debug ]"
+.B "hwclock --hctosys"
.br
-.B "hwclock --adjust [ --utc ] [ --test ] [ --debug ]"
+.B "hwclock --getepoch"
.br
-.B "hwclock --version [ --debug ]
+.B "hwclock --setepoch --epoch=year"
+.br
+.B "hwclock --adjust"
+.br
+.B "hwclock --version"
+.PP
+other options:
+.PP
+.B "--utc --directisa --test --debug"
.PP
Minimum unique abbreviations of all options are acceptable.
.PP
@@ -58,6 +66,23 @@ Add or subtract time from the Hardware Clock to account for systematic
drift since the last time the clock was set or adjusted. See discussion
below.
.TP
+.B \-\-getepoch
+Print out standard output the kernel's Hardware Clock epoch value.
+This is the number of years into AD to which a zero year value in the
+Hardware Clock refers. For example, if you are using the convention
+that the year counter in your Hardware Clock contains the number of
+full years since 1952, then the kernel's Hardware Counter epoch value
+must be 1952.
+
+This epoch value is used whenever hwclock reads or sets the Hardware Clock.
+.TP
+.B \-\-setepoch
+Set the kernel's Hardware Clock epoch value to the value specified by the
+.B \-\-epoch
+option. See the
+.B \-\-getepoch
+option for details.
+.TP
.B \-\-version
Print the version of
.I hwclock
@@ -74,11 +99,21 @@ option is an argument to the
program. For example,
.sp
.I hwclock --set --date="9/22/96 16:45:05"
+.TP
+.B \-\-epoch=year
+Specifies the year which is the beginning of the Hardware Clock's
+epoch. I.e. the number of years into AD to which a zero value in the
+Hardware Clock's year counter refers.
+
+For example,
+.sp
+.I hwclock --setepoch --epoch=1952
+
.PP
The following options apply to most functions.
.TP
.B \-\-utc
-Indicates that the Hardware Clock is kept in Universal Coordinated
+Indicates that the Hardware Clock is kept in Coordinated Universal
Time. It is your choice whether to keep your clock in UTC or local
time, but nothing in the clock tells which you've chosen. So this
option is how you give that information to
@@ -89,9 +124,22 @@ If you don't specify
when you should, or vice versa, both setting and querying of the
Hardware Clock will be messed up.
.TP
+.B \-\-directisa
+is meaningful only on an ISA machine. For all other machines, it has
+no effect. This option tells
+.I hwclock
+to use explicit I/O instructions to access the Hardware Clock.
+Without this option,
+.I hwclock
+will try to use the /dev/rtc device (which it assumes to be driven by the
+rtc device driver). If it is unable to open the device (for read), it will
+use the explicit I/O instructions anyway.
+.PP
+The rtc device driver was new in Linux Release 2.
+.TP
.B \-\-test
-Do everything except actually updating the Hardware Clock. This is
-useful, especially in conjunction with
+Do everything except actually updating the Hardware Clock or anything
+else. This is useful, especially in conjunction with
.B \-\-debug,
in learning about
.I hwclock.
@@ -112,11 +160,12 @@ There are two main clocks in a Linux system:
.PP
.B The Hardware Clock:
This is a clock that runs independently of any control program running
-in the CPU and even when the machine is powered off. It is specified
-as part of the ISA standard. The control program can read or set this
-clock to a whole second, but the control program can also detect the
-edges of the 1 second clock ticks, so the clock actually has virtually
-infinite precision.
+in the CPU and even when the machine is powered off.
+
+On an ISA system, this clock is specified as part of the ISA standard.
+The control program can read or set this clock to a whole second, but
+the control program can also detect the edges of the 1 second clock
+ticks, so the clock actually has virtually infinite precision.
.PP
This clock is commonly called the hardware clock, the real time clock,
the RTC, the BIOS clock, and the CMOS clock. Hardware Clock, in its
@@ -127,11 +176,12 @@ misleading.
.PP
.B The System Time:
This is the time kept by a clock inside the Linux kernel and driven by
-the ISA timer interrupt. It has meaning only while Linux is running
-on the machine. The System Time is the number of seconds since
-00:00:00 January 1, 1970 UTC (or more succinctly, the number of
-seconds since 1969). The System Time is not an integer, though. It
-has virtually infinite precision.
+a timer interrupt. (On an ISA machine, the timer interrupt is part of
+the ISA standard). It has meaning only while Linux is running on the
+machine. The System Time is the number of seconds since 00:00:00
+January 1, 1970 UTC (or more succinctly, the number of seconds since
+1969). The System Time is not an integer, though. It has virtually
+infinite precision.
.PP
The System Time is the time that matters. The Hardware Clock's basic
purpose in a Linux system is to keep time when Linux is not running. You
@@ -150,6 +200,66 @@ Clock. You can also use the program
to smoothly adjust the System Time while the system runs.
+.SH How hwclock Accesses the Hardware Clock
+.PP
+.I
+hwclock
+Uses many different ways to get and set Hardware Clock values.
+The most normal way is to do I/O to the device special file /dev/rtc,
+which is presumed to be driven by the rtc device driver. However,
+this method is not always available. For one thing, the rtc driver is
+a relatively recent addition to Linux. Older systems don't have it.
+.PP
+On older systems, the method of accessing the Hardware Clock depends on
+the system hardware.
+.PP
+On an ISA system,
+.I
+hwclock
+can directly access the "CMOS memory" registers that constitute the clock,
+by doing I/O to Ports 0x70 and 0x71. It can only do this if running with
+superuser effective userid.
+
+This is a really poor method of accessing the clock, for all the
+reasons that user space programs are generally not supposed to do
+direct I/O and disable interrupts. Hwclock provides it because it is
+the only method available with older Linux kernels for ISA machines.
+
+.PP
+On an m68k system,
+.I
+hwclock
+can access the clock via the console driver, via the device special
+file /dev/tty1.
+.PP
+On an Alpha,
+.I
+/dev/rtc
+is the only choice.
+
+There are or were some Alpha Linux systems that don't have /dev/rtc
+and there are or were programs that accessed the clock via almost
+direct I/O using /dev/port. However, this is not as good a method as
+/dev/rtc and such programs were not widely enough used that hwclock
+has any need to be backward compatible with them. So hwclock does not
+provide the /dev/port method and consequently will not work on an
+Alpha that doesn't have /dev/rtc.
+
+.PP
+.I
+hwclock
+tries to use /dev/rtc. If it is compiled for a kernel that doesn't have
+that function or it is unable to open /dev/rtc,
+.I
+hwclock
+will fall back to another method, if available. On an ISA
+machine, you can force
+.I
+hwclock
+to use the direct manipulation of the CMOS registers without even trying
+/dev/rtc by specifying the --directisa option.
+
+
.SH The Adjust Function
.PP
The Hardware Clock is usually not very accurate. However, much of its
@@ -210,7 +320,7 @@ will do the adjustment then.
It is good to do a
.I hwclock --adjust
just before the
-.I hwclock --set
+.I hwclock --hctosys
at system startup time, and maybe periodically while the system is
running via cron.
.PP
@@ -238,7 +348,8 @@ program with
adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1)
.SH AUTHORS
-Written By Bryan Henderson, September 1996, based on work done on the
+Written By Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
+based on work done on the
.I clock
program by Charles Hedrick, Rob Hooft, and Harald Koenig. See the source
code for complete history and credits.
diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
index 9f4d77149..643ccda5b 100644
--- a/sys-utils/hwclock.c
+++ b/sys-utils/hwclock.c
@@ -8,7 +8,7 @@
See man page for details.
- By Bryan Henderson, 96.09.19
+ By Bryan Henderson, 96.09.19. bryanh@giraffe-data.com
Based on work by others; see history at end of source code.
@@ -26,7 +26,7 @@
The program is designed to run setuid superuser, since we need to be
able to do direct I/O. (More to the point: we need permission to
- execute the iopl() system call.) (However, if you use one of the
+ execute the iopl() system call). (However, if you use one of the
methods other than direct ISA I/O to access the clock, no setuid is
required).
@@ -59,9 +59,9 @@
integral number of seconds. N.B. The Hardware Clock can only be set
in integral seconds.
- If we're setting the clock to the system clock value, we wait for it
- to reach the top of a second, and then set the Hardware Clock to the
- system clock's value.
+ If we're setting the clock to the system clock value, we wait for
+ the system clock to reach the top of a second, and then set the
+ Hardware Clock to the system clock's value.
Here's an interesting point about setting the Hardware Clock: On my
machine, when you set it, it sets to that precise time. But one can
@@ -71,6 +71,23 @@
complications that might cause, we set the clock as soon as possible
after an oscillator tick.
+
+ About synchronizing to the Hardware Clock when reading the time: The
+ precision of the Hardware Clock counters themselves is one second.
+ You can't read the counters and find out that is 12:01:02.5. But if
+ you consider the location in time of the counter's ticks as part of
+ its value, then its precision is as infinite as time is continuous!
+ What I'm saying is this: To find out the _exact_ time in the
+ hardware clock, we wait until the next clock tick (the next time the
+ second counter changes) and measure how long we had to wait. We
+ then read the value of the clock counters and subtract the wait time
+ and we know precisely what time it was when we set out to query the
+ time.
+
+ hwclock uses this method, and considers the Hardware Clock to have
+ infinite precision.
+
+
Enhancements needed:
- When waiting for whole second boundary in set_hardware_clock_exact,
@@ -79,8 +96,6 @@
****************************************************************************/
-#define _GNU_SOURCE /* for snprintf */
-
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
@@ -96,7 +111,7 @@
#include "../version.h"
#define MYNAME "hwclock"
-#define VERSION "2.1"
+#define VERSION "2.2"
#define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
@@ -129,7 +144,7 @@ struct adjtime {
};
-enum clock_access_method {ISA, RTC_IOCTL, KD};
+enum clock_access_method {ISA, RTC_IOCTL, KD, NOCLOCK};
/* A method for accessing (reading, writing) the hardware clock:
ISA:
@@ -140,14 +155,14 @@ enum clock_access_method {ISA, RTC_IOCTL, KD};
via the rtc device driver, using device special file /dev/rtc.
KD:
- via the console driver, using device special file /dev/console.
- This is the m64k ioctl interface.
+ via the console driver, using device special file /dev/tty1.
+ This is the m68k ioctl interface, known as KDGHWCLK.
NO_CLOCK:
- Unable to determine a accessmethod for the system clock.
+ Unable to determine a usable access method for the system clock.
*/
-
+#ifdef __i386__
/* The following are just constants. Oddly, this program will not
compile if the inb() and outb() functions use something even
slightly different from these variables. This is probably at least
@@ -157,12 +172,24 @@ enum clock_access_method {ISA, RTC_IOCTL, KD};
*/
static unsigned short clock_ctl_addr = 0x70;
static unsigned short clock_data_addr = 0x71;
+#endif
bool debug;
/* We are running in debug mode, wherein we put a lot of information about
- what we're doing to standard error. Because of the pervasive and yet
+ what we're doing to standard output. Because of the pervasive and yet
background nature of this value, this is a global variable. */
+bool interrupts_enabled;
+ /* Interrupts are enabled as normal. We, unfortunately, turn interrupts
+ on the machine off in some places where we do the direct ISA accesses
+ to the Hardware Clock. It is in extremely poor form for a user space
+ program to do this, but that's the price we have to pay to run on an
+ ISA machine without the rtc driver in the kernel.
+
+ Code which turns interrupts off uses this value to determine if they
+ need to be turned back on.
+ */
+
#include <linux/version.h>
/* Check if the /dev/rtc interface is available in this version of
@@ -173,11 +200,35 @@ bool debug;
#include <linux/kd.h>
static const bool got_rtc = TRUE;
#else
-/* Dummy to make it compile */
-#define RTC_SET_TIME 0
static const bool got_rtc = FALSE;
+/* Dummy definitions to make it compile. If any lines containing these
+ macros ever execute, there is a bug in the code.
+ */
+#define RTC_SET_TIME -1
+#define RTC_RD_TIME -1
+#define RTC_UIE_ON -1
+#define RTC_UIE_OFF -1
#endif
+/* The RTC_EPOCH_READ and RTC_EPOCH_SET macros are supposed to be
+ defined by linux/mc146818rtc.h, included above. However, these are
+ recent inventions and at the time of this writing, not in any
+ official Linux. Since these values aren't even necessary for most
+ uses of hwclock, we don't want compilation to depend on the user
+ having some arcane version of this header file on his system. Thus,
+ we define the macros ourselves if the header file failed to do so.
+ 98.03.03.
+*/
+
+#ifndef RTC_EPOCH_READ
+#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
+ /* Not all kernels have this ioctl */
+#endif
+
+#ifndef RTC_EPOCH_SET
+#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
+ /* Not all kernels have this ioctl */
+#endif
#if defined(KDGHWCLK)
@@ -187,13 +238,54 @@ static const int kdshwclk_ioctl = KDSHWCLK;
#else
static const bool got_kdghwclk = FALSE;
static const int kdghwclk_ioctl; /* Never used; just to make compile work */
-struct hwclk_time {char dummy;};
+struct hwclk_time {int sec;};
/* Never used; just to make compile work */
#endif
+/* We're going to assume that if the CPU is in the Intel x86 family,
+ this is an ISA family machine. For all practical purposes, this is
+ the case at the time of this writing, especially after we assume a
+ Linux kernel is running on it.
+ */
+const bool isa_machine =
+#ifdef __i386__
+TRUE
+#else
+FALSE;
+#endif
+;
+
+const bool alpha_machine =
+#ifdef __alpha__
+TRUE
+#else
+FALSE;
+#endif
+;
-float
+
+
+static int
+i386_iopl(const int level) {
+/*----------------------------------------------------------------------------
+ When compiled for an Intel target, this is just the iopl() kernel call.
+ When compiled for any other target, this is a dummy function.
+
+ We do it this way in order to keep the conditional compilation stuff
+ out of the way so it doesn't mess up readability of the code.
+-----------------------------------------------------------------------------*/
+#ifdef __i386__
+ extern int iopl(const int level);
+ return iopl(level);
+#else
+ return -1;
+#endif
+}
+
+
+
+static float
time_diff(struct timeval subtrahend, struct timeval subtractor) {
/*---------------------------------------------------------------------------
The difference in seconds between two times in "timeval" format.
@@ -203,7 +295,7 @@ time_diff(struct timeval subtrahend, struct timeval subtractor) {
}
-struct timeval
+static struct timeval
time_inc(struct timeval addend, float increment) {
/*----------------------------------------------------------------------------
The time, in "timeval" format, which is <increment> seconds after
@@ -231,18 +323,28 @@ static inline unsigned char
hclock_read(unsigned char reg) {
/*---------------------------------------------------------------------------
Relative byte <reg> of the Hardware Clock value.
+
+ On non-ISA machine, just return 0.
---------------------------------------------------------------------------*/
-#ifdef __i386__
register unsigned char ret;
+#ifdef __i386__
+ const bool interrupts_were_enabled = interrupts_enabled;
+
__asm__ volatile ("cli");
+ interrupts_enabled = FALSE;
/* & 0x7f ensures that we are not disabling NMI while we read.
Setting on Bit 7 here would disable NMI
*/
outb(reg & 0x7f, clock_ctl_addr);
ret = inb(clock_data_addr);
- __asm__ volatile ("sti");
- return ret;
+ if (interrupts_were_enabled) {
+ __asm__ volatile ("sti");
+ interrupts_enabled = TRUE;
+ }
+#else
+ ret = 0;
#endif
+ return ret;
}
@@ -251,6 +353,8 @@ static inline void
hclock_write(unsigned char reg, unsigned char val) {
/*----------------------------------------------------------------------------
Set relative byte <reg> of the Hardware Clock value to <val>.
+
+ On non-ISA machine, do nothing.
----------------------------------------------------------------------------*/
#ifdef __i386__
/* & 0x7f ensures that we are not disabling NMI while we read.
@@ -276,7 +380,7 @@ hclock_write_bcd(int addr, int value) {
}
-void
+static void
read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
/*----------------------------------------------------------------------------
Read the adjustment parameters out of the /etc/adjtime file.
@@ -348,7 +452,7 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
-void
+static void
synchronize_to_clock_tick_ISA(int *retcode_p) {
/*----------------------------------------------------------------------------
Same as synchronize_to_clock_tick(), but just for ISA.
@@ -371,14 +475,56 @@ synchronize_to_clock_tick_ISA(int *retcode_p) {
-void
+static void
+busywait_for_rtc_clock_tick(const int rtc_fd, int *retcode_p) {
+/*----------------------------------------------------------------------------
+ Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
+ we see it.
+-----------------------------------------------------------------------------*/
+ struct tm start_time;
+ /* The time when we were called (and started waiting) */
+ int rc;
+
+ if (debug)
+ printf("Waiting in loop for time from /dev/rtc to change\n");
+
+ rc = ioctl(rtc_fd, RTC_RD_TIME, &start_time);
+ if (rc == -1) {
+ fprintf(stderr, "ioctl() to /dev/rtc to read time failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 1;
+ } else {
+ /* Wait for change. Should be within a second, but in case something
+ weird happens, we have a limit on this loop to reduce the impact
+ of this failure.
+ */
+ struct tm nowtime;
+ int i; /* local loop index */
+ int rc; /* Return code from ioctl */
+
+ for (i = 0;
+ (rc = ioctl(rtc_fd, RTC_RD_TIME, &nowtime)) != -1
+ && start_time.tm_sec == nowtime.tm_sec && i < 1000000;
+ i++);
+ if (i >= 1000000) {
+ fprintf(stderr, "Timed out waiting for time change.\n");
+ *retcode_p = 2;
+ } else if (rc == -1) {
+ fprintf(stderr, "ioctl() to /dev/rtc to read time failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 3;
+ } else *retcode_p = 0;
+ }
+}
+
+
+
+static void
synchronize_to_clock_tick_RTC(int *retcode_p) {
/*----------------------------------------------------------------------------
Same as synchronize_to_clock_tick(), but just for /dev/rtc.
-----------------------------------------------------------------------------*/
-#if defined(_MC146818RTC_H)
- int rc; /* local return code */
- int rtc_fd; /* File descriptor of /dev/rtc */
+int rtc_fd; /* File descriptor of /dev/rtc */
rtc_fd = open("/dev/rtc",O_RDONLY);
if (rtc_fd == -1) {
@@ -386,45 +532,97 @@ synchronize_to_clock_tick_RTC(int *retcode_p) {
strerror(errno), errno);
*retcode_p = 1;
} else {
+ int rc; /* Return code from ioctl */
/* Turn on update interrupts (one per second) */
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
- if (rc == -1) {
- fprintf(stderr, "ioctl() to /dev/rtc to turn on update interrupts "
- "failed, errno = %s (%d).\n", strerror(errno), errno);
- *retcode_p = 1;
- } else {
+ if (rc == -1 && errno == EINVAL) {
+ /* This rtc device doesn't have interrupt functions. This is typical
+ on an Alpha, where the Hardware Clock interrupts are used by the
+ kernel for the system clock, so aren't at the user's disposal.
+ */
+ if (debug) printf("/dev/rtc does not have interrupt functions. ");
+ busywait_for_rtc_clock_tick(rtc_fd, retcode_p);
+ } else if (rc != -1) {
+ int rc; /* return code from ioctl */
unsigned long dummy;
- /* this blocks */
- rc = read(rtc_fd, &dummy, sizeof(unsigned long));
+ /* this blocks until the next update interrupt */
+ rc = read(rtc_fd, &dummy, sizeof(dummy));
if (rc == -1) {
fprintf(stderr, "read() to /dev/rtc to wait for clock tick failed, "
"errno = %s (%d).\n", strerror(errno), errno);
*retcode_p = 1;
} else {
*retcode_p = 0;
-
- /* Turn off update interrupts */
- rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
- if (rc == -1) {
- fprintf(stderr, "ioctl() to /dev/rtc to turn off update interrupts "
- "failed, errno = %s (%d).\n", strerror(errno), errno);
- }
}
+ /* Turn off update interrupts */
+ rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
+ if (rc == -1) {
+ fprintf(stderr, "ioctl() to /dev/rtc to turn off update interrupts "
+ "failed, errno = %s (%d).\n", strerror(errno), errno);
+ }
+ } else {
+ fprintf(stderr, "ioctl() to /dev/rtc to turn on update interrupts "
+ "failed unexpectedly, errno = %s (%d).\n",
+ strerror(errno), errno);
+ *retcode_p = 1;
}
close(rtc_fd);
}
-#else
-/* This function should never be called. It is here just to make the
- program compile.
-*/
-#endif
}
-
-int
-synchronize_to_clock_tick(enum clock_access_method clock_access) {
+
+static void
+synchronize_to_clock_tick_KD(int *retcode_p) {
+/*----------------------------------------------------------------------------
+ Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until
+ we see it.
+-----------------------------------------------------------------------------*/
+ int con_fd;
+
+ if (debug)
+ printf("Waiting in loop for time from KDGHWCLK to change\n");
+
+ con_fd = open("/dev/tty1", O_RDONLY);
+ if (con_fd < 0) {
+ fprintf(stderr, "open() failed to open /dev/tty1, errno = %s (%d).\n",
+ strerror(errno), errno);
+ *retcode_p = 1;
+ } else {
+ int rc; /* return code from ioctl() */
+ int i; /* local loop index */
+ /* The time when we were called (and started waiting) */
+ struct hwclk_time start_time, nowtime;
+
+ rc = ioctl(con_fd, kdghwclk_ioctl, &start_time);
+ if (rc == -1) {
+ fprintf(stderr, "KDGHWCLK to read time failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 3;
+ }
+
+ for (i = 0;
+ (rc = ioctl(con_fd, kdghwclk_ioctl, &nowtime)) != -1
+ && start_time.sec == nowtime.sec && i < 1000000;
+ i++);
+ if (i >= 1000000) {
+ fprintf(stderr, "Timed out waiting for time change.\n");
+ *retcode_p = 2;
+ } else if (rc == -1) {
+ fprintf(stderr, "KDGHWCLK to read time failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 3;
+ } else *retcode_p = 0;
+ close(con_fd);
+ }
+}
+
+
+
+static void
+synchronize_to_clock_tick(enum clock_access_method clock_access,
+ int *retcode_p) {
/*-----------------------------------------------------------------------------
Wait until the falling edge of the Hardware Clock's update flag so
that any time that is read from the clock immediately after we
@@ -440,35 +638,27 @@ synchronize_to_clock_tick(enum clock_access_method clock_access) {
just return immediately. This will mess some things up, but it's the
best we can do.
- Return 1 if something weird goes wrong (nothing can normally go wrong),
- 0 if everything OK.
+ Return *retcode_p == 0 if it worked, nonzero if it didn't.
-----------------------------------------------------------------------------*/
- int retcode; /* our eventual return code */
-
if (debug) printf("Waiting for clock tick...\n");
switch (clock_access) {
- case ISA: synchronize_to_clock_tick_ISA(&retcode); break;
- case RTC_IOCTL: synchronize_to_clock_tick_RTC(&retcode); break;
- case KD:
- if (debug)
- printf("Can't wait for clock tick because we're using the Alpha "
- "/dev/console clock! Assuming a clock tick.\n");
- retcode = 1;
- break;
+ case ISA: synchronize_to_clock_tick_ISA(retcode_p); break;
+ case RTC_IOCTL: synchronize_to_clock_tick_RTC(retcode_p); break;
+ case KD: synchronize_to_clock_tick_KD(retcode_p); break;
default:
fprintf(stderr, "Internal error in synchronize_to_clock_tick. Invalid "
"value for clock_access argument.\n");
- retcode = 1;
+ *retcode_p = 1;
}
if (debug) printf("...got clock tick\n");
- return(retcode);
+ return;
}
-time_t
+static time_t
mktime_tz(struct tm tm, const bool universal) {
/*-----------------------------------------------------------------------------
Convert a time in broken down format (hours, minutes, etc.) into standard
@@ -489,7 +679,7 @@ mktime_tz(struct tm tm, const bool universal) {
if (universal) {
/* Set timezone to UTC */
- (void) putenv("TZ=");
+ setenv("TZ", "", TRUE);
/* Note: tzset() gets called implicitly by the time code, but only the
first time. When changing the environment variable, better call
tzset() explicitly.
@@ -504,10 +694,8 @@ mktime_tz(struct tm tm, const bool universal) {
}
/* now put back the original zone. */
- if (zone)
- setenv ("TZ", zone, 1);
- else
- putenv ("TZ");
+ if (zone) setenv("TZ", zone, TRUE);
+ else unsetenv("TZ");
tzset();
if (debug)
@@ -519,20 +707,23 @@ mktime_tz(struct tm tm, const bool universal) {
-void
+static void
read_hardware_clock_kd(struct tm *tm) {
/*----------------------------------------------------------------------------
Read the hardware clock and return the current time via <tm>
- argument. Use ioctls to /dev/console on what we assume is an Alpha
+ argument. Use ioctls to /dev/tty1 on what we assume is an m68k
machine.
+
+ Note that we don't use /dev/console here. That might be a serial
+ console.
-----------------------------------------------------------------------------*/
#ifdef KDGHWCLK
int con_fd;
struct hwclk_time t;
- con_fd = open("/dev/console", O_RDONLY);
+ con_fd = open("/dev/tty1", O_RDONLY);
if (con_fd < 0) {
- fprintf(stderr, "open() failed to open /dev/console, errno = %s (%d).\n",
+ fprintf(stderr, "open() failed to open /dev/tty1, errno = %s (%d).\n",
strerror(errno), errno);
exit(5);
} else {
@@ -540,7 +731,7 @@ read_hardware_clock_kd(struct tm *tm) {
rc = ioctl(con_fd, kdghwclk_ioctl, &t);
if (rc == -1) {
- fprintf(stderr, "ioctl() failed to read time from /dev/console, "
+ fprintf(stderr, "ioctl() failed to read time from /dev/tty1, "
"errno = %s (%d).\n",
strerror(errno), errno);
exit(5);
@@ -565,7 +756,7 @@ read_hardware_clock_kd(struct tm *tm) {
-void
+static void
read_hardware_clock_rtc_ioctl(struct tm *tm) {
/*----------------------------------------------------------------------------
Read the hardware clock and return the current time via <tm>
@@ -600,52 +791,85 @@ read_hardware_clock_rtc_ioctl(struct tm *tm) {
-void
+static void
read_hardware_clock_isa(struct tm *tm) {
/*----------------------------------------------------------------------------
Read the hardware clock and return the current time via <tm> argument.
Assume we have an ISA machine and read the clock directly with CPU I/O
instructions.
+
+ This function is not totally reliable. It takes a finite and
+ unpredictable amount of time to execute the code below. During that
+ time, the clock may change and we may even read an invalid value in
+ the middle of an update. We do a few checks to minimize this
+ possibility, but only the kernel can actually read the clock
+ properly, since it can execute code in a short and predictable
+ amount of time (by turning of interrupts).
+
+ In practice, the chance of this function returning the wrong time is
+ extremely remote.
+
-----------------------------------------------------------------------------*/
- /* The loop here is just for integrity. In theory it should never run
- more than once
- */
- do {
- tm->tm_sec = hclock_read_bcd(0);
- tm->tm_min = hclock_read_bcd(2);
- tm->tm_hour = hclock_read_bcd(4);
- tm->tm_wday = hclock_read_bcd(6);
- tm->tm_mday = hclock_read_bcd(7);
- tm->tm_mon = hclock_read_bcd(8);
- tm->tm_year = hclock_read_bcd(9);
- if (hclock_read_bcd(50) == 0) {
- /* I suppose Linux could run on an old machine that doesn't implement
- the Byte 50 century value, and that if it does, that machine puts
- zero in Byte 50. If so, this could could be useful, in that it
- makes values 70-99 -> 1970-1999 and 00-69 -> 2000-2069.
- */
- if (hclock_read_bcd(9) >= 70) tm->tm_year = hclock_read_bcd(9);
- else tm->tm_year = hclock_read_bcd(9) + 100;
- } else {
- tm->tm_year = hclock_read_bcd(50) * 100 + hclock_read_bcd(9) - 1900;
- /* Note: Byte 50 contains centuries since A.D. Byte 9 contains
- years since beginning of century. tm_year contains years
- since 1900. At least we _assume_ that's what tm_year
- contains. It is documented only as "year", and it could
- conceivably be years since the beginning of the current
- century. If so, this code won't work after 1999.
+ bool got_time;
+ /* We've successfully read a time from the Hardware Clock */
+
+ got_time = FALSE;
+ while (!got_time) {
+ /* Bit 7 of Byte 10 of the Hardware Clock value is the Update In Progress
+ (UIP) bit, which is on while and 244 uS before the Hardware Clock
+ updates itself. It updates the counters individually, so reading
+ them during an update would produce garbage. The update takes 2mS,
+ so we could be spinning here that long waiting for this bit to turn
+ off.
+
+ Furthermore, it is pathologically possible for us to be in this
+ code so long that even if the UIP bit is not on at first, the
+ clock has changed while we were running. We check for that too,
+ and if it happens, we start over.
+ */
+
+ if ((hclock_read(10) & 0x80) == 0) {
+ /* No clock update in progress, go ahead and read */
+ tm->tm_sec = hclock_read_bcd(0);
+ tm->tm_min = hclock_read_bcd(2);
+ tm->tm_hour = hclock_read_bcd(4);
+ tm->tm_wday = hclock_read_bcd(6) - 3;
+ tm->tm_mday = hclock_read_bcd(7);
+ tm->tm_mon = hclock_read_bcd(8) - 1;
+ tm->tm_year = hclock_read_bcd(9);
+ if (hclock_read_bcd(50) == 0) {
+ /* I suppose Linux could run on an old machine that doesn't implement
+ the Byte 50 century value, and that if it does, that machine puts
+ zero in Byte 50. If so, this could could be useful, in that it
+ makes values 70-99 -> 1970-1999 and 00-69 -> 2000-2069.
+ */
+ if (hclock_read_bcd(9) >= 70) tm->tm_year = hclock_read_bcd(9);
+ else tm->tm_year = hclock_read_bcd(9) + 100;
+ } else {
+ tm->tm_year = hclock_read_bcd(50) * 100 + hclock_read_bcd(9) - 1900;
+ /* Note: Byte 50 contains centuries since A.D. Byte 9 contains
+ years since beginning of century. tm_year contains years
+ since 1900. At least we _assume_ that's what tm_year
+ contains. It is documented only as "year", and it could
+ conceivably be years since the beginning of the current
+ century. If so, this code won't work after 1999.
+ */
+ }
+ /* Unless the clock changed while we were reading, consider this
+ a good clock read .
*/
+ if (tm->tm_sec == hclock_read_bcd (0)) got_time = TRUE;
+ /* Yes, in theory we could have been running for 60 seconds and
+ the above test wouldn't work!
+ */
}
- } while (tm->tm_sec != hclock_read_bcd (0));
-
- tm->tm_mon--; /* DOS uses 1 base */
- tm->tm_wday -= 3; /* DOS uses 3 - 9 for week days */
+ }
tm->tm_isdst = -1; /* don't know whether it's daylight */
}
-void
+static void
read_hardware_clock(const enum clock_access_method method, struct tm *tm){
/*----------------------------------------------------------------------------
Read the hardware clock and return the current time via <tm> argument.
@@ -674,39 +898,41 @@ read_hardware_clock(const enum clock_access_method method, struct tm *tm){
-void
+static void
set_hardware_clock_kd(const struct tm new_broken_time,
const bool testing) {
/*----------------------------------------------------------------------------
Set the Hardware Clock to the time <new_broken_time>. Use ioctls to
- /dev/console on what we assume is an Alpha machine.
+ /dev/tty1 on what we assume is an m68k machine.
+
+ Note that we don't use /dev/console here. That might be a serial console.
----------------------------------------------------------------------------*/
#ifdef KDGHWCLK
- int con_fd; /* File descriptor of /dev/console */
+ int con_fd; /* File descriptor of /dev/tty1 */
struct hwclk_time t;
- con_fd = open("/dev/console", O_RDONLY);
+ con_fd = open("/dev/tty1", O_RDONLY);
if (con_fd < 0) {
- fprintf(stderr, "Error opening /dev/console. Errno: %s (%d)\n",
+ fprintf(stderr, "Error opening /dev/tty1. Errno: %s (%d)\n",
strerror(errno), errno);
exit(1);
} else {
int rc; /* locally used return code */
- t.sec = new_broken_time->tm_sec;
- t.min = new_broken_time->tm_min;
- t.hour = new_broken_time->tm_hour;
- t.day = new_broken_time->tm_mday;
- t.mon = new_broken_time->tm_mon;
- t.year = new_broken_time->tm_year;
- t.wday = new_broken_time->tm_wday;
+ t.sec = new_broken_time.tm_sec;
+ t.min = new_broken_time.tm_min;
+ t.hour = new_broken_time.tm_hour;
+ t.day = new_broken_time.tm_mday;
+ t.mon = new_broken_time.tm_mon;
+ t.year = new_broken_time.tm_year;
+ t.wday = new_broken_time.tm_wday;
if (testing)
printf("Not setting Hardware Clock because running in test mode.\n");
else {
rc = ioctl(con_fd, kdshwclk_ioctl, &t );
if (rc < 0) {
- fprintf(stderr, "ioctl() to open /dev/console failed. "
+ fprintf(stderr, "ioctl() to open /dev/tty1 failed. "
"Errno: %s (%d)\n",
strerror(errno), errno);
exit(1);
@@ -723,7 +949,7 @@ set_hardware_clock_kd(const struct tm new_broken_time,
-void
+static void
set_hardware_clock_rtc_ioctl(const struct tm new_broken_time,
const bool testing) {
/*----------------------------------------------------------------------------
@@ -739,14 +965,19 @@ set_hardware_clock_rtc_ioctl(const struct tm new_broken_time,
strerror(errno), errno);
exit(5);
} else {
- rc = ioctl(rtc_fd, RTC_SET_TIME, &new_broken_time);
- if (rc == -1) {
- fprintf(stderr, "ioctl() (RTC_SET_TIME) to /dev/rtc to set time failed, "
- "errno = %s (%d).\n", strerror(errno), errno);
- exit(5);
- } else {
- if (debug)
- fprintf(stderr, "ioctl(RTC_SET_TIME) was successful.\n");
+ if (testing)
+ printf("Not setting Hardware Clock because running in test mode.\n");
+ else {
+ rc = ioctl(rtc_fd, RTC_SET_TIME, &new_broken_time);
+ if (rc == -1) {
+ fprintf(stderr,
+ "ioctl() (RTC_SET_TIME) to /dev/rtc to set time failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ exit(5);
+ } else {
+ if (debug)
+ printf("ioctl(RTC_SET_TIME) was successful.\n");
+ }
}
close(rtc_fd);
}
@@ -754,7 +985,7 @@ set_hardware_clock_rtc_ioctl(const struct tm new_broken_time,
-void
+static void
set_hardware_clock_isa(const struct tm new_broken_time,
const bool testing) {
/*----------------------------------------------------------------------------
@@ -763,12 +994,16 @@ set_hardware_clock_isa(const struct tm new_broken_time,
an ISA Hardware Clock.
----------------------------------------------------------------------------*/
unsigned char save_control, save_freq_select;
+#ifdef __i386__
+ const bool interrupts_were_enabled = interrupts_enabled;
+#endif
if (testing)
printf("Not setting Hardware Clock because running in test mode.\n");
else {
#ifdef __i386__
__asm__ volatile ("cli");
+ interrupts_enabled = FALSE;
#endif
save_control = hclock_read(11); /* tell the clock it's being set */
hclock_write(11, (save_control | 0x80));
@@ -801,13 +1036,16 @@ set_hardware_clock_isa(const struct tm new_broken_time,
hclock_write (11, save_control);
hclock_write (10, save_freq_select);
#ifdef __i386__
- __asm__ volatile ("sti");
+ if (interrupts_were_enabled) {
+ __asm__ volatile ("sti");
+ interrupts_enabled = TRUE;
+ }
#endif
}
}
-void
+static void
set_hardware_clock(const enum clock_access_method method,
const time_t newtime,
const bool universal,
@@ -852,7 +1090,7 @@ set_hardware_clock(const enum clock_access_method method,
-void
+static void
set_hardware_clock_exact(const time_t settime,
const struct timeval ref_time,
const enum clock_access_method clock_access,
@@ -897,7 +1135,91 @@ set_hardware_clock_exact(const time_t settime,
-void
+static void
+get_epoch(unsigned long *epoch_p, int *retcode_p) {
+/*----------------------------------------------------------------------------
+ Get the Hardware Clock epoch setting from the kernel.
+----------------------------------------------------------------------------*/
+ int rtc_fd;
+
+ rtc_fd = open("/dev/rtc", O_RDONLY);
+ if (rtc_fd < 0) {
+ if (errno == ENOENT)
+ fprintf(stderr, "To manipulate the epoch value in the kernel, we must "
+ "access the Linux 'rtc' device driver via the device special "
+ "file /dev/rtc. This file does not exist on this system.\n");
+ else
+ fprintf(stderr, "Unable to open /dev/rtc, open() errno = %s (%d)\n",
+ strerror(errno), errno);
+ *retcode_p = 1;
+ } else {
+ int rc; /* return code from ioctl */
+ rc = ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p);
+ if (rc == -1) {
+ fprintf(stderr, "ioctl(RTC_EPOCH_READ) to /dev/rtc failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 1;
+ } else {
+ *retcode_p = 0;
+ if (debug) printf("we have read epoch %ld from /dev/rtc "
+ "with RTC_EPOCH_READ ioctl.\n", *epoch_p);
+ }
+ close(rtc_fd);
+ }
+ return;
+}
+
+
+
+static void
+set_epoch(unsigned long epoch, const bool testing, int *retcode_p) {
+/*----------------------------------------------------------------------------
+ Set the Hardware Clock epoch in the kernel.
+----------------------------------------------------------------------------*/
+ if (epoch < 1900)
+ /* kernel would not accept this epoch value */
+ fprintf(stderr, "The epoch value may not be less than 1900. "
+ "You requested %ld\n", epoch);
+ else {
+ int rtc_fd;
+
+ rtc_fd = open("/dev/rtc", O_RDONLY);
+ if (rtc_fd < 0) {
+ if (errno == ENOENT)
+ fprintf(stderr, "To manipulate the epoch value in the kernel, we must "
+ "access the Linux 'rtc' device driver via the device special "
+ "file /dev/rtc. This file does not exist on this system.\n");
+ fprintf(stderr, "Unable to open /dev/rtc, open() errno = %s (%d)\n",
+ strerror(errno), errno);
+ *retcode_p = 1;
+ } else {
+ if (debug) printf("setting epoch to %ld "
+ "with RTC_EPOCH_SET ioctl to /dev/rtc.\n", epoch);
+ if (testing) {
+ printf("Not setting epoch because running in test mode.\n");
+ *retcode_p = 0;
+ } else {
+ int rc; /* return code from ioctl */
+ rc = ioctl(rtc_fd, RTC_EPOCH_SET, epoch);
+ if (rc == -1) {
+ if (errno == EINVAL)
+ fprintf(stderr, "The kernel (specifically, the device driver "
+ "for /dev/rtc) does not have the RTC_EPOCH_SET ioctl. "
+ "Get a newer driver.\n");
+ else
+ fprintf(stderr, "ioctl(RTC_EPOCH_SET) to /dev/rtc failed, "
+ "errno = %s (%d).\n", strerror(errno), errno);
+ *retcode_p = 1;
+ } else *retcode_p = 0;
+ }
+ close(rtc_fd);
+ }
+ }
+}
+
+
+
+static void
display_time(const time_t systime, const float sync_duration) {
/*----------------------------------------------------------------------------
Put the time "systime" on standard output in display format.
@@ -917,8 +1239,8 @@ display_time(const time_t systime, const float sync_duration) {
-int
-interpret_date_string(const char *date_opt, const time_t *time_p) {
+static int
+interpret_date_string(const char *date_opt, time_t * const time_p) {
/*----------------------------------------------------------------------------
Interpret the value of the --date option, which is something like
"13:05:01". In fact, it can be any of the myriad ASCII strings that specify
@@ -927,16 +1249,16 @@ interpret_date_string(const char *date_opt, const time_t *time_p) {
The specified time is in the local time zone.
- Our output, "*newtime", is a seconds-into-epoch time.
+ Our output, "*time_p", is a seconds-into-epoch time.
We use the "date" program to interpret the date string. "date" must be
runnable by issuing the command "date" to the /bin/sh shell. That means
in must be in the current PATH.
- If anything goes wrong (and many things can), we return return code 10.
- Otherwise, return code is 0 and *newtime is valid.
+ If anything goes wrong (and many things can), we return return code
+ 10 and arbitrary *time_p. Otherwise, return code is 0 and *time_p
+ is valid.
----------------------------------------------------------------------------*/
-
FILE *date_child_fp;
char date_resp[100];
const char magic[]="seconds-into-epoch=";
@@ -974,7 +1296,8 @@ interpret_date_string(const char *date_opt, const time_t *time_p) {
date_command, date_resp);
retcode = 8;
} else {
- rc = sscanf(date_resp + sizeof(magic)-1, "%d", (int *) time_p);
+ int seconds_since_epoch;
+ rc = sscanf(date_resp + sizeof(magic)-1, "%d", &seconds_since_epoch);
if (rc < 1) {
fprintf(stderr, "The date command issued by " MYNAME " returned"
"something other than an integer where the converted"
@@ -984,6 +1307,7 @@ interpret_date_string(const char *date_opt, const time_t *time_p) {
retcode = 6;
} else {
retcode = 0;
+ *time_p = seconds_since_epoch;
if (debug)
printf("date string %s equates to %d seconds since 1969.\n",
date_opt, (int) *time_p);
@@ -997,8 +1321,8 @@ interpret_date_string(const char *date_opt, const time_t *time_p) {
-int
-set_system_clock(const time_t newtime, const int testing) {
+static int
+set_system_clock(const time_t newtime, const bool testing) {
struct timeval tv;
int retcode; /* our eventual return code */
@@ -1009,9 +1333,8 @@ set_system_clock(const time_t newtime, const int testing) {
if (debug) {
printf( "Calling settimeofday:\n" );
- /* Note: In Linux 1.2, tv_sec and tv_usec were long int */
- printf( "\ttv.tv_sec = %d, tv.tv_usec = %d\n",
- tv.tv_sec, tv.tv_usec );
+ printf( "\ttv.tv_sec = %ld, tv.tv_usec = %ld\n",
+ (long) tv.tv_sec, (long) tv.tv_usec );
}
if (testing) {
printf("Not setting system clock because running in test mode.\n");
@@ -1032,7 +1355,7 @@ set_system_clock(const time_t newtime, const int testing) {
}
-void
+static void
adjust_drift_factor(struct adjtime *adjtime_p,
const time_t nowtime,
const time_t hclocktime ) {
@@ -1081,7 +1404,7 @@ adjust_drift_factor(struct adjtime *adjtime_p,
-void
+static void
calculate_adjustment(
const float factor,
const time_t last_time,
@@ -1121,7 +1444,7 @@ calculate_adjustment(
-void
+static void
save_adjtime(const struct adjtime adjtime, const bool testing) {
/*-----------------------------------------------------------------------------
Write the contents of the <adjtime> structure to its disk file.
@@ -1130,16 +1453,18 @@ save_adjtime(const struct adjtime adjtime, const bool testing) {
bother.
-----------------------------------------------------------------------------*/
FILE *adjfile;
- char newfile[162]; /* Stuff to write to disk file */
+ char newfile[405]; /* Stuff to write to disk file */
int rc; /* locally used: return code from a function */
if (adjtime.dirty) {
- snprintf(newfile, sizeof(newfile), "%f %d %f\n%d\n",
+ /* snprintf is not always available, but this is safe
+ as long as libc does not use more than 100 positions for %ld or %f */
+ sprintf(newfile, "%f %ld %f\n%ld\n",
adjtime.drift_factor,
- adjtime.last_adj_time,
+ (long) adjtime.last_adj_time,
adjtime.not_adjusted,
- adjtime.last_calib_time );
+ (long) adjtime.last_calib_time );
if (testing) {
printf("Not updating adjtime file because of testing mode.\n");
@@ -1180,7 +1505,7 @@ save_adjtime(const struct adjtime adjtime, const bool testing) {
-void
+static void
do_adjustment(struct adjtime *adjtime_p,
const time_t hclocktime, const struct timeval read_time,
const enum clock_access_method clock_access,
@@ -1236,7 +1561,7 @@ do_adjustment(struct adjtime *adjtime_p,
-void
+static void
determine_clock_access_method(const bool user_requests_ISA,
enum clock_access_method *clock_access_p) {
/*----------------------------------------------------------------------------
@@ -1245,6 +1570,8 @@ determine_clock_access_method(const bool user_requests_ISA,
using compile-time constants.
<user_requests_ISA> means the user explicitly asked for the ISA method.
+ Even if he did, we will not select the ISA method if this is not an
+ ISA machine.
-----------------------------------------------------------------------------*/
bool rtc_works;
/* The /dev/rtc method is available and seems to work on this machine */
@@ -1261,15 +1588,20 @@ determine_clock_access_method(const bool user_requests_ISA,
"falling back to more primitive clock access method.\n",
strerror(errno), errno);
}
- } else rtc_works = TRUE;
+ } else {
+ if (debug)
+ printf("The Linux kernel for which this copy of hwclock() was built "
+ "is too old to have /dev/rtc\n");
+ rtc_works = FALSE;
+ }
- if (user_requests_ISA) *clock_access_p = ISA;
+ if (user_requests_ISA && isa_machine) *clock_access_p = ISA;
else if (rtc_works) *clock_access_p = RTC_IOCTL;
else if (got_kdghwclk) {
int con_fd;
struct hwclk_time t;
- con_fd = open("/dev/console", O_RDONLY);
+ con_fd = open("/dev/tty1", O_RDONLY);
if (con_fd >= 0) {
if (ioctl( con_fd, kdghwclk_ioctl, &t ) >= 0)
*clock_access_p = KD;
@@ -1287,17 +1619,18 @@ determine_clock_access_method(const bool user_requests_ISA,
} else {
*clock_access_p = KD;
fprintf(stderr,
- "Can't open /dev/console. open() errno = %s (%d).\n",
+ "Can't open /dev/tty1. open() errno = %s (%d).\n",
strerror(errno), errno);
}
close(con_fd);
- } else {
+ } else if (isa_machine) {
*clock_access_p = ISA;
- }
+ } else
+ *clock_access_p = NOCLOCK;
if (debug) {
switch (*clock_access_p) {
case ISA: printf("Using direct I/O instructions to ISA clock.\n"); break;
- case KD: printf("Using /dev/console interface to Alpha clock.\n"); break;
+ case KD: printf("Using KDGHWCLK interface to m68k clock.\n"); break;
case RTC_IOCTL: printf("Using /dev/rtc interface to clock.\n"); break;
default:
printf("determine_clock_access_method() returned invalid value: %d.\n",
@@ -1308,14 +1641,14 @@ determine_clock_access_method(const bool user_requests_ISA,
-void
+static void
manipulate_clock(const bool show, const bool adjust,
const bool set, const time_t set_time,
const bool hctosys, const bool systohc,
const struct timeval startup_time,
const enum clock_access_method clock_access,
const bool universal, const bool testing,
- int *retcode
+ int *retcode_p
) {
/*---------------------------------------------------------------------------
Do all the normal work of hwclock - read, set clock, etc.
@@ -1338,10 +1671,10 @@ manipulate_clock(const bool show, const bool adjust,
bool no_auth; /* User lacks necessary authorization to access the clock */
if (clock_access == ISA) {
- rc = iopl(3);
+ rc = i386_iopl(3);
if (rc != 0) {
fprintf(stderr, MYNAME " is unable to get I/O port access. "
- "I.e. iopl(3) returned nonzero return code %d.\n"
+ "I.e. iopl(2) returned nonzero return code %d.\n"
"This is often because the program isn't running "
"with superuser privilege, which it needs.\n",
rc);
@@ -1349,56 +1682,108 @@ manipulate_clock(const bool show, const bool adjust,
} else no_auth = FALSE;
} else no_auth = FALSE;
- if (no_auth) *retcode = 1;
+ if (no_auth) *retcode_p = 1;
else {
- if (adjust || set)
+ if (adjust || set || systohc)
read_adjtime(&adjtime, &rc);
else {
/* A little trick to avoid reading the file if we don't have to */
adjtime.dirty = FALSE;
rc = 0;
}
- if (rc != 0) *retcode = 2;
+ if (rc != 0) *retcode_p = 2;
else {
- synchronize_to_clock_tick(clock_access); /* this takes up to 1 second */
-
- /* Get current time from Hardware Clock, in case we need it */
- gettimeofday(&read_time, NULL);
- read_hardware_clock(clock_access, &tm);
- hclocktime = mktime_tz(tm, universal);
-
- if (show) {
- display_time(hclocktime, time_diff(read_time, startup_time));
- *retcode = 0;
- } else if (set) {
- set_hardware_clock_exact(set_time, startup_time,
- clock_access, universal, testing);
- adjust_drift_factor(&adjtime, set_time, hclocktime);
- *retcode = 0;
- } else if (adjust) {
- do_adjustment(&adjtime, hclocktime, read_time, clock_access,
- universal, testing);
- *retcode = 0;
- } else if (systohc) {
- struct timeval nowtime, reftime;
- /* We can only set_hardware_clock_exact to a whole seconds time, so we
- set it with reference to the most recent whole seconds time.
- */
- gettimeofday(&nowtime, NULL);
- reftime.tv_sec = nowtime.tv_sec;
- reftime.tv_usec = 0;
-
- set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
- clock_access, universal, testing);
- *retcode = 0;
- } else if (hctosys) {
- rc = set_system_clock(hclocktime, testing);
- if (rc != 0) {
- printf("Unable to set system clock.\n");
- *retcode = 1;
- } else *retcode = 0;
+ synchronize_to_clock_tick(clock_access, retcode_p);
+ /* this takes up to 1 second */
+ if (*retcode_p == 0) {
+ /* Get current time from Hardware Clock, in case we need it */
+ gettimeofday(&read_time, NULL);
+ read_hardware_clock(clock_access, &tm);
+ hclocktime = mktime_tz(tm, universal);
+
+ if (show) {
+ display_time(hclocktime, time_diff(read_time, startup_time));
+ *retcode_p = 0;
+ } else if (set) {
+ set_hardware_clock_exact(set_time, startup_time,
+ clock_access, universal, testing);
+ adjust_drift_factor(&adjtime, set_time, hclocktime);
+ *retcode_p = 0;
+ } else if (adjust) {
+ do_adjustment(&adjtime, hclocktime, read_time, clock_access,
+ universal, testing);
+ *retcode_p = 0;
+ } else if (systohc) {
+ struct timeval nowtime, reftime;
+ /* We can only set_hardware_clock_exact to a whole seconds
+ time, so we set it with reference to the most recent
+ whole seconds time.
+ */
+ gettimeofday(&nowtime, NULL);
+ reftime.tv_sec = nowtime.tv_sec;
+ reftime.tv_usec = 0;
+
+ set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
+ clock_access, universal, testing);
+ *retcode_p = 0;
+ adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclocktime);
+ } else if (hctosys) {
+ rc = set_system_clock(hclocktime, testing);
+ if (rc != 0) {
+ printf("Unable to set system clock.\n");
+ *retcode_p = 1;
+ } else *retcode_p = 0;
+ }
+ save_adjtime(adjtime, testing);
+ }
+ }
+ }
+}
+
+
+
+static void
+manipulate_epoch(const bool getepoch, const bool setepoch,
+ const int epoch_opt, const bool testing) {
+/*----------------------------------------------------------------------------
+ Get or set the Hardware Clock epoch value in the kernel, as appropriate.
+ <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
+
+ <epoch> == -1 if the user did not specify an "epoch" option.
+
+-----------------------------------------------------------------------------*/
+ /*
+ Maintenance note: This should work on non-Alpha machines, but the
+ evidence today (98.03.04) indicates that the kernel only keeps the
+ epoch value on Alphas. If that is ever fixed, this function should be
+ changed.
+ */
+
+ if (!alpha_machine)
+ fprintf(stderr, "The kernel keeps an epoch value for the Hardware Clock "
+ "only on an Alpha machine.\nThis copy of hwclock was built for "
+ "a machine other than Alpha\n(and thus is presumably not running "
+ "on an Alpha now). No action taken.\n");
+ else {
+ if (getepoch) {
+ unsigned long epoch;
+ int retcode;
+
+ get_epoch(&epoch, &retcode);
+ if (retcode != 0)
+ printf("Unable to get the epoch value from the kernel.\n");
+ else
+ printf("Kernel is assuming an epoch value of %lu\n", epoch);
+ } else if (setepoch) {
+ if (epoch_opt == -1)
+ fprintf(stderr, "To set the epoch value, you must use the 'epoch' "
+ "option to tell to what value to set it.\n");
+ else {
+ int rc;
+ set_epoch(epoch_opt, testing, &rc);
+ if (rc != 0)
+ printf("Unable to set the epoch value in the kernel.\n");
}
- save_adjtime(adjtime, testing);
}
}
}
@@ -1430,38 +1815,47 @@ main(int argc, char **argv, char **envp) {
are given by the option_def. The only exception is <show>, which
may be modified after parsing is complete to effect an implied option.
*/
- bool show, set, systohc, hctosys, adjust, version;
+ bool show, set, systohc, hctosys, adjust, getepoch, setepoch, version;
bool universal, testing, directisa;
char *date_opt;
+ int epoch_opt;
const optStruct option_def[] = {
{ 'r', (char *) "show", OPT_FLAG, &show, 0 },
{ 0, (char *) "set", OPT_FLAG, &set, 0 },
{ 'w', (char *) "systohc", OPT_FLAG, &systohc, 0 },
{ 's', (char *) "hctosys", OPT_FLAG, &hctosys, 0 },
+ { 0, (char *) "getepoch", OPT_FLAG, &getepoch, 0 },
+ { 0, (char *) "setepoch", OPT_FLAG, &setepoch, 0 },
{ 'a', (char *) "adjust", OPT_FLAG, &adjust, 0 },
{ 'v', (char *) "version", OPT_FLAG, &version, 0 },
{ 0, (char *) "date", OPT_STRING, &date_opt, 0 },
+ { 0, (char *) "epoch", OPT_UINT, &epoch_opt, 0 },
{ 'u', (char *) "utc", OPT_FLAG, &universal, 0 },
{ 0, (char *) "directisa", OPT_FLAG, &directisa, 0 },
{ 0, (char *) "test", OPT_FLAG, &testing, 0 },
- { 'D', (char *) "debug", OPT_FLAG, &debug, 0 }
+ { 'D', (char *) "debug", OPT_FLAG, &debug, 0 },
+ { 0, (char *) NULL, OPT_END, NULL, 0 }
};
int argc_parse; /* argc, except we modify it as we parse */
char **argv_parse; /* argv, except we modify it as we parse */
+ interrupts_enabled = TRUE; /* Since we haven't messed with them yet */
+
gettimeofday(&startup_time, NULL); /* Remember what time we were invoked */
/* set option defaults */
- show = set = systohc = hctosys = adjust = version = universal =
+ show = set = systohc = hctosys = adjust = getepoch = setepoch =
+ version = universal =
directisa = testing = debug = FALSE;
date_opt = NULL;
+ epoch_opt = -1;
argc_parse = argc; argv_parse = argv;
optParseOptions(&argc_parse, argv_parse, option_def, 0);
/* Uses and sets argc_parse, argv_parse.
Sets show, systohc, hctosys, adjust, universal, version, testing,
- debug, set, date_opt
+ debug, set, date_opt, getepoch, setepoch, epoch_opt
*/
if (argc_parse - 1 > 0) {
@@ -1471,7 +1865,8 @@ main(int argc, char **argv, char **envp) {
exit(100);
}
- if (show + set + systohc + hctosys + adjust + version > 1) {
+ if (show + set + systohc + hctosys + adjust +
+ getepoch + setepoch + version > 1) {
fprintf(stderr, "You have specified multiple function options.\n"
"You can only perform one function at a time.\n");
exit(100);
@@ -1485,29 +1880,50 @@ main(int argc, char **argv, char **envp) {
}
}
- if (!(show | set | systohc | hctosys | adjust | version))
- show = 1; /* default to show */
+ if (directisa && !isa_machine) {
+ fprintf(stderr, "You have requested direct access to the ISA Hardware "
+ "Clock using machine instructions from the user process. "
+ "But this method only works on an ISA machine with an x86 "
+ "CPU, and this is not one!\n");
+ exit(100);
+ }
- if (set || hctosys || systohc || adjust) {
- /* program is designed to run setuid, be secure! */
+ if (!(show | set | systohc | hctosys | adjust | getepoch | setepoch |
+ version))
+ show = 1; /* default to show */
- if (getuid() != 0) {
+
+ if (getuid() == 0) permitted = TRUE;
+ else {
+ /* program is designed to run setuid (in some situations) -- be secure! */
+ if (set || hctosys || systohc || adjust) {
fprintf(stderr,
- "Sorry, only superuser can change the Hardware Clock.\n");
+ "Sorry, only the superuser can change the Hardware Clock.\n");
+ permitted = FALSE;
+ } else if (setepoch) {
+ fprintf(stderr,
+ "Sorry, only the superuser can change "
+ "the Hardware Clock epoch in the kernel.\n");
permitted = FALSE;
} else permitted = TRUE;
- } else permitted = TRUE;
+ }
if (!permitted) retcode = 2;
else {
retcode = 0;
if (version) {
printf(MYNAME " " VERSION "/%s\n",util_linux_version);
+ } else if (getepoch || setepoch) {
+ manipulate_epoch(getepoch, setepoch, epoch_opt, testing);
} else {
determine_clock_access_method(directisa, &clock_access);
-
- manipulate_clock(show, adjust, set, set_time, hctosys, systohc,
- startup_time, clock_access, universal, testing, &rc);
+ if (clock_access == NOCLOCK)
+ fprintf(stderr, "Cannot access the Hardware Clock via any known "
+ "method. Use --debug option to see the details of our "
+ "search for an access method.\n");
+ else
+ manipulate_clock(show, adjust, set, set_time, hctosys, systohc,
+ startup_time, clock_access, universal, testing, &rc);
}
}
exit(retcode);
@@ -1518,6 +1934,18 @@ main(int argc, char **argv, char **envp) {
History of this program:
+ 98.03.05 BJH. Version 2.2.
+
+ Add --getepoch and --setepoch.
+
+ Fix some word length things so it works on Alpha.
+
+ Make it work when /dev/rtc doesn't have the interrupt functions.
+ In this case, busywait for the top of a second instead of blocking and
+ waiting for the update complete interrupt.
+
+ Fix a bunch of bugs too numerous to mention.
+
97.06.01: BJH. Version 2.1. Read and write the century byte (Byte
50) of the ISA Hardware Clock when using direct ISA I/O. Problem
discovered by job (jei@iclnl.icl.nl).
diff --git a/sys-utils/kbdrate.c b/sys-utils/kbdrate.c
index e61fb8906..07a7e40e5 100644
--- a/sys-utils/kbdrate.c
+++ b/sys-utils/kbdrate.c
@@ -62,6 +62,7 @@ beats rebuilding the kernel!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <errno.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <linux/version.h>
@@ -99,7 +100,6 @@ int main( int argc, char **argv )
int c;
int i;
extern char *optarg;
- extern int optind;
while ( (c = getopt( argc, argv, "r:d:sv" )) != EOF )
switch (c) {
diff --git a/sys-utils/readprofile.c b/sys-utils/readprofile.c
index 4c52cf1fa..4462a811f 100644
--- a/sys-utils/readprofile.c
+++ b/sys-utils/readprofile.c
@@ -121,7 +121,7 @@ int popenMap; /* flag to tell if popen() has been used */
* Use an fd for the profiling buffer, to skip stdio overhead
*/
if ( ((proFd=open(proFile,O_RDONLY)) < 0)
- || ((len=lseek(proFd,0,SEEK_END)) < 0)
+ || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
|| (lseek(proFd,0,SEEK_SET)<0) )
{
fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
diff --git a/sys-utils/renice.c b/sys-utils/renice.c
index 63af8cd4e..8867d0022 100644
--- a/sys-utils/renice.c
+++ b/sys-utils/renice.c
@@ -31,16 +31,6 @@
* SUCH DAMAGE.
*/
-#ifndef lint
-static char copyright[] =
-"@(#) Copyright (c) 1983, 1989, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)renice.c 8.1 (Berkeley) 6/9/93";
-#endif /* not lint */
-
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -56,9 +46,8 @@ int donice(int,int,int);
* or groups of processes which are already
* running.
*/
-void
-main(argc, argv)
- char **argv;
+int
+main(int argc, char **argv)
{
int which = PRIO_PROCESS;
int who = 0, prio, errs = 0;
@@ -107,7 +96,7 @@ main(argc, argv)
}
errs += donice(which, who, prio);
}
- exit(errs != 0);
+ return (errs != 0);
}
int
diff --git a/sys-utils/tunelp.c b/sys-utils/tunelp.c
index 6bdebda72..e3b015ba3 100644
--- a/sys-utils/tunelp.c
+++ b/sys-utils/tunelp.c
@@ -6,8 +6,11 @@
* for information on distribution conditions. *
\****************************************************************************/
-/* $Id: tunelp.c,v 1.8 1997/07/06 00:14:06 aebr Exp $
+/* $Id: tunelp.c,v 1.9 1998/06/08 19:37:11 janl Exp $
* $Log: tunelp.c,v $
+ * Revision 1.9 1998/06/08 19:37:11 janl
+ * Thus compiles tunelp with 2.1.103 kernels
+ *
* Revision 1.8 1997/07/06 00:14:06 aebr
* Fixes to silence -Wall.
*
@@ -45,6 +48,8 @@
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
+/* This is for (some) 2.1 kernels */
+#define LP_NEED_CAREFUL
#include<linux/lp.h>
#include<linux/fs.h>
#include<sys/ioctl.h>