[comp.unix.questions] adjtime

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (08/03/90)

(Environment:  SunOS 4.0.3 on Sun-3 and Sun-4 machines.)

I am trying to use the adjtime(2) system call.

I get the time-of-day from a remote host into a variable "struct
timeval remote_time".  I also call gettimeofday(2) to get the local
time-of-day in the variable "struct timeval local_time".

I must supply adjtime(2) with a delta time by which the local clock
should be adjusted.  So, I want to store this delta into "struct
timeval delta_time".

QUESTION:  How should I use the values remote_time and local_time to
calculate the values in delta_time?  I am currently doing this:

   delta_time.tv_sec  = remote_time.tv_sec  - local_time.tv_sec;
   delta_time.tv_usec = remote_time.tv_usec - local_time.tv_usec;

As a result, delta_time.tv_sec and delta_time.tv_usec could have
different signs.  Is this acceptable?  If not, what should I be doing?
The problem here is that I don't know how delta time is supposed to be
represented in the two fields, and the manuals don't seem to address
the issue.

SECONDARY QUESTION:  I am using the rtime(3) function (which may be
SunOS-specific), to get time from a remote host.  I need to supply
rtime(3) the address of the remote host in a "struct sockaddr_in"
structure.  Am I supposed to place any specific value for a port number
in the sin_port field of this structure?  I find that rtime(3) seems to
work correctly regardless of the value of sin_port, but it would be
nice to know what the official intended usage is.

I will appreciate any help anybody can provide.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

samlb@pioneer.arc.nasa.gov (Sam Bassett RCS) (08/04/90)

	I would add seconds x 1000 to milliseconds in separate temporary
variables, then do the addition or subtraction, and convert back to
seconds -- subtracting seconds and milliseconds separately does not yield
a very usable value . . . . .


Sam'l Bassett, Sterling Software @ NASA Ames Research Center, 
Moffett Field CA 94035 Work: (415) 604-4792;  Home: (415) 969-2644
samlb@well.sf.ca.us                     samlb@ames.arc.nasa.gov 
<Disclaimer> := 'Sterling doesn't _have_ opinions -- much less NASA!'

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

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)