summaryrefslogtreecommitdiffstats
path: root/sys-utils
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:37 +0100
committerKarel Zak2006-12-07 00:25:37 +0100
commit5c36a0eb7cdb0360f9afd5d747c321f423b35984 (patch)
tree147599a77eaff2b5fbc0d389e89d2b51602326c0 /sys-utils
parentImported from util-linux-2.8 tarball. (diff)
downloadkernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.tar.gz
kernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.tar.xz
kernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.zip
Imported from util-linux-2.9i tarball.
Diffstat (limited to 'sys-utils')
-rw-r--r--sys-utils/Makefile16
-rw-r--r--sys-utils/ctrlaltdel.c10
-rw-r--r--sys-utils/hwclock.8130
-rw-r--r--sys-utils/hwclock.c362
-rw-r--r--sys-utils/ipcrm.c15
-rw-r--r--sys-utils/ipcs.c30
-rw-r--r--sys-utils/kbdrate.87
-rw-r--r--sys-utils/kbdrate.c15
-rw-r--r--sys-utils/lpcntl.830
-rw-r--r--sys-utils/lpcntl.c54
-rw-r--r--sys-utils/sln.8 (renamed from sys-utils/sln.1)11
11 files changed, 422 insertions, 258 deletions
diff --git a/sys-utils/Makefile b/sys-utils/Makefile
index 9085fa965..91aa32d1d 100644
--- a/sys-utils/Makefile
+++ b/sys-utils/Makefile
@@ -11,9 +11,9 @@ include ../MCONFIG
MAN1= arch.1 readprofile.1
-MAN8= ctrlaltdel.8 cytune.8 dmesg.8 \
+MAN8= ctrlaltdel.8 cytune.8 dmesg.8 hwclock.8 \
ipcrm.8 ipcs.8 kbdrate.8 ramsize.8 renice.8 \
- rootflags.8 setsid.8 swapdev.8 tunelp.8 \
+ rootflags.8 setsid.8 sln.8 swapdev.8 tunelp.8 \
vidmode.8
# Where to put binaries?
@@ -23,15 +23,14 @@ BIN= arch dmesg
USRBIN= cytune ipcrm ipcs renice readprofile setsid tunelp
-SBIN= sln ctrlaltdel kbdrate
+SBIN= ctrlaltdel hwclock kbdrate
-ifneq "$(CPU)" "sparc"
-MAN8:= $(MAN8) hwclock.8
-SBIN:=$(SBIN) hwclock
+ifeq "$(HAVE_SLN)" "no"
+SBIN:=$(SBIN) sln
endif
ifeq "$(CPU)" "intel"
-MAN8:= $(MAN8) rdev.8
+MAN8:=$(MAN8) rdev.8
USRBIN:=$(USRBIN) rdev
endif
@@ -49,7 +48,8 @@ sln: sln.c
arch: arch.o
hwclock.o: hwclock.c shhopt.h
hwclock: hwclock.o shhopt.o
-ctrlaltdel: ctrlaltdel.o
+ctrlaltdel.o: ctrlaltdel.c $(LIB)/linux_reboot.h
+ctrlaltdel: ctrlaltdel.o $(LIB)/my_reboot.o
ipcrm: ipcrm.o
ipcs: ipcs.o
kbdrate: kbdrate.o
diff --git a/sys-utils/ctrlaltdel.c b/sys-utils/ctrlaltdel.c
index e5565d704..c754fd058 100644
--- a/sys-utils/ctrlaltdel.c
+++ b/sys-utils/ctrlaltdel.c
@@ -7,24 +7,24 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
-
-int reboot(int magic, int magictoo, int flag);
+#include "linux_reboot.h"
int
main(int argc, char *argv[]) {
if(geteuid()) {
- fprintf(stderr, "You must be root to set the Ctrl-Alt-Del behaviour.\n");
+ fprintf(stderr,
+ "You must be root to set the Ctrl-Alt-Del behaviour.\n");
exit(1);
}
if(argc == 2 && !strcmp("hard", argv[1])) {
- if(reboot(0xfee1dead, 672274793, 0x89abcdef) < 0) {
+ if(my_reboot(LINUX_REBOOT_CMD_CAD_ON) < 0) {
perror("ctrlaltdel: reboot");
exit(1);
}
} else if(argc == 2 && !strcmp("soft", argv[1])) {
- if(reboot(0xfee1dead, 672274793, 0) < 0) {
+ if(my_reboot(LINUX_REBOOT_CMD_CAD_OFF) < 0) {
perror("ctrlaltdel: reboot");
exit(1);
}
diff --git a/sys-utils/hwclock.8 b/sys-utils/hwclock.8
index ec8b00762..58f4a259e 100644
--- a/sys-utils/hwclock.8
+++ b/sys-utils/hwclock.8
@@ -55,8 +55,17 @@ Set the Hardware Clock to the time given by the
option.
.TP
.B \-\-hctosys
-Set the System Time from the Hardware Clock. This is a good option to use
-in one of the system startup scripts.
+Set the System Time from the Hardware Clock.
+
+Also set the kernel's timezone value to the local timezone as indicated by
+the TZ environment variable and/or /usr/lib/zoneinfo, as tzset(3) would
+interpret them. EXCEPT: always set the Daylight Savings Time part of
+the kernel's timezone value to 0 ("not Daylight Savings Time"). If DST
+is indicated, just add an hour to the base part.
+
+See the discussion of timezones below.
+
+This is a good option to use in one of the system startup scripts.
.TP
.B \-\-systohc
Set the Hardware Clock to the current System Time.
@@ -118,11 +127,19 @@ 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
.I hwclock.
-.PP
-If you don't specify
-.B --utc
-when you should, or vice versa, both setting and querying of the
-Hardware Clock will be messed up.
+
+In order to avoid any possible misunderstandings: all conversation
+with the program
+.I hwclock
+is done in local time. If you have your clock in UTC
+(as is common on a Unix system) then the option
+.B --utc
+tells
+.I hwclock
+to do the appropriate conversions: `hwclock \-\-show \-\-utc'
+will tell you the local time, assuming the hardware clock is in UTC,
+and `hwclock \-\-set \-\-date="XXX" \-\-utc' will set the
+hardware clock to the UTC equivalent of the local time XXX.
.TP
.B \-\-directisa
is meaningful only on an ISA machine. For all other machines, it has
@@ -134,7 +151,7 @@ Without this option,
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
@@ -198,7 +215,42 @@ time Linux starts up, it will do so with the adjusted time from the Hardware
Clock. You can also use the program
.I adjtimex(8)
to smoothly adjust the System Time while the system runs.
-
+.PP
+A Linux kernel maintains a concept of a local timezone for the system.
+But don't be misled -- almost nobody cares what timezone the kernel
+thinks it is in. Instead, programs that care about the timezone
+(perhaps because they want to display a local time for you) almost
+always use a more traditional method of determining the timezone: They
+use the TZ environment variable and/or the /usr/local/timezone
+directory, as explained in the man page for tzset(3). However, some
+programs and fringe parts of the Linux kernel such as filesystems use
+the kernel timezone value. An example is the vfat filesystem. If the
+kernel timezone value is wrong, the vfat filesystem will report and
+set the wrong timestamps on files.
+.PP
+.I hwclock
+sets the kernel timezone to the value indicated by TZ and/or
+/usr/local/timezone when you set the System Time using the
+.B \-\-hctosys
+option.
+.PP
+A complication is that the timezone value actually consists of two
+parts: 1) how far from the Standard Meridian the locality is
+geographically, and 2) whether or not a Daylight Savings Time (DST)
+convention is in effect in the locality at the present time. In
+practice, the DST part of the timezone value is almost never used, so
+if the geographical part were to be set to its correct value, the
+users of the timezone value would actually compute the wrong local
+time.
+.PP
+Therefore,
+.I
+hwclock
+violates the definition of the kernel's timezone value and always sets
+the DST part to zero. If DST is supposed to be in effect,
+.I
+hwclock
+simply adds an hour to the geographical part.
.SH How hwclock Accesses the Hardware Clock
.PP
@@ -302,7 +354,11 @@ Another 24 hours goes by and you issue another
does the same thing: subtracts 2 seconds and updates the adjtime file
with the current time as the last time the clock was adjusted.
.PP
-Every time you calibrate (set) the clock,
+Every time you calibrate (set) the clock (using
+.I --set
+or
+.I --systohc
+),
.I hwclock
recalculates the systematic drift rate based on how long it has been
since the last calibration, how long it has been since the last
@@ -324,12 +380,12 @@ just before the
at system startup time, and maybe periodically while the system is
running via cron.
.PP
-The format of the adjtime file is:
+The format of the adjtime file is, in ASCII:
.PP
-Line 1: 3 numbers: 1) systematic drift rate in seconds per day,
-floating point decimal; 2) Resulting number of seconds since 1969 UTC
-of most recent adjustment or calibration, decimal integer; 3) zero
-(for compatibility with
+Line 1: 3 numbers, separated by blanks: 1) systematic drift rate in
+seconds per day, floating point decimal; 2) Resulting number of
+seconds since 1969 UTC of most recent adjustment or calibration,
+decimal integer; 3) zero (for compatibility with
.I clock
).
.PP
@@ -341,11 +397,51 @@ You can use an adjtime file that was previously used with the
program with
.I hwclock.
+
+.SH Automatic Hardware Clock Synchronization By the Kernel
+
+You should be aware of another way that the Hardware Clock is kept
+synchronized in some systems. The Linux kernel has a mode wherein it
+copies the System Time to the Hardware Clock every 11 minutes.
+This is a good mode to use when you are using something sophisticated
+like ntp to keep your System Time synchronized. (ntp is a way to keep
+your System Time synchronized either to a time server somewhere on the
+network or to a radio clock hooked up to your system. See RFC 1305).
+
+This mode (we'll call it "11 minute mode") is off until something
+turns it on. The ntp daemon xntpd is one thing that turns it on. You
+can turn it off by running anything, including
+.I hwclock --hctosys
+, that sets the System Time the old fashioned way.
+
+To see if it is on or
+off, use the command
+.I adjtimex --print
+and look at the value of "status". If the "64" bit of this number
+(expressed in binary) equal to 0, 11 minute mode is on. Otherwise, it
+is off.
+
+If your system runs with 11 minute mode on, don't use
+.I hwclock --adjust
+or
+.I hwclock --hctosys .
+You'll just make a mess. It is acceptable to use a
+.I hwclock --hctosys
+at startup time to get a reasonable System Time until your system is
+able to set the System Time from the external source and start 11
+minute mode.
+
+
+.SH ENVIRONMENT VARIABLES
+.I TZ
+
.SH FILES
.I /etc/adjtime
+.I /usr/lib/zoneinfo/
.SH SEE ALSO
-adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1)
+adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1),
+tzset(3)
.SH AUTHORS
Written By Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
@@ -353,5 +449,3 @@ 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 643ccda5b..02302da29 100644
--- a/sys-utils/hwclock.c
+++ b/sys-utils/hwclock.c
@@ -106,12 +106,14 @@
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
-#include <asm/io.h>
+#ifdef __i386__
+#include <asm/io.h> /* for inb, outb */
+#endif
#include <shhopt.h>
#include "../version.h"
#define MYNAME "hwclock"
-#define VERSION "2.2"
+#define VERSION "2.4"
#define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
@@ -190,7 +192,6 @@ bool interrupts_enabled;
need to be turned back on.
*/
-
#include <linux/version.h>
/* Check if the /dev/rtc interface is available in this version of
the system headers. 131072 is linux 2.0.0. Might need to make
@@ -658,17 +659,27 @@ synchronize_to_clock_tick(enum clock_access_method clock_access,
-static time_t
-mktime_tz(struct tm tm, const bool universal) {
+static void
+mktime_tz(struct tm tm, const bool universal,
+ bool *valid_p, time_t *systime_p) {
/*-----------------------------------------------------------------------------
Convert a time in broken down format (hours, minutes, etc.) into standard
- unix time (seconds into epoch).
+ unix time (seconds into epoch). Return it as *systime_p.
The broken down time is argument <tm>. This broken down time is either in
local time zone or UTC, depending on value of logical argument "universal".
True means it is in UTC.
+
+ If the argument contains values that do not constitute a valid time,
+ and mktime() recognizes this, return *valid_p == false and
+ *systime_p undefined. However, mktime() sometimes goes ahead and
+ computes a fictional time "as if" the input values were valid,
+ e.g. if they indicate the 31st day of April, mktime() may compute
+ the time of May 1. In such a case, we return the same fictional
+ value mktime() does as *systime_p and return *valid_p == true.
+
-----------------------------------------------------------------------------*/
- time_t systime; /* our eventual return value */
+ time_t mktime_result; /* The value returned by our mktime() call */
char *zone; /* Local time zone name */
/* We use the C library function mktime(), but since it only works on
@@ -686,23 +697,31 @@ mktime_tz(struct tm tm, const bool universal) {
*/
tzset();
}
- systime = mktime(&tm);
- if (systime == -1) {
- /* We don't expect this to happen. Consider this a crash */
- fprintf(stderr, "mktime() failed unexpectedly (rc -1). Aborting.\n");
- exit(2);
+ mktime_result = mktime(&tm);
+ if (mktime_result == -1) {
+ /* This apparently (not specified in mktime() documentation) means
+ the 'tm' structure does not contain valid values (however, not
+ containing valid values does _not_ imply mktime() returns -1).
+ */
+ *valid_p = FALSE;
+ *systime_p = 0;
+ if (debug)
+ printf("Invalid values in hardware clock: "
+ "%2d/%.2d/%.2d %.2d:%.2d:%.2d\n",
+ tm.tm_year, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec
+ );
+ } else {
+ *valid_p = TRUE;
+ *systime_p = mktime_result;
+ if (debug)
+ printf("Hw clock time : %.2d:%.2d:%.2d = %d seconds since 1969\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) *systime_p);
}
-
/* now put back the original zone. */
if (zone) setenv("TZ", zone, TRUE);
else unsetenv("TZ");
tzset();
-
- if (debug)
- printf("Hw clock time : %.2d:%.2d:%.2d = %d seconds since 1969\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec, (int) systime);
-
- return(systime);
}
@@ -837,32 +856,28 @@ read_hardware_clock_isa(struct tm *tm) {
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 .
+ /* We don't use the century byte (Byte 50) of the Hardware Clock.
+ Here's why: On older machines, it isn't defined. In at least
+ one reported case, a machine puts some arbitrary value in that
+ byte. Furthermore, the Linux standard time data structure doesn't
+ allow for times beyond about 2037 and no Linux systems were
+ running before 1937. Therefore, all the century byte could tell
+ us is that the clock is wrong or this whole program is obsolete!
+
+ So we just say if the year of century is less than 37, it's the
+ 21st century, otherwise it's the 20th.
*/
- 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!
- */
+
+ if (hclock_read_bcd(9) >= 37) tm->tm_year = hclock_read_bcd(9);
+ else tm->tm_year = hclock_read_bcd(9) + 100;
}
+ /* 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!
+ */
}
tm->tm_isdst = -1; /* don't know whether it's daylight */
}
@@ -870,21 +885,25 @@ read_hardware_clock_isa(struct tm *tm) {
static void
-read_hardware_clock(const enum clock_access_method method, struct tm *tm){
+read_hardware_clock(const enum clock_access_method method,
+ const bool universal, bool *valid_p, time_t *systime_p){
/*----------------------------------------------------------------------------
Read the hardware clock and return the current time via <tm> argument.
Use the method indicated by <method> argument to access the hardware clock.
-----------------------------------------------------------------------------*/
+ struct tm tm;
+
+
switch (method) {
case ISA:
- read_hardware_clock_isa(tm);
+ read_hardware_clock_isa(&tm);
break;
case RTC_IOCTL:
- read_hardware_clock_rtc_ioctl(tm);
+ read_hardware_clock_rtc_ioctl(&tm);
break;
case KD:
- read_hardware_clock_kd(tm);
+ read_hardware_clock_kd(&tm);
break;
default:
fprintf(stderr,
@@ -893,7 +912,8 @@ read_hardware_clock(const enum clock_access_method method, struct tm *tm){
}
if (debug)
printf ("Time read from Hardware Clock: %02d:%02d:%02d\n",
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ mktime_tz(tm, universal, valid_p, systime_p);
}
@@ -994,14 +1014,13 @@ 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__
+ const bool interrupts_were_enabled = interrupts_enabled;
+
__asm__ volatile ("cli");
interrupts_enabled = FALSE;
#endif
@@ -1220,21 +1239,30 @@ set_epoch(unsigned long epoch, const bool testing, int *retcode_p) {
static void
-display_time(const time_t systime, const float sync_duration) {
+display_time(const bool hclock_valid, const time_t systime,
+ const float sync_duration) {
/*----------------------------------------------------------------------------
Put the time "systime" on standard output in display format.
+ Except if hclock_valid == false, just tell standard output that we don't
+ know what time it is.
Include in the output the adjustment "sync_duration".
-----------------------------------------------------------------------------*/
- char *ctime_now; /* Address of static storage containing time string */
-
- /* For some strange reason, ctime() is designed to include a newline
- character at the end. We have to remove that.
- */
- ctime_now = ctime(&systime); /* Compute display value for time */
- *(ctime_now+strlen(ctime_now)-1) = '\0'; /* Cut off trailing newline */
+ if (!hclock_valid)
+ fprintf(stderr, "The Hardware Clock registers contain values that are "
+ "either invalid (e.g. 50th day of month) or beyond the range "
+ "we can handle (e.g. Year 2095).\n");
+ else {
+ char *ctime_now; /* Address of static storage containing time string */
- printf("%s %.6f seconds\n", ctime_now, -(sync_duration));
+ /* For some strange reason, ctime() is designed to include a newline
+ character at the end. We have to remove that.
+ */
+ ctime_now = ctime(&systime); /* Compute display value for time */
+ *(ctime_now+strlen(ctime_now)-1) = '\0'; /* Cut off trailing newline */
+
+ printf("%s %.6f seconds\n", ctime_now, -(sync_duration));
+ }
}
@@ -1322,34 +1350,69 @@ interpret_date_string(const char *date_opt, time_t * const time_p) {
static int
-set_system_clock(const time_t newtime, const bool testing) {
+set_system_clock(const bool hclock_valid, const time_t newtime,
+ const bool testing) {
+/*----------------------------------------------------------------------------
+ Set the System Clock to time 'newtime'.
+
+ Also set the kernel time zone value to the value indicated by the
+ TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
+ tzset() would interpret them. Except: do not consider Daylight
+ Savings Time to be a separate component of the time zone. Include
+ any effect of DST in the basic timezone value and set the kernel
+ DST value to 0.
- struct timeval tv;
+ EXCEPT: if hclock_valid is false, just issue an error message
+ saying there is no valid time in the Hardware Clock to which to set
+ the system time.
+
+ If 'testing' is true, don't actually update anything -- just say we
+ would have.
+-----------------------------------------------------------------------------*/
int retcode; /* our eventual return code */
- int rc; /* local return code */
- tv.tv_sec = newtime;
- tv.tv_usec = 0;
-
- if (debug) {
- printf( "Calling settimeofday:\n" );
- 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");
- retcode = 0;
+ if (!hclock_valid) {
+ fprintf(stderr,"The Hardware Clock does not contain a valid time, so "
+ "we cannot set the System Time from it.\n");
+ retcode = 1;
} else {
- rc = settimeofday(&tv, NULL);
- if (rc != 0) {
- if (errno == EPERM)
- fprintf(stderr, "Must be superuser to set system clock.\n");
- else
- fprintf(stderr,
- "settimeofday() failed, errno=%d:%s\n",
- errno, strerror(errno));
- retcode = 1;
- } else retcode = 0;
+ struct timeval tv;
+ int rc; /* local return code */
+
+ tv.tv_sec = newtime;
+ tv.tv_usec = 0;
+
+ tzset(); /* init timezone, daylight from TZ or ...zoneinfo/localtime */
+ /* An undocumented function of tzset() is to set global variabales
+ 'timezone' and 'daylight'
+ */
+
+ if (debug) {
+ printf( "Calling settimeofday:\n" );
+ 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");
+ retcode = 0;
+ } else {
+ /* For documentation of settimeofday(), in addition to its man page,
+ see kernel/time.c in the Linux source code.
+ */
+ const struct timezone tz = { timezone/60 - 60*daylight, 0 };
+ /* put daylight in minuteswest rather than dsttime,
+ since the latter is mostly ignored ... */
+ rc = settimeofday(&tv, &tz);
+ if (rc != 0) {
+ if (errno == EPERM)
+ fprintf(stderr, "Must be superuser to set system clock.\n");
+ else
+ fprintf(stderr,
+ "settimeofday() failed, errno=%d:%s\n",
+ errno, strerror(errno));
+ retcode = 1;
+ } else retcode = 0;
+ }
}
return(retcode);
}
@@ -1358,7 +1421,7 @@ set_system_clock(const time_t newtime, const bool testing) {
static void
adjust_drift_factor(struct adjtime *adjtime_p,
const time_t nowtime,
- const time_t hclocktime ) {
+ const bool hclock_valid, const time_t hclocktime ) {
/*---------------------------------------------------------------------------
Update the drift factor in <*adjtime_p> to reflect the fact that the
Hardware Clock was calibrated to <nowtime> and before that was set
@@ -1372,8 +1435,20 @@ adjust_drift_factor(struct adjtime *adjtime_p,
We record in the adjtime file the time at which we last calibrated
the clock so we can compute the drift rate each time we calibrate.
+ EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
+ before to anything meaningful and regular adjustments have not been
+ done, so don't adjust the drift factor.
+
----------------------------------------------------------------------------*/
- if ((hclocktime - adjtime_p->last_calib_time) >= 24 * 60 * 60) {
+ if (!hclock_valid) {
+ if (debug)
+ printf("Not adjusting drift factor because the Hardware Clock "
+ "previously contained garbage.\n");
+ } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
+ if (debug)
+ printf("Not adjusting drift factor because it has been less than a "
+ "day since the last calibration.\n");
+ } else {
const float factor_adjust =
((float) (nowtime - hclocktime)
/ (hclocktime - adjtime_p->last_calib_time))
@@ -1387,18 +1462,15 @@ adjust_drift_factor(struct adjtime *adjtime_p,
(int) (hclocktime - adjtime_p->last_calib_time),
adjtime_p->drift_factor,
factor_adjust );
-
+
adjtime_p->drift_factor += factor_adjust;
- } else if (debug)
- printf("Not adjusting drift factor because it has been less than a "
- "day since the last calibration.\n");
-
+ }
adjtime_p->last_calib_time = nowtime;
adjtime_p->last_adj_time = nowtime;
-
+
adjtime_p->not_adjusted = 0;
-
+
adjtime_p->dirty = TRUE;
}
@@ -1507,7 +1579,8 @@ save_adjtime(const struct adjtime adjtime, const bool testing) {
static void
do_adjustment(struct adjtime *adjtime_p,
- const time_t hclocktime, const struct timeval read_time,
+ const bool hclock_valid, const time_t hclocktime,
+ const struct timeval read_time,
const enum clock_access_method clock_access,
const bool universal, const bool testing) {
/*---------------------------------------------------------------------------
@@ -1515,10 +1588,14 @@ do_adjustment(struct adjtime *adjtime_p,
necessary), and 2) updating the last-adjusted time in the adjtime
structure.
+ Do not update anything if the Hardware Clock does not currently present
+ a valid time.
+
arguments <factor> and <last_time> are current values from the adjtime
file.
- <hclocktime> is the current time set in the Hardware Clock.
+ <hclock_valid> means the Hardware Clock contains a valid time, and that
+ time is <hclocktime>.
<read_time> is the current system time (to be precise, it is the system
time at the time <hclocktime> was read, which due to computational delay
@@ -1534,29 +1611,34 @@ do_adjustment(struct adjtime *adjtime_p,
frequently.
----------------------------------------------------------------------------*/
- int adjustment;
+ if (!hclock_valid) {
+ fprintf(stderr, "The Hardware Clock does not contain a valid time, "
+ "so we cannot adjust it.\n");
+ } else {
+ int adjustment;
/* Number of seconds we must insert in the Hardware Clock */
- float retro;
+ float retro;
/* Fraction of second we have to remove from clock after inserting
<adjustment> whole seconds.
*/
- calculate_adjustment(adjtime_p->drift_factor,
- adjtime_p->last_adj_time,
- adjtime_p->not_adjusted,
- hclocktime,
- &adjustment, &retro,
- debug );
- if (adjustment > 0 || adjustment < -1) {
- set_hardware_clock_exact(hclocktime + adjustment,
- time_inc(read_time, -retro),
- clock_access, universal, testing);
- adjtime_p->last_adj_time = hclocktime + adjustment;
- adjtime_p->not_adjusted = 0;
- adjtime_p->dirty = TRUE;
- } else
- if (debug)
- printf("Needed adjustment is less than one second, "
- "so not setting clock.\n");
+ calculate_adjustment(adjtime_p->drift_factor,
+ adjtime_p->last_adj_time,
+ adjtime_p->not_adjusted,
+ hclocktime,
+ &adjustment, &retro,
+ debug );
+ if (adjustment > 0 || adjustment < -1) {
+ set_hardware_clock_exact(hclocktime + adjustment,
+ time_inc(read_time, -retro),
+ clock_access, universal, testing);
+ adjtime_p->last_adj_time = hclocktime + adjustment;
+ adjtime_p->not_adjusted = 0;
+ adjtime_p->dirty = TRUE;
+ } else
+ if (debug)
+ printf("Needed adjustment is less than one second, "
+ "so not setting clock.\n");
+ }
}
@@ -1659,14 +1741,6 @@ manipulate_clock(const bool show, const bool adjust,
----------------------------------------------------------------------------*/
struct adjtime adjtime;
/* Contents of the adjtime file, or what they should be. */
- struct tm tm;
- time_t hclocktime;
- /* The time the hardware clock had just after we synchronized to its
- next clock tick when we started up.
- */
- struct timeval read_time;
- /* The time at which we read the Hardware Clock */
-
int rc; /* local return code */
bool no_auth; /* User lacks necessary authorization to access the clock */
@@ -1674,7 +1748,7 @@ manipulate_clock(const bool show, const bool adjust,
rc = i386_iopl(3);
if (rc != 0) {
fprintf(stderr, MYNAME " is unable to get I/O port access. "
- "I.e. iopl(2) returned nonzero return code %d.\n"
+ "I.e. iopl(3) returned nonzero return code %d.\n"
"This is often because the program isn't running "
"with superuser privilege, which it needs.\n",
rc);
@@ -1696,21 +1770,36 @@ manipulate_clock(const bool show, const bool adjust,
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 */
+ struct timeval read_time;
+ /* The time at which we read the Hardware Clock */
+
+ bool hclock_valid;
+ /* The Hardware Clock gives us a valid time, or at least something
+ close enough to fool mktime().
+ */
+
+ time_t hclocktime;
+ /* The time the hardware clock had just after we
+ synchronized to its next clock tick when we started up.
+ Defined only if hclock_valid is true.
+ */
+
gettimeofday(&read_time, NULL);
- read_hardware_clock(clock_access, &tm);
- hclocktime = mktime_tz(tm, universal);
+ read_hardware_clock(clock_access, universal, &hclock_valid,
+ &hclocktime);
if (show) {
- display_time(hclocktime, time_diff(read_time, startup_time));
+ display_time(hclock_valid, 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);
+ adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime);
*retcode_p = 0;
} else if (adjust) {
- do_adjustment(&adjtime, hclocktime, read_time, clock_access,
+ do_adjustment(&adjtime, hclock_valid, hclocktime,
+ read_time, clock_access,
universal, testing);
*retcode_p = 0;
} else if (systohc) {
@@ -1726,9 +1815,10 @@ manipulate_clock(const bool show, const bool adjust,
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);
+ adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
+ hclocktime);
} else if (hctosys) {
- rc = set_system_clock(hclocktime, testing);
+ rc = set_system_clock(hclock_valid, hclocktime, testing);
if (rc != 0) {
printf("Unable to set system clock.\n");
*retcode_p = 1;
@@ -1934,6 +2024,16 @@ main(int argc, char **argv, char **envp) {
History of this program:
+ 98.08.12 BJH Version 2.4
+
+ Don't use century byte from Hardware Clock. Add comments telling why.
+
+
+ 98.06.20 BJH Version 2.3.
+
+ Make --hctosys set the kernel timezone from TZ environment variable
+ and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
+
98.03.05 BJH. Version 2.2.
Add --getepoch and --setepoch.
diff --git a/sys-utils/ipcrm.c b/sys-utils/ipcrm.c
index eceb0b71c..c04b7fd44 100644
--- a/sys-utils/ipcrm.c
+++ b/sys-utils/ipcrm.c
@@ -6,9 +6,24 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
+#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val;
+ struct semid_ds *buf;
+ unsigned short int *array;
+ struct seminfo *__buf;
+};
+#endif
+
int main(int argc, char **argv)
{
diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c
index 9505aff55..975bfd1a2 100644
--- a/sys-utils/ipcs.c
+++ b/sys-utils/ipcs.c
@@ -22,12 +22,38 @@
#include <time.h>
#include <pwd.h>
#include <grp.h>
-#define __KERNEL__
+#if 0
+#define __KERNEL__ /* yuk */
#include <linux/linkage.h>
+#endif
+/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
+/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
+/* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */
+#include <sys/types.h>
+#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/shm.h>
+/* The last arg of semctl is a union semun, but where is it defined?
+ X/OPEN tells us to define it ourselves, but until recently
+ Linux include files would also define it. */
+#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val;
+ struct semid_ds *buf;
+ unsigned short int *array;
+ struct seminfo *__buf;
+};
+#endif
+/* X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm;
+ libc 4/5 does not mention struct ipc_term at all, but includes
+ <linux/ipc.h>, which defines a struct ipc_perm with such fields.
+ glibc-1.09 has no support for sysv ipc.
+ glibc 2 uses __key, __seq */
#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
#define KEY __key
#else
@@ -237,7 +263,7 @@ void do_shm (char format)
default:
printf ("------ Shared Memory Segments --------\n");
- printf ("%-11s%-10s%-10s%-10s%-10s%-10s%-12s\n", "key","shmid",
+ printf ("%-10s%-10s%-10s%-10s%-10s%-10s%-12s\n", "key","shmid",
"owner","perms","bytes","nattch","status");
break;
}
diff --git a/sys-utils/kbdrate.8 b/sys-utils/kbdrate.8
index 3fef3395f..88c6cbc1f 100644
--- a/sys-utils/kbdrate.8
+++ b/sys-utils/kbdrate.8
@@ -49,6 +49,13 @@ Not all keyboards have the rates mapped in the same way.
Setting the repeat rate on the Gateway AnyKey keyboard does not work. If
someone with a Gateway figures out how to program the keyboard, please send
mail to faith@cs.unc.edu.
+.PP
+The above description is for i386 machines, and writing to some io port
+won't work on other architectures. Nowadays
+.B kbdrate
+first tries if the KDKBDREP ioctl is available. If it is, it is used,
+otherwise the old method is applied.
+
.SH FILES
.I /etc/rc.local
.br
diff --git a/sys-utils/kbdrate.c b/sys-utils/kbdrate.c
index 07a7e40e5..504429452 100644
--- a/sys-utils/kbdrate.c
+++ b/sys-utils/kbdrate.c
@@ -67,7 +67,7 @@ beats rebuilding the kernel!
#include <sys/ioctl.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= 131072
-/* Kd.h is not available with all linux versions. 131072 is equivalent
+/* kd.h is not available with all linux versions. 131072 is equivalent
to linux 2.0.0 */
#include <linux/kd.h>
#endif
@@ -130,10 +130,15 @@ int main( int argc, char **argv )
} else ioctl_possible = 1;
if (ioctl_possible) {
- kbdrep_s.rate = 1000.0 / rate; /* convert cps to msec */
- if (kbdrep_s.rate < 1) kbdrep_s.rate = 1;
+ if (rate == 0) /* switch repeat off */
+ kbdrep_s.rate = 0;
+ else
+ kbdrep_s.rate = 1000.0 / rate; /* convert cps to msec */
+ if (kbdrep_s.rate < 1)
+ kbdrep_s.rate = 1;
kbdrep_s.delay = delay;
- if (kbdrep_s.delay < 1) kbdrep_s.delay = 1;
+ if (kbdrep_s.delay < 1)
+ kbdrep_s.delay = 1;
if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
perror( "ioctl(KDKBDREP)" );
@@ -192,7 +197,7 @@ int main( int argc, char **argv )
valid_rates[value & 0x1f] / 10.0,
valid_delays[ (value & 0x60) >> 5 ] );
-#ifdef KDKBREP
+#ifdef KDKBDREP
}
#endif
diff --git a/sys-utils/lpcntl.8 b/sys-utils/lpcntl.8
deleted file mode 100644
index 87bcd039e..000000000
--- a/sys-utils/lpcntl.8
+++ /dev/null
@@ -1,30 +0,0 @@
-.\" Public Domain 1994 Rik Faith (faith@cs.unc.edu)
-.\" "
-.TH LPCNTL 8 "18 July 1994" "Linux 1.1" "Linux Programmer's Manual"
-.SH NAME
-lpcntl \- interface to line printer ioctl
-.SH SYNOPSIS
-.BI "lpcntl " device " [ " irq " ]"
-.SH DESCRIPTION
-.B lpcntl
-is used to manipulate the line printer driver.
-.PP
-.I device
-specifies a line printer device (e.g.,
-.IR /dev/lp1 ).
-.PP
-If
-.I irq
-is specified, then the line printer driver is set to use that IRQ. If the
-.I irq
-is zero, then the polling driver is selected. Only the super user may
-change the IRQ.
-.PP
-If no
-.I irq
-is specified, then
-.B lpcntl
-will report the interrupt number currently in use, or will report that the
-polling driver is currently being used.
-.SH AUTHOR
-Nigel Gamble (nigel@gate.net)
diff --git a/sys-utils/lpcntl.c b/sys-utils/lpcntl.c
deleted file mode 100644
index bf164a632..000000000
--- a/sys-utils/lpcntl.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Simple command interface to ioctl(fd, LPSETIRQ, irq).
- * Nigel Gamble (nigel@gate.net)
- * e.g.
- * lpcntl /dev/lp1 7
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <linux/lp.h>
-
-int
-main(int argc, char **argv)
-{
- unsigned int irq;
- int fd;
- int ret;
-
- if (argc < 2) {
- fprintf(stderr, "usage: %s <lp device> [<irq>]\n", argv[0]);
- exit(1);
- }
-
- fd = open(argv[1], O_RDONLY);
- if (fd == -1) {
- perror(argv[1]);
- exit(1);
- }
-
- if (argc == 2) {
- irq = ioctl(fd, LPGETIRQ);
- if (irq == -1) {
- perror(argv[1]);
- exit(1);
- }
- if (irq)
- printf("%s using IRQ %d\n", argv[1], irq);
- else
- printf("%s using polling\n", argv[1]);
- } else {
- irq = atoi(argv[2]);
- ret = ioctl(fd, LPSETIRQ, irq);
- if (ret == -1) {
- if (errno == EPERM)
- fprintf(stderr, "%s: only super-user can change the IRQ\n", argv[0]);
- else
- perror(argv[1]);
- exit(1);
- }
- }
-
- return 0;
-}
diff --git a/sys-utils/sln.1 b/sys-utils/sln.8
index a89271936..f97683d47 100644
--- a/sys-utils/sln.1
+++ b/sys-utils/sln.8
@@ -10,13 +10,14 @@ sln \- static ln
symbolically links
.I dest
to
-.I source
-It is statically linked, needing no dynamic linking at all. This that
-sln is usefull to make symbolic links to dynamic libraries if the
+.IR source .
+It is statically linked, needing no dynamic linking at all. Thus
+.B sln
+is useful to make symbolic links to dynamic libraries if the
dynamic linking system for some reason is nonfunctional.
.SH "SEE ALSO"
.BR ln(1)
.BR ldconfig(8)
.BR ld.so(8)
-.SH AUTHOR
-Mike Parker and David MacKenzie.
+.\" .SH AUTHOR
+.\" Mike Parker and David MacKenzie.