diff mbox

RFC [PATCH] BZ#1077902: New API gettimezone

Message ID 1396499286.85118.YahooMailNeo@web192405.mail.sg3.yahoo.com
State RFC, archived
Headers show

Commit Message

P J P April 3, 2014, 4:28 a.m. UTC
Hello,

WRT BZ#1077902 [1], please see the patch below to introduce a new API gettimezone(). It builds successfully with the glibc Makefile, though I could not test the API from the new library. It uses TZ_VERSION & TZ_FILE macros because they aren't defined in timezone/tzfile.h.


There is #defines TZDEFAULT "localtime", but that is not sufficient to access '/etc/localtime'. There is also #define TZDIR /usr/local/etc/zoneinfo, which seems misplaced. On f19 machine, the zoneinfo is stored under /usr/share/zoneinfo.

===


--
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1077902#c2


Thank you.
---
Regards
   -Prasad
http://feedmug.com

Comments

Paul Eggert April 3, 2014, 5:47 a.m. UTC | #1
I suggest sending this to libc-help first, as it'd need some work before 
it's ready for libc-alpha.  For starters, timezone settings typically 
are not representable as POSIX TZ strings.  More generally, the proposal 
needs more-compelling use cases.
Siddhesh Poyarekar April 3, 2014, 6:44 a.m. UTC | #2
On Wed, Apr 02, 2014 at 10:47:20PM -0700, Paul Eggert wrote:
> I suggest sending this to libc-help first, as it'd need some work before
> it's ready for libc-alpha.  For starters, timezone settings typically are
> not representable as POSIX TZ strings.  More generally, the proposal needs
> more-compelling use cases.

This was in fact sent to libc-help and I suggested sending it here
instead because there's no point in working extensively on the patch
if the proposal is not compelling enough.  Also, I think folks helping
with working on patch are on libc-alpha and not on libc-help.

Siddhesh
P J P April 3, 2014, 9:41 a.m. UTC | #3
Hello Paul,

> On Thursday, 3 April 2014 11:17 AM, Paul Eggert wrote:
> For starters, timezone settings typically are not representable as POSIX TZ strings.

  What do you mean?

> More generally, the proposal needs more-compelling use cases.


  More-compelling than cases wherein '/etc/localtime' is not accessible?

---
Regards
  -Prasad
http://feedmug.com
Andreas Schwab April 3, 2014, 12:18 p.m. UTC | #4
P J P <pj.pandit@yahoo.co.in> writes:

> There is #defines TZDEFAULT "localtime", but that is not sufficient to
> access '/etc/localtime'. There is also #define
> TZDIR /usr/local/etc/zoneinfo, which seems misplaced.

TZDEFAULT and TZDIR are defined on the command line.

Andreas.
P J P April 3, 2014, 5:15 p.m. UTC | #5
Hello Andreas,

> On Thursday, 3 April 2014 5:49 PM, Andreas Schwab wrote:
> TZDEFAULT and TZDIR are defined on the command line. 

  I see. So is it _okay_ to assume that they'll always have correct values and use them as is? Btw, why define them on the command line at build time and not in timezone/tzfile.h header?

Thank you.
---
Regards
   -Prasad
http://feedmug.com
P J P April 3, 2014, 5:30 p.m. UTC | #6
> On Thursday, 3 April 2014 8:15 PM, Paul Eggert wrote:

> Yes, absolutely.  Saying "I want to print the contents of /etc/localtime"
> is not a compelling argument.

  Heh...who said that?

> Why do you want to print its contents?

  Did you see the bug that is listed in the subject line? If not, please see:
-> https://bugzilla.redhat.com/show_bug.cgi?id=1077902.

> What discovery have you made that would impel us to complicate the API?

  Complicate which API?

Btw, you seem to have cross posted your reply to libc-help instead of libc-alpha list. It'll result in distorted list archives, please avoid that.
---
Regards
   -Prasad
http://feedmug.com
Rich Felker April 3, 2014, 7:40 p.m. UTC | #7
On Fri, Apr 04, 2014 at 01:30:36AM +0800, P J P wrote:
> > On Thursday, 3 April 2014 8:15 PM, Paul Eggert wrote:
> 
> > Yes, absolutely.  Saying "I want to print the contents of /etc/localtime"
> > is not a compelling argument.
> 
>   Heh...who said that?
> 
> > Why do you want to print its contents?
> 
>   Did you see the bug that is listed in the subject line? If not, please see:
> -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902.

Classic XY problem. Generating a POSIX TZ string does not solve your
chroot problem, and there's a much simpler approach that does solve
it. I replied on the bug tracker.

Rich
Carlos O'Donell April 3, 2014, 9:53 p.m. UTC | #8
On 04/03/2014 03:40 PM, Rich Felker wrote:
> On Fri, Apr 04, 2014 at 01:30:36AM +0800, P J P wrote:
>>> On Thursday, 3 April 2014 8:15 PM, Paul Eggert wrote:
>>
>>> Yes, absolutely.  Saying "I want to print the contents of /etc/localtime"
>>> is not a compelling argument.
>>
>>   Heh...who said that?
>>
>>> Why do you want to print its contents?
>>
>>   Did you see the bug that is listed in the subject line? If not, please see:
>> -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902.
> 
> Classic XY problem. Generating a POSIX TZ string does not solve your
> chroot problem, and there's a much simpler approach that does solve
> it. I replied on the bug tracker.

The fundamental problem is that it would be nice to have a way
to query the current timezone and launch another process using the
same timezone despite the fact that the the other process might
run in a different configuration (say a chroot, or container defaulting
to EST5EDT).

Why can't the POSIX TZ solve the problem using the ":character"
implementation-defined meaning? We already use this in glibc to
support ":/path/to/tz/file"

The new gettimezone API could just return ":/path/to/tz/file"
which is the expected locale that should be used for current timezone.

The problem could be that your chroot is read-only or part of some
container whose core image is read-only. I don't know that we can
expect the caller to be able to modify the chroot, but it can
certainly adjust the environment to attempt to set the right timezone.

What do we do then? What API or service do we offer?

Cheers,
Carlos.
Rich Felker April 3, 2014, 10:26 p.m. UTC | #9
On Thu, Apr 03, 2014 at 05:53:49PM -0400, Carlos O'Donell wrote:
> On 04/03/2014 03:40 PM, Rich Felker wrote:
> > On Fri, Apr 04, 2014 at 01:30:36AM +0800, P J P wrote:
> >>> On Thursday, 3 April 2014 8:15 PM, Paul Eggert wrote:
> >>
> >>> Yes, absolutely.  Saying "I want to print the contents of /etc/localtime"
> >>> is not a compelling argument.
> >>
> >>   Heh...who said that?
> >>
> >>> Why do you want to print its contents?
> >>
> >>   Did you see the bug that is listed in the subject line? If not, please see:
> >> -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902.
> > 
> > Classic XY problem. Generating a POSIX TZ string does not solve your
> > chroot problem, and there's a much simpler approach that does solve
> > it. I replied on the bug tracker.
> 
> The fundamental problem is that it would be nice to have a way
> to query the current timezone and launch another process using the
> same timezone despite the fact that the the other process might
> run in a different configuration (say a chroot, or container defaulting
> to EST5EDT).
> 
> Why can't the POSIX TZ solve the problem using the ":character"
> implementation-defined meaning? We already use this in glibc to
> support ":/path/to/tz/file"
> 
> The new gettimezone API could just return ":/path/to/tz/file"
> which is the expected locale that should be used for current timezone.

This is a reasonable request, but it doesn't help unless you can copy
the file into the chroot.

> The problem could be that your chroot is read-only or part of some
> container whose core image is read-only. I don't know that we can
> expect the caller to be able to modify the chroot, but it can
> certainly adjust the environment to attempt to set the right timezone.

If it only knows a pathname in the outside-chroot filesystem, how is
it supposed to translate that to an equivalent TZ inside the chroot?
Search the zoneinfo tree for a binary-identical file?

> What do we do then? What API or service do we offer?

TZ service would work but may be overkill...

Rich
Carlos O'Donell April 4, 2014, 2:33 a.m. UTC | #10
On 04/03/2014 06:26 PM, Rich Felker wrote:
>> The fundamental problem is that it would be nice to have a way
>> to query the current timezone and launch another process using the
>> same timezone despite the fact that the the other process might
>> run in a different configuration (say a chroot, or container defaulting
>> to EST5EDT).
>>
>> Why can't the POSIX TZ solve the problem using the ":character"
>> implementation-defined meaning? We already use this in glibc to
>> support ":/path/to/tz/file"
>>
>> The new gettimezone API could just return ":/path/to/tz/file"
>> which is the expected locale that should be used for current timezone.
> 
> This is a reasonable request, but it doesn't help unless you can copy
> the file into the chroot.

We are now in the realm of implementation-defined behaviour so we have
some flexibility?

On Linux you could conceivable encode the timezone compressed into the
TZ var, the largest timezone we have is less than 10kb. That would work
and allow you to pass the entire zone info to the child process without
any coordination or requirement that installed tzdata be compatible.

If you choose not to go this route you can simple document that the
tzdata in the created process must be compatible. This is much more
sensible since the zone info has been around for a long time and will
therefore be generally correct until updated.

>> The problem could be that your chroot is read-only or part of some
>> container whose core image is read-only. I don't know that we can
>> expect the caller to be able to modify the chroot, but it can
>> certainly adjust the environment to attempt to set the right timezone.
> 
> If it only knows a pathname in the outside-chroot filesystem, how is
> it supposed to translate that to an equivalent TZ inside the chroot?
> Search the zoneinfo tree for a binary-identical file?

Use the same path in the chroot and expect tzdata to be as new or newer?

It is much easier for the higher level framework to look at the package
database, determine if all the required packages are in place e.g. a
tzdata that is newer or the same as your tzdata (expecing backwards
compatibility).

You can enforce package version requirements much easier than we can
request root and read-write of the root filesystem to copy /etc/localtime.

You can then abort launching the chroot'd process if the tzdata isn't
new enough that the chroot can run with the right time.

>> What do we do then? What API or service do we offer?
> 
> TZ service would work but may be overkill...

If we made a tz service operate like ntp it would be quite nice.

In summary:

- The request is for an API that allows you to query your own
  timezone in sufficient detail to start another process with the
  same timezone or a different timezone.

  - The value returned by gettimezone could be:

    - Relative path to the zoneinfo file (requires matching tzdata).
      Absolute path to the zoneinfo file (").
    * My preferred solution.

    - Encoded copy of the zoneinfo file (requires libc that can read this).

    - Opaque token (requires coordination with tzdata).

      - Like a uuid with version for each zone.

At present the best known solutions are:

- Standardize on UTC.

- Copy /etc/localtime into the chroot.

  - Requires the ability to write to the chroot

- Read /etc/localtime, if it's version-2-format then continue
  reading the last line of the file which represents the closes
  possible POSIX TZ and use that even if that might not be as
  accurate as the zoneinfo. You can't use this if the line is
  empty.

- Use existing APIs to gather information about the current
  timezone, construct a POSIX-TZ-enviroment-variable-style
  string and use that for the chroots TZ value. Again this is
  inaccurate because it doesn't have enough information.

I need to think about this some more.

Cheers,
Carlos.
P J P April 4, 2014, 5:32 a.m. UTC | #11
> On Friday, 4 April 2014 4:21 AM, Paul Eggert wrote:
> glibc doesn't need an API change.

  It is not an API change. But a fresh new API.

> People who have this problem can save the contents of the TZ
> environment variable (or record that it's unset), 
> and standardize on UTC in /etc/localtime.  That's good enough.

  TZ is not set by default on most systems for '/etc/localtime' is almost always accessible.

For cases when it is not accessible, we need to know appropriate value for the TZ variable. Which is precisely what this new API 'gettimezone()' provides.

Defaulting to UTC when TZ is not set is an easy solution. Many applications did that in the past. But it does not work for users. First, it's a usability disaster and second they have to maintain separate scripts to do time conversions from UTC to their local time when reading timestamps. Imagine reading a log file wherein timestamps are in UTC. First question any user would ask is why is not local time?

> about helping someone use the system than about changing the libc API. 

  It is about a new API that is genuinely useful. Not about changing any existing API.

---
Regards
   -Prasad
http://feedmug.com
Andreas Schwab April 4, 2014, 6:51 a.m. UTC | #12
P J P <pj.pandit@yahoo.co.in> writes:

> Imagine reading a log file wherein timestamps are in UTC. First
> question any user would ask is why is not local time?

Answer: because local time is ambigous.

Andreas.
keld@keldix.com April 4, 2014, 1:11 p.m. UTC | #13
On Thu, Apr 03, 2014 at 05:53:49PM -0400, Carlos O'Donell wrote:
> On 04/03/2014 03:40 PM, Rich Felker wrote:
> > On Fri, Apr 04, 2014 at 01:30:36AM +0800, P J P wrote:
> >>> On Thursday, 3 April 2014 8:15 PM, Paul Eggert wrote:
> >>
> >>> Yes, absolutely.  Saying "I want to print the contents of /etc/localtime"
> >>> is not a compelling argument.
> >>
> >>   Heh...who said that?
> >>
> >>> Why do you want to print its contents?
> >>
> >>   Did you see the bug that is listed in the subject line? If not, please see:
> >> -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902.
> > 
> > Classic XY problem. Generating a POSIX TZ string does not solve your
> > chroot problem, and there's a much simpler approach that does solve
> > it. I replied on the bug tracker.
> 
> The fundamental problem is that it would be nice to have a way
> to query the current timezone and launch another process using the
> same timezone despite the fact that the the other process might
> run in a different configuration (say a chroot, or container defaulting
> to EST5EDT).
> 
> Why can't the POSIX TZ solve the problem using the ":character"
> implementation-defined meaning? We already use this in glibc to
> support ":/path/to/tz/file"
> 
> The new gettimezone API could just return ":/path/to/tz/file"
> which is the expected locale that should be used for current timezone.
> 
> The problem could be that your chroot is read-only or part of some
> container whose core image is read-only. I don't know that we can
> expect the caller to be able to modify the chroot, but it can
> certainly adjust the environment to attempt to set the right timezone.
> 
> What do we do then? What API or service do we offer?

I think we should take into account the timezone keyword of the LC_TIME category in ISO TR 30112.
I think we should aim at least at an API, and I am happy to include a description
of the API in the revision of 30112.


Best regards
keld
Carlos O'Donell April 4, 2014, 8:02 p.m. UTC | #14
On 04/04/2014 09:11 AM, keld@keldix.com wrote:
>> What do we do then? What API or service do we offer?
> 
> I think we should take into account the timezone keyword of the LC_TIME category in ISO TR 30112.
> I think we should aim at least at an API, and I am happy to include a description
> of the API in the revision of 30112.

Would you mind adding any relevant information and a brief summary
to our master todo list under "Date and Time API" or under another
locale-specific entry?

https://sourceware.org/glibc/wiki/Development_Todo/Master#Date_and_Time_API

Cheers,
Carlos.
P J P April 12, 2014, 11:24 a.m. UTC | #15
Ping!

> On Thursday, 3 April 2014 10:01 AM, P J P <pj.pandit@yahoo.co.in> wrote:
>    Hello,
> 
> WRT BZ#1077902 [1], please see the patch below to introduce a new API 
> gettimezone(). It builds successfully with the glibc Makefile, though I could 
> not test the API from the new library. It uses TZ_VERSION & TZ_FILE macros 
> because they aren't defined in timezone/tzfile.h.
> 
> 
> There is #defines TZDEFAULT "localtime", but that is not sufficient to 
> access '/etc/localtime'. There is also #define 
> TZDIR /usr/local/etc/zoneinfo, which seems misplaced. On f19 machine, the 
> zoneinfo is stored under /usr/share/zoneinfo.
> 
> ===
> diff --git a/ChangeLog b/ChangeLog
> index 7e530ef..e2cdbcf 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,8 @@
> +2014-04-03  P J P  <pj.pandit@yahoo.co.in>
> +
> +       [BZ #1077902]
> +       * time/gettimezone.c: new API to query POSIX TZ variable string.
> +
>  2014-04-02  Joseph Myers  <joseph@codesourcery.com>
> 
>         [BZ #16799]
> diff --git a/time/Makefile b/time/Makefile
> index b7f3dba..8bcc5ca 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -31,7 +31,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
>             stime dysize timegm ftime                    \
>             getdate strptime strptime_l                  \
>             strftime wcsftime strftime_l wcsftime_l      \
> -           timespec_get
> +           timespec_get gettimezone
>  aux :=     era alt_digit lc-time-cleanup
> 
>  tests  := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
> 
> diff --git a/time/Versions b/time/Versions
> index fd83818..957d2bf 100644
> --- a/time/Versions
> +++ b/time/Versions
> @@ -25,7 +25,7 @@ libc {
>      ftime;
> 
>      # g*
> -    getitimer; gettimeofday; gmtime; gmtime_r;
> +    getitimer; gettimeofday; gmtime; gmtime_r; gettimezone;
> 
>      # l*
>      localtime; localtime_r;
> diff --git a/time/gettimezone.c b/time/gettimezone.c
> new file mode 100644
> index 0000000..88b2141
> --- /dev/null
> +++ b/time/gettimezone.c
> @@ -0,0 +1,109 @@
> +/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <err.h>
> +#include <errno.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <sys/stat.h>
> +#include <timezone/tzfile.h>
> +
> +#define TZ_VERSION '2'
> +#define TZ_FILE    "/etc/"TZDEFAULT
> +
> +
> +/* gettimezone: reads local timezone definition from '/etc/localtime'
> +   and returns a POSIX TZ environment variable string or NULL in case
> +   of an error; See: tzfile(5), tzset(3).
> +
> +       std offset dst [offset],start[/time],end[/time]
> +
> +   Ex: TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"  */
> +char *
> +gettimezone (const char *tzname)
> +{
> +    int n = 0;
> +    FILE *fp = NULL;
> +    char *tz = NULL, s[4];
> +
> +    errno = 0;
> +    if (!tzname)
> +        tzname = TZ_FILE;
> +
> +    fp = fopen (tzname, "rce");
> +    if (!fp)
> +        return tz;
> +
> +    if (fread (s, sizeof (char), 4, fp) != 4)
> +        goto err;
> +    if (strncmp (TZ_MAGIC, s, 4))
> +        goto err;
> +
> +    if (fread (s, sizeof (char), 1, fp) != 1)
> +        goto err;
> +    if (TZ_VERSION != *s && TZ_VERSION != (*s - 1))
> +        goto err;
> +
> +    if (fseek (fp, -1, SEEK_END) < 0)
> +        goto err;
> +    if (fread (s, sizeof (char), 1, fp) != 1)
> +        goto err;
> +    if ('\n' != *s)
> +        goto err;
> +
> +    n = -2;
> +    while (!fseek (fp, n, SEEK_END))
> +    {
> +        if (fread (s, sizeof (char), 1, fp) != 1)
> +            goto err;
> +        if ('\n' == *s)
> +            break;
> +
> +        n--;
> +    }
> +    fseek (fp, ++n, SEEK_END);
> +
> +    n = -(n + 1);
> +    tz = calloc (n, sizeof (char));
> +    if (!tz)
> +        goto err;
> +
> +    if (fread (tz, sizeof (char), n, fp) != n)
> +    {
> +        free (tz);
> +        tz = NULL;
> +    }
> +
> +err:
> +    fclose (fp);
> +    return tz;
> +}
> +
> +
> +/* int
> +main (int argc, char *argv[])
> +{
> +    char *tz = NULL;
> +
> +    tz = gettimezone (NULL);
> +    printf ("tz: %s\n", tz);
> +    if (tz)
> +        free (tz);
> +
> +    return 0;
> +} */
> ===
> 
> 
> --
> [1] https://bugzilla.redhat.com/show_bug.cgi?id=1077902#c2
> 
> 
> Thank you.
> ---
> Regards
>    -Prasad
> http://feedmug.com
Paul Eggert April 12, 2014, 5:03 p.m. UTC | #16
I'm afraid that subsequent discussion, both on this mailing list and on 
libc-help, has made it clear that the proposed API is not likely to 
reach consensus.  The underlying application problem can already be 
addressed in a standard way, by setting and getting the TZ environment 
variable; it's not significantly harder to modify an entire application 
that way, as to modify it to add a nonstandard library call.  And even 
if the need were greater, the proposed implementation does not work in 
general, because TZ binary files do not always end with strings that are 
appropriate TZ settings.
Carlos O'Donell April 12, 2014, 5:21 p.m. UTC | #17
On 04/12/2014 01:03 PM, Paul Eggert wrote:
> I'm afraid that subsequent discussion, both on this mailing list and
> on libc-help, has made it clear that the proposed API is not likely
> to reach consensus.  The underlying application problem can already
> be addressed in a standard way, by setting and getting the TZ
> environment variable; it's not significantly harder to modify an
> entire application that way, as to modify it to add a nonstandard
> library call.  And even if the need were greater, the proposed
> implementation does not work in general, because TZ binary files do
> not always end with strings that are appropriate TZ settings.

What needs to happen next IMO is that a design document (on the wiki) should
be written up for this work that includes and integrates the suggestions
by various reviewers including Paul's suggestion to look the APIs
that take and create timezone_t and how that should be integrated.

This is a core library, we don't accept hacks, and it takes a long time
to get new APIs accepted.

I don't entirely agree with Paul's points, but I also don't entirely disagree.

Where I disagree is that I think we could make a go at solving PJ's and
other developer problems by providing some way to query the existing in-use
local time as part of the whole and larger API addition to allow printing
locale time via timezone_t's.

Next steps that *someone* needs to do:
* Integrate feedback.
* Write up wiki page with new design.
* Discuss the various recommendations and show which one is best or
  not best.

Discussing this further without summary or a document to reference is
going to get more and more difficult.

Cheers,
Carlos.
P J P April 12, 2014, 5:30 p.m. UTC | #18
> On Saturday, 12 April 2014 10:33 PM, Paul Eggert wrote:
> The underlying application problem can already be addressed in a standard way,
> by setting and getting the TZ environment variable;

  How is user to know what value to set for TZ to get the correct(same as system) time?

> And even if the need were greater, the proposed implementation does not work in 
> general, because TZ binary files do not always end with strings that are 
> appropriate TZ settings.

  Agreed. That is why it is up for review. Nobody said accept the given patch and make it an API.

---
Regards
   -Prasad
http://feedmug.com
P J P April 12, 2014, 5:33 p.m. UTC | #19
> On Saturday, 12 April 2014 10:52 PM, Carlos O'Donell wrote:
> Where I disagree is that I think we could make a go at solving PJ's and
> other developer problems by providing some way to query the existing in-use
> local time as part of the whole and larger API addition to allow printing
> locale time via timezone_t's.
> 
> Next steps that *someone* needs to do:
> * Integrate feedback.
> * Write up wiki page with new design.
> * Discuss the various recommendations and show which one is best or
>   not best.
> 
> Discussing this further without summary or a document to reference is
> going to get more and more difficult.

  Agreed. I'll try and summarise it on the wiki. Does glibc have an existing wiki wherein this kind of summary page can be created?

Thank you.
---
Regards
   -Prasad
http://feedmug.com
Carlos O'Donell April 12, 2014, 8:40 p.m. UTC | #20
On 04/12/2014 01:33 PM, P J P wrote:
>> On Saturday, 12 April 2014 10:52 PM, Carlos O'Donell wrote: Where I
>> disagree is that I think we could make a go at solving PJ's and 
>> other developer problems by providing some way to query the
>> existing in-use local time as part of the whole and larger API
>> addition to allow printing locale time via timezone_t's.
>> 
>> Next steps that *someone* needs to do: * Integrate feedback. *
>> Write up wiki page with new design. * Discuss the various
>> recommendations and show which one is best or not best.
>> 
>> Discussing this further without summary or a document to reference
>> is going to get more and more difficult.
> 
> Agreed. I'll try and summarise it on the wiki. Does glibc have an
> existing wiki wherein this kind of summary page can be created?

Wiki? Yes. 

https://sourceware.org/glibc/wiki/

You'll have to make a new page for the straw-man proposal that will
eventually become the API if we can get consensus.

Note that you cant edit the wiki until someone vouches for you:
https://sourceware.org/glibc/wiki/EditorGroup

You can ask on #glibc on freenode to get added or for someone to
vouch for you as not-a-spammer.

Cheers,
Carlos.
P J P April 13, 2014, 5:36 a.m. UTC | #21
Hello,

> On Sunday, 13 April 2014 2:48 AM, Carlos O'Donell wrote:
> https://sourceware.org/glibc/wiki/
> 
> You'll have to make a new page for the straw-man proposal that will
> eventually become the API if we can get consensus.
> 
> Note that you cant edit the wiki until someone vouches for you:
> https://sourceware.org/glibc/wiki/EditorGroup
> 
> You can ask on #glibc on freenode to get added or for someone to
> vouch for you as not-a-spammer. 

Cool, thank you!
---
Regards
   -Prasad
http://feedmug.com
P J P April 13, 2014, 7:56 a.m. UTC | #22
> On Sunday, 13 April 2014 2:48 AM, Carlos O'Donell wrote:
> Note that you cant edit the wiki until someone vouches for you:
> https://sourceware.org/glibc/wiki/EditorGroup
> 
> You can ask on #glibc on freenode to get added or for someone to
> vouch for you as not-a-spammer. 

  Please see -> http://rst.ninjs.org/?n=5f36bde95828566b339bc0c115ee149a&theme=nature

I've summarised the problem and discussion so far on the page above. Could someone please add me to the EditorGroup list, so that I could create a wiki page for the same?

Thank you.
---
Regards
   -Prasad
http://feedmug.com
P J P April 13, 2014, 6:46 p.m. UTC | #23
> On Sunday, 13 April 2014 1:33 PM, P J P wrote:
> Could someone please add me to the EditorGroup list, so that I could create a wiki 
> page for the same? 

Username: pjp, email same as this one.
---
Regards
   -Prasad
http://feedmug.com
Carlos O'Donell April 14, 2014, 7:13 a.m. UTC | #24
On 04/13/2014 02:46 PM, P J P wrote:
>> On Sunday, 13 April 2014 1:33 PM, P J P wrote:
>> Could someone please add me to the EditorGroup list, so that I could create a wiki 
>> page for the same? 
> 
> Username: pjp, email same as this one.

Done. You can now create the page on the glibc wiki.

Cheers,
Carlos.
P J P April 14, 2014, 10:02 a.m. UTC | #25
> On Monday, 14 April 2014 12:55 PM, Carlos O'Donell wrote:
> Done. You can now create the page on the glibc wiki. 

  Thank you.

Please see -> https://sourceware.org/glibc/wiki/NewTimeZoneAPI

I guess I did something wrong, it created a new tab on the main page.:(
---
Regards
   -Prasad
http://feedmug.com
P J P April 22, 2014, 5:57 a.m. UTC | #26
Ping!

> On Monday, 14 April 2014 3:32 PM, P J P wrote:
> Please see -> https://sourceware.org/glibc/wiki/NewTimeZoneAPI
> 
> ---
> Regards
>    -Prasad
P J P April 29, 2014, 7:15 a.m. UTC | #27
Ping!

WRT -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902#c9

- What modifications would we need to the currently submitted patch?
- Or if we are to go for modifications to tzalloc() routine(s), how do we go about it?

Just checking, for I'm unsure about the details. Any comments/suggestions shall be helpful and welcome.

Thank you.
---
Regards
   -Prasad
http://feedmug.com
Carlos O'Donell April 29, 2014, 9:40 a.m. UTC | #28
On 04/14/2014 06:02 AM, P J P wrote:
>> On Monday, 14 April 2014 12:55 PM, Carlos O'Donell wrote:
>> Done. You can now create the page on the glibc wiki. 
> 
>   Thank you.
> 
> Please see -> https://sourceware.org/glibc/wiki/NewTimeZoneAPI
> 
> I guess I did something wrong, it created a new tab on the main page.:(

You didn't do anything wrong. Page looks good.

Cheers,
Carlos.
Carlos O'Donell April 29, 2014, 9:46 a.m. UTC | #29
On 04/29/2014 03:15 AM, P J P wrote:
> Ping!
> 
> WRT -> https://bugzilla.redhat.com/show_bug.cgi?id=1077902#c9
> 
> - What modifications would we need to the currently submitted patch?
> - Or if we are to go for modifications to tzalloc() routine(s), how do we go about it?
> 
> Just checking, for I'm unsure about the details. Any comments/suggestions shall be helpful and welcome.

The current implementation isn't robust in that the POSIX TZ at the end
of the zone file might not be enough to define the timezone completely.
You need to set TZ to a file e.g. TZ=Country/City where possible and
assume in your use-case that the chroot has an updated set of zones
installed that match. You want to use the TZ file format because it allows
a correct implementation by using all the data in the zone files. The POSIX
TZ is insufficient to be correct all the time.

Can you sketch out the tzalloc-style API and propse it?

Cheers,
Carlos.
P J P April 29, 2014, 12:41 p.m. UTC | #30
Hello,

> On Tuesday, 29 April 2014 3:16 PM, Carlos O'Donell <carlos@redhat.com> wrote:
> The current implementation isn't robust in that the POSIX TZ at the end
> of the zone file might not be enough to define the timezone completely.

  True. TZ variable does not include all the entries from a time zone file. Nonetheless, the TZ string at the end of a zone file does work well because it defines the required offsets from UTC for both standard and daylight savings time. When it does not define such offsets, the default of 1 hour is defined and documented. And for cases wherein the TZ string is absent from a zone file, fall-back to UTC is well reasonable too.

IMO, TZ variable is not expected to hold the 'complete' time zone definition from a zone file. Its syntax does not allow for that:

       std offset dst [offset],start[/time],end[/time]

It could be treated as a minimal time zone definition to be used in circumstances wherein the complete elaborate definition is not accessible. In that sense, the current patch does offer an acceptable working solution.

> You need to set TZ to a file e.g. TZ=Country/City where possible and
> assume in your use-case that the chroot has an updated set of zones
> installed that match. You want to use the TZ file format because it allows
> a correct implementation by using all the data in the zone files. The POSIX
> TZ is insufficient to be correct all the time.

  Agreed. But the 'TZ=Region/City' definition requires that the said file is accessible from the chroot(2) jail. It is not always feasible.

> Can you sketch out the tzalloc-style API and propse it?

  Sure! I'll look into it and get back asap. Is such API expected to make the 'complete' time zone definition available to its consumers?

Thank you.
---
Regards
   -Prasad
http://feedmug.com
Paul Eggert April 29, 2014, 3:11 p.m. UTC | #31
P J P wrote:
> the TZ string at the end of a zone file does work well

Not really.  Sometimes it works, but sometimes it's completely wrong.

> for cases wherein the TZ string is absent from a zone file, fall-back to UTC is well reasonable too

If *that* is good enough, then there's no need to change the API.  Just 
set TZ to "UTC0".  Done.  Which is what apps have done for decades.

I'm afraid I still have the impression that the proposed cure is worse 
than the disease.
Carlos O'Donell April 29, 2014, 6:39 p.m. UTC | #32
On 04/29/2014 11:11 AM, Paul Eggert wrote:
> P J P wrote:
>> the TZ string at the end of a zone file does work well
> 
> Not really.  Sometimes it works, but sometimes it's completely wrong.
> 
>> for cases wherein the TZ string is absent from a zone file, fall-back to UTC is well reasonable too
> 
> If *that* is good enough, then there's no need to change the API.  Just set TZ to "UTC0".  Done.  Which is what apps have done for decades.
> 
> I'm afraid I still have the impression that the proposed cure is worse than the disease.

That may be the case, but at least we had the discussion.

I'm worried only by PJP's assertion that you can't trust the chroot to have the zone file you have yourself.

In that case nothing short of stuffing the zone *into* TZ will help which I'd like to avoid.

Unfortunately all of this complicates the API.

I'll wait and see what PJP comes up with for the tzalloc solution to solve two birds with one stone.

Cheers,
Carlos.
Paul Eggert April 29, 2014, 7:14 p.m. UTC | #33
On 04/29/2014 11:39 AM, Carlos O'Donell wrote:
> In that case nothing short of stuffing the zone*into*  TZ will help
And even that could have problems if the API stuffs a version-3-format 
zone into a TZ string that's shipped to a destination system that groks 
only version 2.Presumably the version number will be in the string 
somewhere so the destination could report an error, but how would that 
actually work?

> Unfortunately all of this complicates the API.
Yes.  This complication is a cost, and the cost/benefit ratio seems 
pretty high here.
P J P April 29, 2014, 7:52 p.m. UTC | #34
Hi,

> On Tuesday, 29 April 2014 8:41 PM, Paul Eggert wrote:
> Not really.  Sometimes it works, but sometimes it's completely wrong.

  I see. Do we know why is it completely wrong, when it is wrong? Do you have an example when it is completely wrong? That'll help to debug the issue.

Because if without the TZ string or with TZ=UTC0, <time.h> APIs can provide accurate UTC times, then all TZ definition helping us with is the offsets and time frame within an year.

> If *that* is good enough, then there's no need to change the API.  Just 

> set TZ to "UTC0".  Done.  Which is what apps have done for decades.

  No! I said UTC is reasonable when the TZ string is absent from the time zone file. Ie. it is the *last* resort, when no other option is *available/possible*.

---

Regards
   -Prasad
http://feedmug.com
P J P April 29, 2014, 8:09 p.m. UTC | #35
> On Wednesday, 30 April 2014 12:09 AM, Carlos O'Donell wrote:
> I'm worried only by PJP's assertion that you can't trust the chroot 
> to have the zone file you have yourself.

  I tried copying time zone file to /etc/localtime under chroot(2) directory, it did not work. Besides, it's an added configuration that user has to do and ensure that it is correct. That is not a good solution IMO.

> In that case nothing short of stuffing the zone *into* TZ will help which 

  The second form of TZ syntax(TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0") is a good option. Many applications use it and depend on it. If its handling is buggy, the least we could do is fix it.
 
> Unfortunately all of this complicates the API.

  True. I'm not suggesting that we stuff the zone file contents into TZ variable.
 
> I'll wait and see what PJP comes up with for the tzalloc solution to solve 

  Sure! But if we agree to not stuff zone file contents into TZ variable, then the only option is to use the TZ string at the end of the zone files, no?

Thank you.
---
Regards
   -Prasad
http://feedmug.com
Carlos O'Donell April 29, 2014, 8:34 p.m. UTC | #36
On 04/29/2014 04:09 PM, P J P wrote:
>> I'll wait and see what PJP comes up with for the tzalloc solution
>> to solve
> 
> Sure! But if we agree to not stuff zone file contents into TZ
> variable, then the only option is to use the TZ string at the end of
> the zone files, no?

I'm not against stuffing the zone file contents into the TZ
env var.

However, in order to do that we'd have to look at the kernel
implementation for at least Linux and Hurd to see if we can put
that much data into the process and the consequences of that.

If we have to share data across a chroot I'm going to ask you
to put your thinking cap on and at least consider alternatives
to using the environment variable pages for storing that data
e.g. shared memory segment checked when the chroot'd
application calls tz* functions?

Think outside the box.

Cheers,
Carlos.
Carlos O'Donell April 29, 2014, 8:59 p.m. UTC | #37
On 04/29/2014 03:14 PM, Paul Eggert wrote:
> On 04/29/2014 11:39 AM, Carlos O'Donell wrote:
>> In that case nothing short of stuffing the zone*into*  TZ will
>> help
> And even that could have problems if the API stuffs a
> version-3-format zone into a TZ string that's shipped to a
> destination system that groks only version 2.Presumably the version
> number will be in the string somewhere so the destination could
> report an error, but how would that actually work?

I'll let PJP think about it.
 
>> Unfortunately all of this complicates the API.
> Yes.  This complication is a cost, and the cost/benefit ratio seems
> pretty high here.

I don't feel like we're done hashing it out.

As I said before I'd like to see the unified tzalloc et. al. solution
since it solves the unique problem of tz-specific messages
per-thread and may with a slight enhancement fix this issue.

The implementation is certainly up in the air, but I reserve my
judgement until later.

Cheers,
Carlos.
Paul Eggert April 29, 2014, 11:36 p.m. UTC | #38
P J P wrote:
> Do we know why is it completely wrong, when it is wrong?

The TZ string contains a prediction of DST behavior after the rest of 
the zoneinfo file's history expires; in general it's incorrect to use 
this string at other times.  For example, the TZ string at the end of 
America/Sao_Paolo is "BRT3BRST,M10.3.0/0,M2.3.0/0", which corresponds to 
our best guess for what happens after the year 2038.  Unfortunately, 
this guess is known to be wrong next year, as Sao Paolo is scheduled to 
switch back to standard time on 2015-02-22, not on 2015-02-15.  So 
shipping TZ="BRT3BRST,M10.3.0/0,M2.3.0/0" to a remote site will 
mishandle many time stamps in Brazil.

> Because if without the TZ string or with TZ=UTC0, <time.h> APIs can provide accurate UTC times, then all TZ definition helping us with is the offsets and time frame within an year.

Sorry, I don't understand this comment.

> I said UTC is reasonable when the TZ string is absent from the time zone file. Ie. it is the *last* resort, when no other option is *available/possible*.

I'm afraid no other option is available or possible under reasonable 
constraints, if the goal is to have gmtime->localtime conversion on the 
remote host exactly match gmtime->localtime conversion with TZ unset on 
the local host even if the two hosts don't have identical tz setups.

One way to work around the problem is to arrange for your hosts to have 
identical tz setups.  That is something you need to do anyway if you 
want gmtime->localtime mappings to match on all hosts.
P J P April 30, 2014, 3:49 p.m. UTC | #39
Hi,

> On Wednesday, 30 April 2014 5:07 AM, Paul Eggert <eggert@cs.ucla.edu> wrote:
> The TZ string contains a prediction of DST behavior after the rest of 
> the zoneinfo file's history expires; in general it's incorrect to use 
> this string at other times.  For example, the TZ string at the end of 
> America/Sao_Paolo is "BRT3BRST,M10.3.0/0,M2.3.0/0", which corresponds 
> to our best guess for what happens after the year 2038.  Unfortunately, 
> this guess is known to be wrong next year, as Sao Paolo is scheduled to 
> switch back to standard time on 2015-02-22, not on 2015-02-15.  So 
> shipping TZ="BRT3BRST,M10.3.0/0,M2.3.0/0" to a remote site will 
> mishandle many time stamps in Brazil.

  Sorry, it's confusing. What is the problem here? It sounds more of incorrect or buggy time zone file. Which is a different issue. We can not deem TZ variable unreliable for it.

>> Because if without the TZ string or with TZ=UTC0, <time.h> APIs can 
> provide accurate UTC times, then all TZ definition helping us with is the 
> offsets and time frame within an year.

> Sorry, I don't understand this comment.

  TZ variable provides offsets which are added to the UTC times to get the local time, right?
 
> I'm afraid no other option is available or possible under reasonable 

> constraints, if the goal is to have gmtime->localtime conversion on the 
> remote host exactly match gmtime->localtime conversion with TZ unset on 
> the local host even if the two hosts don't have identical tz setups.

  From where did you gather this? Goal is to make local system time zone definition available to processes running inside of a chroot(2) jail; On the same host.

---
Regards
   -Prasad
http://feedmug.com
Paul Eggert April 30, 2014, 6:30 p.m. UTC | #40
On 04/30/2014 08:49 AM, P J P wrote:
> It sounds more of incorrect or buggy time zone file.

No, that time zone file is not buggy.  It's generated by the standard 
tzdata distribution, it uses the documented file layout, and many other 
time zone files are like it.  For details, please see the tzfile man page.

> TZ variable provides offsets which are added to the UTC times to get 
> the local time, right?

That's basically right.  (TZ also can provide leap-second info, which 
maps TAI to UTC, but let's ignore that for now.)

> Goal is to make local system time zone definition available to 
> processes running inside of a chroot(2) jail; On the same host.

Sorry, that point was never made clear to me.  In that case, please let 
me rephrase my remark, as follows:

I'm afraid no other option is available or possible under reasonable 
constraints, if the goal is to have gmtime->localtime conversion in the 
chrooted jail exactly match gmtime->localtime conversion with TZ unset 
outside the jail regardless of whether the jail and the main host have 
identical tz files.

One way to work around the problem is to arrange for chrooted jail to 
have identical tz files as the main host.  That is necessary anyway, if 
you want gmtime->localtime mappings to match no matter how applications 
set TZ.  This sort of thing is standard practice for chrooted jails: one 
must set up configuration files, shared libraries, etc. to be the same 
in the jail as in the main host, and the tz files are just another part 
of this.
Rich Felker April 30, 2014, 7:31 p.m. UTC | #41
On Wed, Apr 30, 2014 at 11:30:32AM -0700, Paul Eggert wrote:
> On 04/30/2014 08:49 AM, P J P wrote:
> >It sounds more of incorrect or buggy time zone file.
> 
> No, that time zone file is not buggy.  It's generated by the
> standard tzdata distribution, it uses the documented file layout,
> and many other time zone files are like it.  For details, please see
> the tzfile man page.
> 
> >TZ variable provides offsets which are added to the UTC times to
> >get the local time, right?
> 
> That's basically right.  (TZ also can provide leap-second info,
> which maps TAI to UTC, but let's ignore that for now.)

This is actually a bug. The TZ variable is not specified to modify the
behavior of functions that work with non-local time, and in fact
having gmtime return different results based on the TZ variable is
non-conforming.

Rich
Paul Eggert April 30, 2014, 9:39 p.m. UTC | #42
On 04/30/2014 12:31 PM, Rich Felker wrote:
> having gmtime return different results based on the TZ variable is
> non-conforming.

glibc gmtime doesn't return different results.  Only localtime is 
affected: it throws in leap seconds if you set TZ appropriately. In this 
case gmtime is returning TAI, not the POSIX approximation to UTC.

Anyway, this is not a POSIX conformance issue, as POSIX does not 
constrain gmtime's behavior when the user sets TZ to a value outside the 
POSIX range.
Russ Allbery April 30, 2014, 10:23 p.m. UTC | #43
P J P <pj.pandit@yahoo.co.in> writes:

>   Hi,

>> On Wednesday, 30 April 2014 5:07 AM, Paul Eggert <eggert@cs.ucla.edu> wrote:

>> The TZ string contains a prediction of DST behavior after the rest of 
>> the zoneinfo file's history expires; in general it's incorrect to use 
>> this string at other times.  For example, the TZ string at the end of 
>> America/Sao_Paolo is "BRT3BRST,M10.3.0/0,M2.3.0/0", which corresponds 
>> to our best guess for what happens after the year 2038.  Unfortunately, 
>> this guess is known to be wrong next year, as Sao Paolo is scheduled to 
>> switch back to standard time on 2015-02-22, not on 2015-02-15.  So 
>> shipping TZ="BRT3BRST,M10.3.0/0,M2.3.0/0" to a remote site will 
>> mishandle many time stamps in Brazil.

>   Sorry, it's confusing. What is the problem here? It sounds more of
> incorrect or buggy time zone file. Which is a different issue. We can
> not deem TZ variable unreliable for it.

Let me take a different approach to this, since it feels like you and Paul
are talking past each other.  Maybe I can explain it in a different way
and that will help.

Most people are probably used to fairly predictable time zone rules, where
the time either never changes for a given area or changes twice a year for
something called either "daylight saving time" or "summer time," always
changing on the same day according to some predictable rule, such as 2am
on the second Sunday in March.

However, while this sort of predictability of time zones is a common
property, it is *not* a universal property.  If it were, the work of the
tz mailing list, and Paul as primary maintainer, would be considerably
simpler.

There are some regions where the transition date of daylight saving time
is determined by statute every year, independently, with no forward
guidance given.  In other words, the legislature passes a law, hopefully
reasonably in advance of the start of daylight saving time (but often
not), saying when it will start and end that year, with only casual
attention paid to when it started and ended in previous years.  Or there's
a yearly battle over whether daylight saving time should exist at all, and
sometimes it happens and sometimes it doesn't.  Or there are two
neighboring time zones with which it would be convenient to agree, and the
local time flips back and forth between them at political whim or based on
larger geopolitical concerns at the time.

Cases like this are why the tz database receives regular updates.

I believe that the rule that you're looking to populate in the TZ variable
is the "forward-looking" rule for the zone.  This is the rule that's used
in the absence of any better information for the specific time period in
question.  Usually, it's a blind forward projection of whatever rule was
in place for the year when the database was updated.  Sometimes it's not
even that, such as in the example Paul gave.  Sometimes the best available
information is that the current year is an aberration and the best forward
projection is some previous year, in which case using that rule will get
*current* time wrong, or in this case, the time for next year.

The database says that the rule should not be used for times in those
ranges, so the database is not buggy.  It's just not suited to how you're
trying to use it.

At best, these sorts of forward projections might be correct for
predictable and stable zones like the largest United States time zones or
most European zones, barring fairly disruptive changes in laws.  It is,
however, known to be wrong for some of the zones where the transition
times are determined yearly by statute.  And even when it's not known to
be wrong, it's a guess, and is still likely to be wrong on any given year
until the legislature actually takes up the issue.

This is setting aside the fact that any single rule string cannot easily
represent all the various changes and complexity of historical time, so at
best you would get accurate localtime results for the current time and
possibly times into the future, but those times will often be wrong for
dates in the past because you've discarded most of the rule file.
Carlos O'Donell May 1, 2014, 5:17 a.m. UTC | #44
On 04/30/2014 02:30 PM, Paul Eggert wrote:
> One way to work around the problem is to arrange for chrooted jail to
> have identical tz files as the main host.  That is necessary anyway,
> if you want gmtime->localtime mappings to match no matter how
> applications set TZ.  This sort of thing is standard practice for
> chrooted jails: one must set up configuration files, shared
> libraries, etc. to be the same in the jail as in the main host, and
> the tz files are just another part of this.

It's also necessary to have the same locales in both places if
you are expecting localization to work correctly across the
chroot.

However, even if you had identical files there is presently no
programmatic API to determine your own TZ, and that's part of
the flaw. For localization it's easy you use "setlocale(LC_ALL, NULL);".

The workaround that is suggested is to always set TZ on the
server. Unfortunately that requires administrative privileges
or knowing exactly which file was symlinked, hardlinked, or
copied into /etc/localtime. What if you're on a locked down
VM? Running in an OpenShift gear with no access to /etc/localtime
and no chance of getting OpenShift to modify the server for
you?

It would be easier to just have an API that tells you your
current tz so you can use it to set TZ.

Do we agree that there is a flaw in the API here?

Cheers,
Carlos.
P J P May 1, 2014, 6:07 a.m. UTC | #45
> On Thursday, 1 May 2014 12:00 AM, Paul Eggert wrote:
> One way to work around the problem is to arrange for chrooted jail to 
> have identical tz files as the main host.  That is necessary anyway, if 
> you want gmtime->localtime mappings to match no matter how applications 
> set TZ.  This sort of thing is standard practice for chrooted jails: one 
> must set up configuration files, shared libraries, etc. to be the same 
> in the jail as in the main host, and the tz files are just another part 
> of this.

  I did try to do this multiple times, somehow it does not work. Examples I came across, couple of which are listed on the wiki page, do not seem to do this. Instead, they depend on the TZ variable for the time zone definition. I'm sure there would be other programs too. Thirdly, it's an added task to ensure that the files inside chroot(2) jail are in sync with the ones on the host. And it is an easy one to be missed. That's why it is not the best solution IMO.

---
Regards
   -Prasad
http://feedmug.com
Paul Eggert May 1, 2014, 6:21 a.m. UTC | #46
Carlos O'Donell wrote:
> even if you had identical files there is presently no
> programmatic API to determine your own TZ

But there is a programmatic API, namely getenv ("TZ").  If the chrooted 
files are identical, and if the TZ value (or lack of value) is 
propagated into the chrooted process, localtime should behave the same 
way inside the chrooted jail as it does outside.

That is, it's not necessary to set TZ to the same string both inside and 
outside the jail.  All that's necessary is that if TZ is set outside the 
jail, it must be set to the same value inside the jail, and vice versa.

> Do we agree that there is a flaw in the API here?

That depends on what one means by "flaw".  :-)  My impression so far has 
been that most of the problem has been due to a lack of understanding of 
how time zones work in glibc.  If my impression is correct, then perhaps 
all we need to do is improve the documentation.
Paul Eggert May 1, 2014, 6:22 a.m. UTC | #47
P J P wrote:
> it's an added task to ensure that the files inside chroot(2) jail are in sync with the ones on the host.

If you can't ensure that, then you can't ensure that the time zone 
behaviors will be in sync, no matter what changes we make to glibc's 
API.  This should be obvious.  Please fix that problem first, before 
worrying so much about the API issue.
P J P May 1, 2014, 6:36 a.m. UTC | #48
Hello Russ,

Thanks so much for the explanation.

> On Thursday, 1 May 2014 3:53 AM, Russ Allbery wrote:
> There are some regions where the transition date of daylight saving time
> is determined by statute every year, independently, with no forward
> guidance given.  In other words, the legislature passes a law, hopefully
> reasonably in advance of the start of daylight saving time (but often
> not), saying when it will start and end that year, with only casual
> attention paid to when it started and ended in previous years.  Or there's
> a yearly battle over whether daylight saving time should exist at all, and
> sometimes it happens and sometimes it doesn't.  Or there are two
> neighboring time zones with which it would be convenient to agree, and the
> local time flips back and forth between them at political whim or based on
> larger geopolitical concerns at the time.

> Cases like this are why the tz database receives regular updates.

  Agreed and understood. For some region the DST settings change each year.

> I believe that the rule that you're looking to populate in the TZ variable
> is the "forward-looking" rule for the zone.  This is the rule 
> that's used in the absence of any better information for the specific time period in
> question.  Usually, it's a blind forward projection of whatever rule was
> in place for the year when the database was updated.  Sometimes it's not
> even that, such as in the example Paul gave.  Sometimes the best available
> information is that the current year is an aberration and the best forward
> projection is some previous year, in which case using that rule will get
> *current* time wrong, or in this case, the time for next year.

  Ie. the TZ string at the end of the time zone file is a prediction of how DST would work next year, instead of this(current) year? Did I get it right??

 
> The database says that the rule should not be used for times in those
> ranges, so the database is not buggy.  It's just not suited to how 
> you're trying to use it.

  Sorry, I did not get this part.

> At best, these sorts of forward projections might be correct for
> predictable and stable zones like the largest United States time zones or
> most European zones, barring fairly disruptive changes in laws.  It is,
> however, known to be wrong for some of the zones where the transition
> times are determined yearly by statute.  And even when it's not known to
> be wrong, it's a guess, and is still likely to be wrong on any given year
> until the legislature actually takes up the issue.

  (to confirm) Say 'Sao Paulo' enters DST on 15th March and exits DST on 15th October. In case, on 20th February Sao Paulo's court decides to enter DST on 15th Apr and exit on 15 Nov, then the systems would not reflect that because the tzdata files are not updated to have the new time window. And as result, localtime(3) would show incorrect times for 30 days? Did I get it right??
 
> This is setting aside the fact that any single rule string cannot easily
> represent all the various changes and complexity of historical time, so at
> best you would get accurate localtime results for the current time and
> possibly times into the future, but those times will often be wrong for
> dates in the past because you've discarded most of the rule file.

  So because the tzdata files include the historical time zone settings, one can compute accurate times of the past too. That won't be possible if TZ variable is set to the current time zone settings, right?

I think that is the limitation of the TZ variable we'll have to live with. Because its syntax does not provide room to hold 'complete' contents of a time zone file. If it did, I'm sure we would have defined it accordingly.

---
Regards
   -Prasad
http://feedmug.com
P J P May 1, 2014, 6:40 a.m. UTC | #49
> On Thursday, 1 May 2014 10:47 AM, Carlos O'Donell <carlos@redhat.com> wrote:
> It would be easier to just have an API that tells you your
> current tz so you can use it to set TZ.

> Do we agree that there is a flaw in the API here?

Yes!
---
Regards
   -Prasad
http://feedmug.com
P J P May 1, 2014, 7:05 a.m. UTC | #50
> On Thursday, 1 May 2014 11:52 AM, Paul Eggert wrote:

> But there is a programmatic API, namely getenv ("TZ").

  It requires that TZ is defined and exported on the host. Currently not done by default. And since TZ is not defined, we need a way to determine current system time zone as identified by '/etc/localtime'.

> If the chrooted files are identical, and if the TZ value (or lack of value) is 
> propagated into the chrooted process, localtime should behave the same 
> way inside the chrooted jail as it does outside.

  If '/etc/localtime' is accessible inside chroot(2) jail, there is no need to set TZ variable.

> That is, it's not necessary to set TZ to the same string both inside and 
> outside the jail.  All that's necessary is that if TZ is set outside the 
> jail, it must be set to the same value inside the jail, and vice versa.

  If TZ is set outside the jail, why wouldn't it be accessible inside the jail?

The whole issue exists because TZ is not set by default. And even if you set it to 'TZ=Region/City' format, it requires that the said file is accessible inside chroot(2) jail, which is not always possible.

---
Regards
   -Prasad
http://feedmug.com
Carlos O'Donell May 1, 2014, 7:05 a.m. UTC | #51
On 05/01/2014 02:21 AM, Paul Eggert wrote:
> Carlos O'Donell wrote:
>> even if you had identical files there is presently no programmatic
>> API to determine your own TZ
> 
> But there is a programmatic API, namely getenv ("TZ").  If the
> chrooted files are identical, and if the TZ value (or lack of value)
> is propagated into the chrooted process, localtime should behave the
> same way inside the chrooted jail as it does outside.

Sure, but getenv ("TZ"); right now on an OpenShift gear returns "",
and if I pass my cartridge to someone running in Mumbai, and they
use it the chroot'd process prints the wrong time.

As the user I get to decide how to run my servers and UTC isn't
what I want.

How do I get the TZ out of the running system?
 
> That is, it's not necessary to set TZ to the same string both inside
> and outside the jail.  All that's necessary is that if TZ is set
> outside the jail, it must be set to the same value inside the jail,
> and vice versa.

Sure, but what do I set TZ to?

It seems way more sensible to just provide the missing symmetric
portion of the API than to say "You just have to get all other
distros or frameworks you use to set TZ."

>> Do we agree that there is a flaw in the API here?
> 
> That depends on what one means by "flaw".  :-)  My impression so far
> has been that most of the problem has been due to a lack of
> understanding of how time zones work in glibc.  If my impression is
> correct, then perhaps all we need to do is improve the
> documentation.

I think it's my own failing at explaining why it's relevant and or
important.

On top of all this copying in /etc/localtime for say Docker containers
forces a COW for the changed file and that's a size and performance
issue. Assume you have the same TZ's and all you want is to detect
the local timezone, and pass it to all of your children via env var
TZ. Today you can't detect the local timezone via any API.

Leave the discussion of binary data in TZ out of this discussion
and for another day.

Cheers,
Carlos.
P J P May 1, 2014, 7:16 a.m. UTC | #52
> On Thursday, 1 May 2014 11:52 AM, Paul Eggert wrote:

> If you can't ensure that, then you can't ensure that the time zone 
> behaviors will be in sync, no matter what changes we make to glibc's 
> API.  This should be obvious.  Please fix that problem first, before 
> worrying so much about the API issue.

  Don't just pick on one sentence I said. I also said copying files across chroot(2) jail does not work. Besides, if it worked and we decided to sync files across chroot(2) jail, we would end-up creating something analogous to python-virtualenv or docker or some such thing. Which would copy 'required' files across to the new root and update them as and when required.

---
Regards
   -Prasad
http://feedmug.com
Russ Allbery May 1, 2014, 5:08 p.m. UTC | #53
P J P <pj.pandit@yahoo.co.in> writes:
> On Thursday, 1 May 2014 3:53 AM, Russ Allbery wrote:

>> I believe that the rule that you're looking to populate in the TZ
>> variable is the "forward-looking" rule for the zone.  This is the rule
>> that's used in the absence of any better information for the specific
>> time period in question.  Usually, it's a blind forward projection of
>> whatever rule was in place for the year when the database was updated.
>> Sometimes it's not even that, such as in the example Paul gave.
>> Sometimes the best available information is that the current year is an
>> aberration and the best forward projection is some previous year, in
>> which case using that rule will get *current* time wrong, or in this
>> case, the time for next year.

>   Ie. the TZ string at the end of the time zone file is a prediction of
> how DST would work next year, instead of this(current) year? Did I get
> it right??

No, not quite.  Here's the description from the tzfile man page:

    After the second header and data comes a newline-enclosed, POSIX-TZ-
    environment-variable-style string for use in handling instants after
    the last transition time stored in the file (with nothing between the
    newlines if there is no POSIX representation for such instants).

The TZ string is only applicable to times *after* the last transition time
stored in the file.  In other words, if the file has any specific data for
a given time period, that data overrides the TZ string.  The TZ string is
supposed to be used only as a fallback for times that are beyond the date
range represented in the database file.

So in some cases the TZ string may represent time for next year, if there
is, as yet, no data for next year.  In some cases, it may only be accurate
for time after 2016, or 2020, or 2040, if we have data for all times up to
that point.

In some regions, for example, the rule for daylight saving time is based
on some complex calculation that cannot be represented in a POSIX TZ
string, in which case the database generally contains yearly rules going
quite some distance forward and then either a known-incorrect but not
*too* incorrect TZ string or none at all.

Regardless, using that TZ string for current time, or for any time that
has an actual database rule, is incorrect under the data model of the
file, and in some cases will result in real time errors.

>> The database says that the rule should not be used for times in those
>> ranges, so the database is not buggy.  It's just not suited to how
>> you're trying to use it.

> Sorry, I did not get this part.

I believe you're proposing extracting a fallback rule from a file whose
format is explicitly defined as saying the fallback should only be used
when there is no more specific rule, and using it unconditionally
regardless of whether there's a more specific rule.  Problems caused by
that approach do not represent a bug in the database.

> (to confirm) Say 'Sao Paulo' enters DST on 15th March and exits DST on
> 15th October. In case, on 20th February Sao Paulo's court decides to
> enter DST on 15th Apr and exit on 15 Nov, then the systems would not
> reflect that because the tzdata files are not updated to have the new
> time window. And as result, localtime(3) would show incorrect times for
> 30 days? Did I get it right??

That's the problem with time zone data in general, yes.  But by using the
fallback TZ rule blindly, one would make the problem worse and get times
wrong even if we *do* know what the transitions are and those transitions
are properly documented in the rest of the database file.

> So because the tzdata files include the historical time zone settings,
> one can compute accurate times of the past too. That won't be possible
> if TZ variable is set to the current time zone settings, right?

I am not deeply familiar with the syntax of the POSIX TZ variable, but I
don't believe it can represent multiple rules in different date ranges.

> I think that is the limitation of the TZ variable we'll have to live
> with. Because its syntax does not provide room to hold 'complete'
> contents of a time zone file. If it did, I'm sure we would have defined
> it accordingly.

I, and I suspect many others who care about accurate local time, would
tell you that there are only two reliable ways to use the TZ variable: set
it to UTC and give up on the idea that you know what local time is, or set
it to the identifier of a tz database file that has the accurate time
transitions.

Any other approach will produce incorrect local times.  In some areas,
such as the US, the inaccuracies will only be for historical times.  In
others, they may be inaccurate even for current or near-future times.

Unless I'm mistaken and am missing some representational power in the
format, I believe the other POSIX time zone settings cannot accurately
represent the complexity of real-world time zones.

Now, obviously, if you can make simplifying assumptions for a specific
application, you may be able to use other TZ settings and be correct
within the problem domain of your application.  For example, if you only
care about forward-looking timestamps in the America/Los_Angeles zone, you
can use a fairly simple TZ rule and be as accurate as the full database
would be (namely, accurate until the US Congress changes daylight saving
time again).  There are probably many applications that can make such
simplifying assumptions.  But I'm dubious that glibc can do so.
Paul Eggert May 1, 2014, 5:53 p.m. UTC | #54
On 05/01/2014 12:05 AM, Carlos O'Donell wrote:
> getenv ("TZ"); right now on an OpenShift gear returns "", and if I 
> pass my cartridge to someone running in Mumbai, and they use it the 
> chroot'd process prints the wrong time. 

If getenv ("TZ") returns the empty string both here and in Mumbai, glibc 
localtime will use UTC in both places, so you should be OK.

> How do I get the TZ out of the running system?

getenv ("TZ").

> Sure, but what do I set TZ to?

Whatever you want.  If you're trying to recreate your local environment 
on a remote host, set TZ to the same value as the local host, or leave 
it unset if it's unset on the local host.  So long as your tz files are 
the same in both places, this should work.

> It seems way more sensible to just provide the missing symmetric 
> portion of the API than to say "You just have to get all other distros 
> or frameworks you use to set TZ."

You don't need to get all other distros or frameworks.  Just ensure that 
your tz files are the same in both places.  Which is something you need 
to do *anyway*, if you want TZ settings to work the same in both places.

> On top of all this copying in /etc/localtime for say Docker containers 
> forces a COW for the changed file

That's a minor optimization issue, one that comes up with any sort of 
configuration file, not just time zones.  So you can address it the same 
way you address it for the rest of your configuration.  If it were me, 
I'd simply remove /etc/localtime from all the hosts in question, as 
that's easier to administer and is faster at runtime. But if someone 
wants all their servers to report Mumbai localtime, then whatever floats 
their boat....
Paul Eggert May 1, 2014, 6:17 p.m. UTC | #55
On 05/01/2014 12:05 AM, P J P wrote:
>> But there is a programmatic API, namely getenv ("TZ").
>    It requires that TZ is defined and exported on the host.

No, getenv ("TZ") works just fine when TZ is not set. getenv ("TZ") 
returns a null pointer in that case, and all you need to do is toarrange 
for TZ to be similarly unset in the chrooted jail.

> I also said copying files across chroot(2) jail does not work. Besides, if it worked and we decided to sync files across chroot(2) jail, we would end-up creating something analogous to python-virtualenv or docker or some such thing. Which would copy 'required' files across to the new root and update them as and when required.

I'm not quite following all this, as it seems to say at first that you 
can't arrange for the tz files to be the same, but later that if you 
arrange for the tz files to be the same then you'd need something like 
docker.  The point I was trying to make is that if you want your 
applications to work the same regardless of how they set TZ, then you 
must arrange for the tz files to be the same. This will be true 
regardless of whether the glibc API is changed.

If you don't care whether arbitrary-TZ-setting applications work the 
same, then you needn't keep all the files in sync.  For example, if you 
know your applications will never set TZ='America/Swift_Current' and 
that no sysadmin will ever set system localtime to 
America/Swift_Current, you can omit the file America/Swift_Current from 
your consideration, and not bother to distribute or to update that 
file.  This sort of optimization is application-specific, though, and 
it's not clear that the glibc API needs to be changed to support it.
Carlos O'Donell May 1, 2014, 6:33 p.m. UTC | #56
On 05/01/2014 01:53 PM, Paul Eggert wrote:
> On 05/01/2014 12:05 AM, Carlos O'Donell wrote:
>> getenv ("TZ"); right now on an OpenShift gear returns "", and if I
>> pass my cartridge to someone running in Mumbai, and they use it the
>> chroot'd process prints the wrong time.
> 
> If getenv ("TZ") returns the empty string both here and in Mumbai,
> glibc localtime will use UTC in both places, so you should be OK.

Let me refine the questions because we're talking past each other
at this point.

Goal:

- Set the local time in the chroot to match the server local time.

Assumptions:

- Server and chroot have updated and matching zone info files.

- You don't control the server e.g. OpenShift Gears or Docker.

Solutions:

(1) Have the administrator of the server set the TZ env var to match
  /etc/localtime.

  - Not easy. Extra step for admin.

  - The TZ env var propagates to chroot'd application and time
    is fine.

(2) Copy the /etc/localtime file from the server to the chroot.

  - Requires a RW chroot which is inefficient if you are running
    say on docker in which you desire to keep your base images
    identical. Changes to the images are *real* $$$ costs in say
    EBS storage from AWS.

(3) Provide an API for users to learn what their zone is.

  - User queries zone, sets TZ, and runs chroot'd application.

  - Adds API complexity.

Is you opinion that (1) is the correct solution?

Cheers,
Carlos.
Paul Eggert May 2, 2014, 3:03 a.m. UTC | #57
Carlos O'Donell wrote:

> Assumptions:
>
> - Server and chroot have updated and matching zone info files.
>
> - You don't control the server e.g. OpenShift Gears or Docker.

Another assumption: tz files don't change while applications are 
running, as the apps typically won't notice the change.

> (1) Have the administrator of the server set the TZ env var to match
>    /etc/localtime.

This should work but it's overkill.

> (2) Copy the /etc/localtime file from the server to the chroot.

This should also work, but it's also overkill.  /etc/localtime is a zone 
info file, and you are already assuming that the containing server and 
the chrooted jail have matching zone info files.  Therefore, 
/etc/localtime already matches, and there's no need to copy it.

If your assumption is violated and zone info files do not match, you and 
your containing-server admin need to decide collectively whether this 
mismatch is your problem or your server admin's problem, and then you 
and/or your server admin should fix the problem.  This is true 
regardless of whether we change the glibc API in this area.

Because the server admin's goal should be to make your life easier, 
there should be no need for you to repair mismatched zone info files; 
they should just match.  But if they don't match, and if you don't have 
the time or political oomph to get your server admin to fix them, then 
you need to fix your chrooted copy.

> (3) Provide an API for users to learn what their zone is.

This should work if the API is fancy enough, but any such API (A) would 
need to be designed and implemented and tested and maintained, and (B) 
would probably expose some aspect of glibc internals.  Down the road (B) 
would likely cause more trouble than it'd cure.  Even (A) sounds like 
it's more trouble than the problem is worth.

> Is you opinion that (1) is the correct solution?

(1) should work under the assumptions you gave, so in that sense it's 
correct; but it's not the only working solution and I would suggest 
something different.
Carlos O'Donell May 2, 2014, 6:24 a.m. UTC | #58
On 05/01/2014 11:03 PM, Paul Eggert wrote:
> Carlos O'Donell wrote:
> 
>> Assumptions:
>>
>> - Server and chroot have updated and matching zone info files.
>>
>> - You don't control the server e.g. OpenShift Gears or Docker.
> 
> Another assumption: tz files don't change while applications are
> running, as the apps typically won't notice the change.

I have forked a new thread to discuss this and it is IMO outside
the scope of this discussion.
 
>> (1) Have the administrator of the server set the TZ env var to match
>>    /etc/localtime.

>> Is you opinion that (1) is the correct solution?
> 
> (1) should work under the assumptions you gave, so in that sense it's
> correct; but it's not the only working solution and I would suggest
> something different.

What would you suggest to solve the goal?

Restated here for clarity:

- Set the local time in the chroot to match the server local time.

Would you set both to UTC?

Cheers,
Carlos.
Paul Eggert May 2, 2014, 6:21 p.m. UTC | #59
On 05/01/2014 11:24 PM, Carlos O'Donell wrote:
> What would you suggest to solve the goal?
>
> Restated here for clarity:
>
> - Set the local time in the chroot to match the server local time.
>
> Would you set both to UTC?

Yes.  I would remove /etc/localtime from both the containing server and 
from the chrooted jail.  That's simpler and faster than the other 
alternatives.
P J P May 2, 2014, 6:50 p.m. UTC | #60
Hello Russ,

Thank you for the explanation.

> On Thursday, 1 May 2014 10:38 PM, Russ Allbery <eagle@eyrie.org> wrote:
> The TZ string is only applicable to times *after* the last transition time
> stored in the file.  In other words, if the file has any specific data for
> a given time period, that data overrides the TZ string.  The TZ string is
> supposed to be used only as a fallback for times that are beyond the date
> range represented in the database file.

  Ah, I see. Well, then the new API could be used to return the most suitable value amongst all available.
 

> Any other approach will produce incorrect local times.  In some areas,

> such as the US, the inaccuracies will only be for historical times.  In
> others, they may be inaccurate even for current or near-future times.

> Unless I'm mistaken and am missing some representational power in the
> format, I believe the other POSIX time zone settings cannot accurately
> represent the complexity of real-world time zones.

> Now, obviously, if you can make simplifying assumptions for a specific
> application, you may be able to use other TZ settings and be correct
> within the problem domain of your application.  For example, if you only
> care about forward-looking timestamps in the America/Los_Angeles zone, you
> can use a fairly simple TZ rule and be as accurate as the full database
> would be (namely, accurate until the US Congress changes daylight saving
> time again).  There are probably many applications that can make such
> simplifying assumptions.  But I'm dubious that glibc can do so.
 
  Hmmn, I understand your concern.

The thing is, we are seeking to rely on the fall-back TZ string option because there is none other more suitable for the case in point, ie. chroot(2) jail. Wherein, the system's time zone data is not readily accessible. It that, glibc is not making simplifying assumptions, but merely facilitating it, if the users want to do so.

---
Regards
   -Prasad
http://feedmug.com
P J P May 2, 2014, 8:19 p.m. UTC | #61
> On Friday, 2 May 2014 11:51 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
> Yes.  I would remove /etc/localtime from both the containing server and 
> from the chrooted jail.  That's simpler and faster than the other 
> alternatives.

  IMO, we should not dictate such choice upon users. Instead, we(& glibc) need to facilitate users to make their own choices. Besides, if UTC is and was the only sane choice, why create the inefficient time zone data and define tacky TZ formats that aren't useful. Also don't overlook the fact that even if you say that TZ is bad and should not be used at all, there are real life applications which use it and depend on it. And they do that because it's a standard variable with a well document syntax and function.

---
Regards
   -Prasad
http://feedmug.com
P J P May 27, 2014, 5:22 p.m. UTC | #62
Ping! (sorry I was away for long)
---
Regards
   -Prasad
http://feedmug.com
Ondrej Bilka May 27, 2014, 6:08 p.m. UTC | #63
On Wed, May 28, 2014 at 01:22:43AM +0800, P J P wrote:
> Ping! (sorry I was away for long)
> ---
> Regards
>    -Prasad
> http://feedmug.com

As was previously said I prefer to stick with existing API instead of
new one, so localtime_rz is preferable. It does not to be effective
initially, something like this could work:


pthread_mutex_t l;

localtime_rz(new, resultp)
{
  pthread_mutex_lock (l);
  char *old = strdup (getenv ("TZ"));
  setenv ("TZ", (char *) new);
  tzset ();
  result = localtime (resultp);
  setenv ("TZ", old);
  tzset ();
  free (old);
  pthread_mutex_unlock (l);
  return result;
}
Paul Eggert May 28, 2014, 12:55 a.m. UTC | #64
Ondřej Bílka wrote:
> localtime_rz is preferable

I assume you meant NetBSD's localtime_rz?  It'd be reasonable to add 
that to glibc, or something like it (in glibc it may need a locale 
argument as well).  However, localtime_rz has quite a different API from 
what was in your email, so I didn't understand your suggestion.

http://netbsd.gw.com/cgi-bin/man-cgi?localtime_rz
P J P May 28, 2014, 8:31 a.m. UTC | #65
Hello,

> On Tuesday, 27 May 2014 11:38 PM, Ondřej Bílka <neleai@seznam.cz> wrote:
> As was previously said I prefer to stick with existing API instead of
> new one, so localtime_rz is preferable.

  Previously said, here? I missed it I guess.

> pthread_mutex_t l;

> localtime_rz(new, resultp)
> {
>   pthread_mutex_lock (l);
>   char *old = strdup (getenv ("TZ"));
>   setenv ("TZ", (char *) new);
>   tzset ();
>   result = localtime (resultp);
>   setenv ("TZ", old);
>   tzset ();
>   free (old);
>   pthread_mutex_unlock (l);
>   return result;

> }

  It depends on the user to set TZ variable. Idea is to have an API which will return the 'best fit' value for the TZ variable, which a user can use to set the TZ variable.

---
Regards
   -Prasad
http://feedmug.com
Ondrej Bilka May 28, 2014, 8:57 a.m. UTC | #66
On Tue, May 27, 2014 at 05:55:07PM -0700, Paul Eggert wrote:
> Ondřej Bílka wrote:
> >localtime_rz is preferable
> 
> I assume you meant NetBSD's localtime_rz?  It'd be reasonable to add
> that to glibc, or something like it (in glibc it may need a locale
> argument as well).  However, localtime_rz has quite a different API
> from what was in your email, so I didn't understand your suggestion.
> 
> http://netbsd.gw.com/cgi-bin/man-cgi?localtime_rz

No its same api. You just define timezone_t as char * so you do not have
to implement anything difficult.
Paul Eggert May 28, 2014, 2:34 p.m. UTC | #67
> No its same api. You just define timezone_t as char * so you do not have
> to implement anything difficult.

But you'd still to make copies of the strings that the char * pointers 
point at, no?

Also, this sounds reallllly slow -- perhaps a reasonable 
proof-of-API-concept, but not reasonable as an actual change one would 
want to make to glibc.

> Idea is to have an API which will return the 'best fit' value for the TZ variable

"best fit" is application-dependent.  glibc is not in a position to 
decide what the best fit is for a particular application.

Plus, "best fit" is a weird thing to ask for.  Why would an application 
want an approximation to the TZ setting?  Why wouldn't it want the real 
thing?
Ondrej Bilka May 28, 2014, 6:28 p.m. UTC | #68
On Wed, May 28, 2014 at 07:34:40AM -0700, Paul Eggert wrote:
> >No its same api. You just define timezone_t as char * so you do not have
> >to implement anything difficult.
> 
> But you'd still to make copies of the strings that the char *
> pointers point at, no?
> 
> Also, this sounds reallllly slow -- perhaps a reasonable
> proof-of-API-concept, but not reasonable as an actual change one
> would want to make to glibc.
> 
It is not that slow as a multithread application must do locking
somewhere to get predicable results and localtime now is bit slow.

I measured difference of uncontended performance, main bottleneck was
setenv so I added equality check.

This code is only 2.5 slower than calling localtime_r when uncontended
on haswell.

#include <pthread.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

pthread_mutex_t l;

struct tm *localtime_rz(char *new, time_t *clockp, struct tm *resultp)
{
  pthread_mutex_lock (&l);
  char *old = strdup (getenv ("TZ"));
  if (strcmp(old,new))
    {
      setenv ("TZ", (char *) new, 1);
      tzset ();
    }
  struct tm *result = localtime_r (clockp, resultp);
  if (strcmp(old,new))
    {
      setenv ("TZ", old, 1);
      tzset ();
      free (old);
    }
  pthread_mutex_unlock (&l);
  return result;
}


int main(){
  int i;
  setenv("TZ", "GMT", 1);
  for (i=0;i<10000000;i++)
    {
      time_t c;
      struct tm p;
      //localtime_rz ("GMT", &c, &p);
      localtime_r (&c, &p);
    }
}
Paul Eggert May 28, 2014, 7:59 p.m. UTC | #69
On 05/28/2014 11:28 AM, Ondřej Bílka wrote:
> It is not that slow as a multithread application must do locking
> somewhere to get predicable results

Sure, but I thought we had established that localtime_r itself need not 
do any locking, because a portable application can't expect predictable 
results if it runs localtime_r in one thread while running tzset in another.

> This code is only 2.5 slower than calling localtime_r when uncontended
> on haswell.

It depends on what one means by "not that slow".  To me, 2.5x slower 
than localtime_r is really slow.

Plus, we should do a better job when multiple threads invoke localtime 
near-equivalents simultaneously.  localtime_r already has an unnecessary 
bottleneck due to an unnecessary lock. It would be better to make 
localtime_r faster, instead of using its slowness to justify an API 
that's slower yet.
P J P May 29, 2014, 9:59 a.m. UTC | #70
> On Wednesday, 28 May 2014 8:05 PM, Paul Eggert wrote:
> "best fit" is application-dependent.  glibc is not in a position to 
> decide what the best fit is for a particular application.

  Application dependent?

> Plus, "best fit" is a weird thing to ask for.  Why would an 
> application want an approximation to the TZ setting?  Why wouldn't it want the real 
> > thing?

  Because application(s) can not access the tzdata files and have to depend on the value provided by 'TZ' variable. And 'TZ' variable can not accommodate entire contents of the tzdata file.
 
---
Regards
   -Prasad
http://feedmug.com
Paul Eggert May 29, 2014, 1:55 p.m. UTC | #71
P J P wrote:
>> "best fit" is application-dependent.  glibc is not in a position to
>> >decide what the best fit is for a particular application.
>    Application dependent?

Yes, application dependent.  Scheduling applications, for example, are 
more interested in times in the near future, whereas date-of-birth 
applications are more interested in times in the medium-distant past. 
They have different needs for the "best fit".

>> >Plus, "best fit" is a weird thing to ask for.  Why would an
>> >application want an approximation to the TZ setting?  Why wouldn't it want the real
>>> > >thing?
>    Because application(s) can not access the tzdata files and have to depend on the value provided by 'TZ' variable. And 'TZ' variable can not accommodate entire contents of the tzdata file.

If the problem cannot easily be solved in glibc then let's be honest and 
leave things alone, and let application developers continue to solve the 
problem in the same simple and portable way that they've solved it for 
decades.  This is better than expending resources trying to come up with 
a halfhearted approximation that could well cause more problems than 
it'll fix.
P J P May 30, 2014, 5:54 a.m. UTC | #72
> On Thursday, 29 May 2014 7:25 PM, Paul Eggert wrote:
> Yes, application dependent.  Scheduling applications, for example, are 
> more interested in times in the near future, whereas date-of-birth 
> applications are more interested in times in the medium-distant past. 
> They have different needs for the "best fit".

  I doubt if such applications have any need for a 'best fit' definition, because they do have access to the system's tzdata files.

> If the problem cannot easily be solved in glibc then let's be honest and 

> leave things alone, and let application developers continue to solve the 
> problem in the same simple and portable way that they've solved it for 
> decades.

  That is precisely what the new API for which the patch was submitted early in this thread aims to do.

  1. Many of those applications depend on the value provided by TZ variable.
     Irrespective of whether it is accurate or an approximation.
  2. TZ variable can not accommodate entirety of a tzdata file.
     Because it's standard documented format allows only for a limited definition.
  3. Today if a user has to set TZ variable it is always going to be such limited definition.
     And there are other users who prefer TZ=UTC+0.

Considering these facts, we know that users already use & rely on the limited definition in 'TZ' variable. We are merely trying to facilitate them to easily find the suitable or 'best fit' TZ value.

It'll greatly help to discuss whether 'best fit' is the TZ string at the end of the tzdata file, when it is present, or any other line from the tzdata file.

> a halfhearted approximation that could well cause more problems than it'll fix.

  And what are these more problems?

---
Regards
   -Prasad
http://feedmug.com
Paul Eggert May 30, 2014, 6:20 a.m. UTC | #73
P J P wrote:
>> On Thursday, 29 May 2014 7:25 PM, Paul Eggert wrote:
>> Yes, application dependent.  Scheduling applications, for example, are
>> more interested in times in the near future, whereas date-of-birth
>> applications are more interested in times in the medium-distant past.
>> They have different needs for the "best fit".
>
>    I doubt if such applications have any need for a 'best fit' definition, because they do have access to the system's tzdata files.

No, these applications typically don't access the system's tzdata files 
directly.  They use the glibc API (or its POSIX subset) to get timezone 
information.

>> If the problem cannot easily be solved in glibc then let's be honest and
>> leave things alone, and let application developers continue to solve the
>> problem in the same simple and portable way that they've solved it for
>> decades.
>
>    That is precisely what the new API for which the patch was submitted early in this thread aims to do.

No, the patch proposes a change to the API, which would require programs 
to change if they want to use the new facility.  This is not leaving 
things alone.

> It'll greatly help to discuss whether 'best fit' is the TZ string at the end of the tzdata file, when it is present, or any other line from the tzdata file.

It's not the 'best fit'.  There is no such thing as a global 'best fit'; 
as I explained to you, and as Russ Allbery explained in 
<https://sourceware.org/ml/libc-alpha/2014-05/msg00023.html>.

At this point I feel like we are going around in circles, as you are not 
responding to the issues raised and are merely repeating your proposal.
P J P May 30, 2014, 9:44 a.m. UTC | #74
> On Friday, 30 May 2014 11:50 AM, Paul Eggert wrote:
> No, the patch proposes a change to the API, which would require programs 
> to change if they want to use the new facility.  This is not leaving 
> things alone.

   Did you even look at the patch? It does not change any API, but introduces a new one. If users want they can use it in future.
 
> It's not the 'best fit'.  There is no such thing as a global 'best fit'; 
> as I explained to you, and as Russ Allbery explained in 
> <https://sourceware.org/ml/libc-alpha/2014-05/msg00023.html>.

   I know currently there is no known 'best fit'. That is precisely what I said we could discuss about, read again what I said:

---
It'll greatly help to discuss whether 'best fit' is the TZ string at the end of the tzdata file, when it is present, or any other line from the tzdata file.
---

> At this point I feel like we are going around in circles, as you are not 
> responding to the issues raised and are merely repeating your proposal.

  We are going in circles because you keep overlooking facts and miss-reading what we have been trying to say and digress from any useful discussion.

---

Regards
   -Prasad
http://feedmug.com
Paul Eggert May 30, 2014, 2:40 p.m. UTC | #75
P J P wrote:
>> things alone.
>     Did you even look at the patch? It does not change any API, but introduces a new one.

Yes, of course I looked at the patch.  It would change the glibc API in 
an upwards compatible way.  As I wrote, this would require applications 
to change if they want to use the new facility.  That is not "leaving 
things alone".  As already discussed, applications already have a way to 
solve the problem, one that is widely used and portable: they can set TZ 
to "UTC0" (or to whatever other value they like).  We can therefore 
leave things alone; there's no need for an extension.

> It'll greatly help to discuss whether 'best fit' is the TZ string at the end of the tzdata file, when it is present, or any other line from the tzdata file.

Again, we are going around in circles.  The 'best fit' is not the TZ 
string at the end of the tzdata file.  It is not any other line from the 
tzdata file.  It is not in the tzdata file anywhere.  You are asking for 
something that does not exist.
P J P May 30, 2014, 8:02 p.m. UTC | #76
> On Friday, 30 May 2014 8:10 PM, Paul Eggert wrote:
> As already discussed, applications already have a way to 
> solve the problem, one that is widely used and portable: they can set TZ 
> to "UTC0" (or to whatever other value they like).  We can therefore 
> leave things alone; there's no need for an extension.

  1. Sure! We have no contention with user setting the TZ variable.
 
  2. We are saying that we need to facilitate the user to _know_
     the possible values he/she can use to initialise the TZ variable.

  3. Because if they decide to use non "UTC0" value, they would need
     to account for the Daylight Savings Time(DST) offset.

  4. That implies that they should be able to define the TZ variable
     in the following syntax

     -> std offset dst [offset],start[/time],end[/time]
        TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"

  5. Currently there is no standard way for users to _know_ such value.
     And the given new API addresses this issue.
 
> Again, we are going around in circles.  The 'best fit' is not the TZ 

> string at the end of the tzdata file.  It is not any other line from the 
> tzdata file.  It is not in the tzdata file anywhere.  You are asking for 
> something that does not exist.

  Again you are overlooking the _fact_ that if you ask users to define TZ variable, they are in most certainty, going to define it as the closet approximation _available_ to them. Most likely the last line from the tzdata file.

If the theoretical accuracy and precision that you seek does not exist, why not provide what is available and what we can?

---
Regards
   -Prasad
http://feedmug.com
Rich Felker May 30, 2014, 8:29 p.m. UTC | #77
On Sat, May 31, 2014 at 04:02:15AM +0800, P J P wrote:
> > string at the end of the tzdata file.  It is not any other line from the 
> > tzdata file.  It is not in the tzdata file anywhere.  You are asking for 
> > something that does not exist.
> 
>   Again you are overlooking the _fact_ that if you ask users to
> define TZ variable, they are in most certainty, going to define it
> as the closet approximation _available_ to them. Most likely the
> last line from the tzdata file.
> 
> If the theoretical accuracy and precision that you seek does not
> exist, why not provide what is available and what we can?

The "last line of the TZ file" is what's expected to be in effect past
times represented/representable in the zoneinfo file. There's no
reason to believe it corresponds to what was in effect at a particular
time the user might be interested in. It's fairly likely that it
corresponds to what's in effect "right now". But I think it's a really
bad idea to encourage further use of such zone specifications, which
are inadequate to describe many world timezones.

Rich
P J P May 31, 2014, 5:59 p.m. UTC | #78
On Saturday, 31 May 2014 1:59 AM, Rich Felker wrote:
>The "last line of the TZ file" is what's expected to be in effect past
>times represented/representable in the zoneinfo file. There's no
>reason to believe it corresponds to what was in effect at a particular
>time the user might be interested in.

  Sure, that's possible. If there is a way to figure out what is/was in effect at a particular time, that user is interested in, we should provide that appropriate value.

> It's fairly likely that it corresponds to what's in effect "right now".

  And a user could be interested in that 'right now' time too.

>But I think it's a really bad idea to encourage further use of such zone specifications,
>which are inadequate to describe many world timezones.

   It's better than not having access to any time-zone definition at all.

---
Regards
   -Prasad
http://feedmug.com
diff mbox

Patch

===
diff --git a/ChangeLog b/ChangeLog
index 7e530ef..e2cdbcf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@ 
+2014-04-03  P J P  <pj.pandit@yahoo.co.in>
+
+       [BZ #1077902]
+       * time/gettimezone.c: new API to query POSIX TZ variable string.
+
 2014-04-02  Joseph Myers  <joseph@codesourcery.com>

        [BZ #16799]
diff --git a/time/Makefile b/time/Makefile
index b7f3dba..8bcc5ca 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -31,7 +31,7 @@  routines := offtime asctime clock ctime ctime_r difftime \
            stime dysize timegm ftime                    \
            getdate strptime strptime_l                  \
            strftime wcsftime strftime_l wcsftime_l      \
-           timespec_get
+           timespec_get gettimezone
 aux :=     era alt_digit lc-time-cleanup

 tests  := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \

diff --git a/time/Versions b/time/Versions
index fd83818..957d2bf 100644
--- a/time/Versions
+++ b/time/Versions
@@ -25,7 +25,7 @@  libc {
     ftime;

     # g*
-    getitimer; gettimeofday; gmtime; gmtime_r;
+    getitimer; gettimeofday; gmtime; gmtime_r; gettimezone;

     # l*
     localtime; localtime_r;
diff --git a/time/gettimezone.c b/time/gettimezone.c
new file mode 100644
index 0000000..88b2141
--- /dev/null
+++ b/time/gettimezone.c
@@ -0,0 +1,109 @@ 
+/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <timezone/tzfile.h>
+
+#define TZ_VERSION '2'
+#define TZ_FILE    "/etc/"TZDEFAULT
+
+
+/* gettimezone: reads local timezone definition from '/etc/localtime'
+   and returns a POSIX TZ environment variable string or NULL in case
+   of an error; See: tzfile(5), tzset(3).
+
+       std offset dst [offset],start[/time],end[/time]
+
+   Ex: TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"  */
+char *
+gettimezone (const char *tzname)
+{
+    int n = 0;
+    FILE *fp = NULL;
+    char *tz = NULL, s[4];
+
+    errno = 0;
+    if (!tzname)
+        tzname = TZ_FILE;
+
+    fp = fopen (tzname, "rce");
+    if (!fp)
+        return tz;
+
+    if (fread (s, sizeof (char), 4, fp) != 4)
+        goto err;
+    if (strncmp (TZ_MAGIC, s, 4))
+        goto err;
+
+    if (fread (s, sizeof (char), 1, fp) != 1)
+        goto err;
+    if (TZ_VERSION != *s && TZ_VERSION != (*s - 1))
+        goto err;
+
+    if (fseek (fp, -1, SEEK_END) < 0)
+        goto err;
+    if (fread (s, sizeof (char), 1, fp) != 1)
+        goto err;
+    if ('\n' != *s)
+        goto err;
+
+    n = -2;
+    while (!fseek (fp, n, SEEK_END))
+    {
+        if (fread (s, sizeof (char), 1, fp) != 1)
+            goto err;
+        if ('\n' == *s)
+            break;
+
+        n--;
+    }
+    fseek (fp, ++n, SEEK_END);
+
+    n = -(n + 1);
+    tz = calloc (n, sizeof (char));
+    if (!tz)
+        goto err;
+
+    if (fread (tz, sizeof (char), n, fp) != n)
+    {
+        free (tz);
+        tz = NULL;
+    }
+
+err:
+    fclose (fp);
+    return tz;
+}
+
+
+/* int
+main (int argc, char *argv[])
+{
+    char *tz = NULL;
+
+    tz = gettimezone (NULL);
+    printf ("tz: %s\n", tz);
+    if (tz)
+        free (tz);
+
+    return 0;
+} */