[unix-pc.general] syslocal

vern@zebra.UUCP (Vernon C. Hoxie) (11/22/88)

	I'm trying to write a program to reset the clock on the 3b1.
First, I want to be able to read the clock to see if things work. 
This has to be done in the quickest time possible, so I am trying the
syslocal(2) call special to the 3b1.  It has the form:
		int syslocal(cmd, [, arg]
From the manual (ugh) and the syslocal.h file, I get the command to be
"SYSL_RDRTC" and the argument to be of struct rtc *x_rtc.  Now:
		int x = syslocal(SYSL_RDRTC, x_rtc);
gives x = -1.  So I added perror("Error id"); as the next instruction
and got a "Bad address" response.
	How does a system function provide a bad address.  Oh! This is
an AT&T machine (:>).  I'm tempted to go to machine language but it
would be nice to have something a little more portable.  Not portable
fully if I am using syslocal(2), I know.

	Any help will be appreciated.
-- 
Vernon C. Hoxie		       {ncar,nbires,boulder,isis}!scicom!zebra!vern
3975 W. 29th Ave.					voice: 303-477-1780
Denver, Colo., 80212					 uucp: 303-455-2670

randy@cctb.mn.org (Randy Orrison) (11/23/88)

In article <130@zebra.UUCP> vern@zebra.UUCP (Vernon C. Hoxie) writes:
|	I'm trying to write a program to reset the clock on the 3b1.
|First, I want to be able to read the clock to see if things work. 
|This has to be done in the quickest time possible, so I am trying the
|syslocal(2) call special to the 3b1.  It has the form:
|		int syslocal(cmd, [, arg]
|From the manual (ugh) and the syslocal.h file, I get the command to be
|"SYSL_RDRTC" and the argument to be of struct rtc *x_rtc.  Now:
|		int x = syslocal(SYSL_RDRTC, x_rtc);
|gives x = -1.  So I added perror("Error id"); as the next instruction
|and got a "Bad address" response.
|	How does a system function provide a bad address. [?]

It's not giving you a bad address - it's complaining that YOU've given
IT a bad address.  You're giving it a pointer to nothing, and it wants
to store the information there.  You have to actually allocate a 'struct
rtc' for it to place the time into, and then give the address of that to
the syslocal call:

	struct rtc	x_rtc;
	int		err;

	err = syslocal (SYSL_RDRTC, &x_rtc);

should do what you want.

	-randy

-- 
Randy Orrison - Chemical Computer Thinking Battery - randy@cctb.mn.org
(aka randy@{umn-cs.uucp, ux.acss.umn.edu, umnacvx.bitnet, halcdc.uucp})

alex@umbc3.UMD.EDU (Alex S. Crain) (11/24/88)

In article <130@zebra.UUCP> vern@zebra.UUCP (Vernon C. Hoxie) writes:
>
>	I'm trying to write a program to reset the clock on the 3b1.
>First, I want to be able to read the clock to see if things work. 
>This has to be done in the quickest time possible, so I am trying the
>syslocal(2) call special to the 3b1.  It has the form:
>		int syslocal(cmd, [, arg]
>From the manual (ugh) and the syslocal.h file, I get the command to be
>"SYSL_RDRTC" and the argument to be of struct rtc *x_rtc.  Now:
>		int x = syslocal(SYSL_RDRTC, x_rtc);
>gives x = -1.  So I added perror("Error id"); as the next instruction
>and got a "Bad address" response.

	syslocal wants the address of a structure, not a pointer, so the 
correct calling format would be:

	rtc x_rtc;
	int x = syslocal(SYSL_RDRTC, &x_rtc);

This is not terribly obvious, but makes sence if you think about it long 
enough, keeping in mind that C uses call-by-value argument passing.

>	How does a system function provide a bad address.  Oh! This is
>an AT&T machine (:>).

	This is a common mistake, and is more a characteristic of C and Unix
documentation than the vendor. rtx *x_rtc implies "the address of a structure"
without being specific about where that address comes from. The natural 
response is to use a pointer in that situation, and expect the system call to
return an address via the pointer. But a second glance shows that that would 
be impossible, because of call-by-value, and the correct method is to pass
the address of an existing structure.

-- 
					:alex.
					Systems Programmer
nerwin!alex@umbc3.umd.edu		UMBC
alex@umbc3.umd.edu

thad@cup.portal.com (Thad P Floryan) (11/25/88)

Re: handling the UNIXpc's real-time clock, following is some code that WORKS,
extracted from a program I'll be posting to unix-pc.sources in the near future.

Enjoy!

Thad Floryan  [ thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad ]

========================================

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

#ifdef UNIXPC
#include <sys/syslocal.h>
#include <sys/rtc.h>
#endif

	.
	.

#ifdef UNIXPC

/*	Sets the battery-backed Real Time Clock in the UNIXpc to the same
 *	date and time values as the system clock.
 */
set_rtc(tval)
time_t	tval;
{
	struct tm	*p_tm;
	struct rtc	rtc_s;
	struct rtc	*p_rtc;

	p_tm = localtime(&tval);

	p_rtc = &rtc_s;

	p_rtc->wkday = p_tm->tm_wday;
	p_rtc->yr10  = p_tm->tm_year / 10;
	p_rtc->yr1   = p_tm->tm_year % 10;
	p_rtc->mon10 = (p_tm->tm_mon + 1) / 10;
	p_rtc->mon1  = (p_tm->tm_mon + 1) % 10;
	p_rtc->day10 = p_tm->tm_mday / 10;
	p_rtc->day1  = p_tm->tm_mday % 10;
	p_rtc->hr10  = p_tm->tm_hour / 10;
	p_rtc->hr1   = p_tm->tm_hour % 10;
	p_rtc->min10 = p_tm->tm_min / 10;
	p_rtc->min1  = p_tm->tm_min % 10;
	p_rtc->sec10 = p_tm->tm_sec / 10;
	p_rtc->sec1  = p_tm->tm_sec % 10;

	syslocal(SYSL_WRTRTC, p_rtc);	/* write to RTC */

}
#endif