[alt.sources] [comp.unix.questions...] Re: adjtime

chris@mimsy.umd.edu (Chris Torek) (08/06/90)

Archive-name: adjtime/04-Aug-90
Original-posting-by: chris@mimsy.umd.edu (Chris Torek)
Original-subject: Re: adjtime(2) hints needed
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[Reposted from comp.unix.questions,alt.sys.sun.
Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]

In article <2119@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com
(Rahul Dhesi) writes:
>I must supply adjtime(2) with a delta time ... [my] delta_time.tv_sec
>and delta_time.tv_usec could have different signs.  Is this acceptable?

It may be accepted, but it is not a great idea.

The following is a program I wrote some time ago.  error() is a function
that prints an error message (appending strerror(arg2) if arg2!=0) to
stderr, prefixed by the program's name (is there an echo in here? :-) ),
and then quits with exit status arg1 if arg1!=0.  (The program's name
is stashed secretly by the C runtime startup code.)

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>

struct	timeval delta, olddelta;
extern	int errno;

main(argc, argv)
	int argc;
	char **argv;
{

	if (argc < 2) {
		timerclear(&delta);
		if (adjtime(&delta, &olddelta))
			error(1, errno, "adjtime");
		if (adjtime(&olddelta, &delta)) {
			int e = errno;

			showdelta("current adjustment", &olddelta);
			error(1, e, "adjtime (readjust)");
		}
		showdelta("current adjustment", &olddelta);
		exit(0);
	}
	if (convtime(&delta, argv[1]))
		error(1, 0, "invalid time spec %s (should be sec.usec)\n",
			argv[1]);
	if (adjtime(&delta, &olddelta))
		error(1, errno, "adjtime");
	showdelta("old adjustment", &olddelta);
	showdelta("new adjustment", &delta);
	exit(0);
}

convtime(tvp, s)
	register struct timeval *tvp;
	register char *s;
{
	char *usec, *index();
	int neg = 0;

	if (*s == '-') {
		neg++;
		s++;
	}
	usec = index(s, '.');	/* strrchr for SysV folks */
	if (usec != NULL) {
		*usec++ = 0;
		if (convone(&tvp->tv_usec, usec))
			return (-1);
		if (tvp->tv_usec > 999999)
			return (-1);
	} else
		tvp->tv_usec = 0;
	if (convone(&tvp->tv_sec, s))
		return (-1);
	if (neg) {
		tvp->tv_usec = -tvp->tv_usec;
		tvp->tv_sec = -tvp->tv_sec;
	}
	return (0);
}

/* this really should use strtol(), but I did not have it when I wrote this */
convone(lp, s)
	long *lp;
	register char *s;
{
	register long l = 0;
	register int c;

	while ((c = *s++) != 0) {
		if (!isdigit(c))
			return (-1);
		l *= 10;
		if (l < 0)
			return (-1);
		l += c - '0';
		if (l < 0)
			return (-1);
	}
	*lp = l;
	return (0);
}

showdelta(what, tvp)
	char *what;
	struct timeval *tvp;
{
	char *p = "";

	if (tvp->tv_usec < 0) {
		tvp->tv_usec = -tvp->tv_usec;
		if (tvp->tv_sec == 0)
			p = "-";
	}
	(void) printf("%s: %s%ld.%06ld seconds\n", what,
		p, tvp->tv_sec, tvp->tv_usec);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris
	(New campus phone system, active sometime soon: +1 301 405 2750)