Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Mar 2010 01:30:39 -0400
From:      Mark Shroyer <subscriber+freebsd@markshroyer.com>
To:        freebsd-questions@freebsd.org
Cc:        Peter Steele <psteele@maxiscale.com>
Subject:   Re: How to make a process detect time zone change?
Message-ID:  <4BA068FF.6000305@markshroyer.com>
In-Reply-To: <7B9397B189EB6E46A5EE7B4C8A4BB7CB3B27D7F5@MBX03.exg5.exghost.com>
References:  <7B9397B189EB6E46A5EE7B4C8A4BB7CB3B27D7F5@MBX03.exg5.exghost.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 3/16/2010 11:23 AM, Peter Steele wrote:
> We have a system controlled through a Java GUI and one of the
> commands provided in the GUI is to change the date/time, including
> the time zone. When the time zone is changed the FreeBSD system
> immediately recognizes the change (that is, the date command from the
> command line shows the correct time and time zone). However, our
> running C apps do not recognize that a time zone change has occurred
> unless they are restarted. What's the proper way to inform an active
> process that a time zone change has occurred? I've tried tzset() and
> tzsetwall() but neither seem to do the trick. The only thing I've
> found that works is to restart the process, and that's not really a
> solution.

I think I have a solution.  First I tried the following code:

> #include <stdio.h>
> #include <time.h>
> #include <unistd.h>
>
> int main(int argc, char* argv[])
> {
>     time_t now;
>     struct tm localNow;
>
>     for (;;) {
>         time(&now);
>         tzsetwall();
>         localtime_r(&now, &localNow);
>         printf("%02d:%02d:%02d %s\n", localNow.tm_hour,
>                                       localNow.tm_min,
>                                       localNow.tm_sec,
>                                       localNow.tm_zone);
>         sleep(1);
>     }
>
>     return 0;
> }

While this was running I set /etc/localtime to a different time zone,
and sure enough, my process failed to pick up the new zone until I
killed and restarted it.  However, when I passed the environment
variable TZ=/etc/localtime to the program:

> $ env TZ=/etc/localtime ./a.out
> 06:11:30 MET
> 06:11:31 MET
> 06:11:32 MET
> 06:11:33 MET
> 01:11:34 EDT
> 01:11:35 EDT
> 01:11:36 EDT
> ^C$

So there it is: set TZ=/etc/localtime and use tzsetwall() to update the
time zone within the process.  In my reading, the tzsetwall(3)
documentation does seem to imply tzsetwall() would check /etc/localtime
even if TZ isn't set, but apparently this isn't the case; maybe the man
page could be clarified on this point?

Anyway, I hope this helps...

-- 
Mark Shroyer
http://markshroyer.com/contact/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BA068FF.6000305>