This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC [PATCH] BZ#1077902: New API gettimezone


   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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]