< prev index next >

src/java.base/unix/native/libjava/TimeZone_md.c

Print this page


   1 /*
   2  * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  35 #include <string.h>
  36 #include <dirent.h>
  37 #include <unistd.h>
  38 #if defined(__solaris__)
  39 #include <libscf.h>
  40 #endif
  41 
  42 #include "jvm.h"
  43 #include "TimeZone_md.h"
  44 
  45 #define SKIP_SPACE(p)   while (*p == ' ' || *p == '\t') p++;
  46 
  47 #define RESTARTABLE(_cmd, _result) do { \
  48   do { \
  49     _result = _cmd; \
  50   } while((_result == -1) && (errno == EINTR)); \
  51 } while(0)
  52 
  53 #if defined(_ALLBSD_SOURCE)
  54 #define dirent64 dirent
  55 #define readdir64_r readdir_r
  56 #endif
  57 
  58 #if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
  59 #define fileopen        fopen
  60 #define filegets        fgets
  61 #define fileclose       fclose
  62 #endif
  63 
  64 #if defined(__linux__) || defined(_ALLBSD_SOURCE)
  65 static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
  66 static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
  67 static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
  68 #else
  69 static const char *SYS_INIT_FILE = "/etc/default/init";
  70 static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
  71 static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
  72 #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
  73 
  74 #if defined(_AIX)
  75 static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";


 105     path = (char *) malloc(strlen(dir) + strlen(name) + 2);
 106     if (path == NULL) {
 107         return NULL;
 108     }
 109     return strcat(strcat(strcpy(path, dir), "/"), name);
 110 }
 111 
 112 /*
 113  * Scans the specified directory and its subdirectories to find a
 114  * zoneinfo file which has the same content as /etc/localtime on Linux
 115  * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
 116  * If file is symbolic link, then the contents it points to are in buf.
 117  * Returns a zone ID if found, otherwise, NULL is returned.
 118  */
 119 static char *
 120 findZoneinfoFile(char *buf, size_t size, const char *dir)
 121 {
 122     DIR *dirp = NULL;
 123     struct stat statbuf;
 124     struct dirent64 *dp = NULL;
 125     struct dirent64 *entry = NULL;
 126     char *pathname = NULL;
 127     int fd = -1;
 128     char *dbuf = NULL;
 129     char *tz = NULL;
 130     int res;
 131     long name_max = 0;
 132 
 133     dirp = opendir(dir);
 134     if (dirp == NULL) {
 135         return NULL;
 136     }
 137 
 138     name_max = pathconf(dir, _PC_NAME_MAX);
 139     // If pathconf did not work, fall back to a mimimum buffer size.
 140     if (name_max < 1024) {
 141         name_max = 1024;
 142     }
 143 
 144     entry = (struct dirent64 *)malloc(offsetof(struct dirent64, d_name) + name_max + 1);
 145     if (entry == NULL) {
 146         (void) closedir(dirp);
 147         return NULL;
 148     }
 149 
 150     while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
 151         /*
 152          * Skip '.' and '..' (and possibly other .* files)
 153          */
 154         if (dp->d_name[0] == '.') {
 155             continue;
 156         }
 157 
 158         /*
 159          * Skip "ROC", "posixrules", and "localtime".
 160          */
 161         if ((strcmp(dp->d_name, "ROC") == 0)
 162             || (strcmp(dp->d_name, "posixrules") == 0)
 163 #if defined(__solaris__)
 164             /*
 165              * Skip the "src" and "tab" directories on Solaris.
 166              */
 167             || (strcmp(dp->d_name, "src") == 0)
 168             || (strcmp(dp->d_name, "tab") == 0)
 169 #endif
 170             || (strcmp(dp->d_name, "localtime") == 0)) {


 197             RESTARTABLE(read(fd, dbuf, size), res);
 198             if (res != (ssize_t) size) {
 199                 break;
 200             }
 201             if (memcmp(buf, dbuf, size) == 0) {
 202                 tz = getZoneName(pathname);
 203                 if (tz != NULL) {
 204                     tz = strdup(tz);
 205                 }
 206                 break;
 207             }
 208             free((void *) dbuf);
 209             dbuf = NULL;
 210             (void) close(fd);
 211             fd = -1;
 212         }
 213         free((void *) pathname);
 214         pathname = NULL;
 215     }
 216 
 217     if (entry != NULL) {
 218         free((void *) entry);
 219     }
 220     if (dirp != NULL) {
 221         (void) closedir(dirp);
 222     }
 223     if (pathname != NULL) {
 224         free((void *) pathname);
 225     }
 226     if (fd != -1) {
 227         (void) close(fd);
 228     }
 229     if (dbuf != NULL) {
 230         free((void *) dbuf);
 231     }
 232     return tz;
 233 }
 234 
 235 #if defined(__linux__) || defined(MACOSX)
 236 
 237 /*
 238  * Performs Linux specific mapping and returns a zone ID
 239  * if found. Otherwise, NULL is returned.


   1 /*
   2  * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  35 #include <string.h>
  36 #include <dirent.h>
  37 #include <unistd.h>
  38 #if defined(__solaris__)
  39 #include <libscf.h>
  40 #endif
  41 
  42 #include "jvm.h"
  43 #include "TimeZone_md.h"
  44 
  45 #define SKIP_SPACE(p)   while (*p == ' ' || *p == '\t') p++;
  46 
  47 #define RESTARTABLE(_cmd, _result) do { \
  48   do { \
  49     _result = _cmd; \
  50   } while((_result == -1) && (errno == EINTR)); \
  51 } while(0)
  52 
  53 #if defined(_ALLBSD_SOURCE)
  54 #define dirent64 dirent
  55 #define readdir64 readdir
  56 #endif
  57 
  58 #if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
  59 #define fileopen        fopen
  60 #define filegets        fgets
  61 #define fileclose       fclose
  62 #endif
  63 
  64 #if defined(__linux__) || defined(_ALLBSD_SOURCE)
  65 static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
  66 static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
  67 static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
  68 #else
  69 static const char *SYS_INIT_FILE = "/etc/default/init";
  70 static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
  71 static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
  72 #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
  73 
  74 #if defined(_AIX)
  75 static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";


 105     path = (char *) malloc(strlen(dir) + strlen(name) + 2);
 106     if (path == NULL) {
 107         return NULL;
 108     }
 109     return strcat(strcat(strcpy(path, dir), "/"), name);
 110 }
 111 
 112 /*
 113  * Scans the specified directory and its subdirectories to find a
 114  * zoneinfo file which has the same content as /etc/localtime on Linux
 115  * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
 116  * If file is symbolic link, then the contents it points to are in buf.
 117  * Returns a zone ID if found, otherwise, NULL is returned.
 118  */
 119 static char *
 120 findZoneinfoFile(char *buf, size_t size, const char *dir)
 121 {
 122     DIR *dirp = NULL;
 123     struct stat statbuf;
 124     struct dirent64 *dp = NULL;

 125     char *pathname = NULL;
 126     int fd = -1;
 127     char *dbuf = NULL;
 128     char *tz = NULL;
 129     int res;

 130 
 131     dirp = opendir(dir);
 132     if (dirp == NULL) {
 133         return NULL;
 134     }
 135 
 136     while ((dp = readdir64(dirp)) != NULL) {












 137         /*
 138          * Skip '.' and '..' (and possibly other .* files)
 139          */
 140         if (dp->d_name[0] == '.') {
 141             continue;
 142         }
 143 
 144         /*
 145          * Skip "ROC", "posixrules", and "localtime".
 146          */
 147         if ((strcmp(dp->d_name, "ROC") == 0)
 148             || (strcmp(dp->d_name, "posixrules") == 0)
 149 #if defined(__solaris__)
 150             /*
 151              * Skip the "src" and "tab" directories on Solaris.
 152              */
 153             || (strcmp(dp->d_name, "src") == 0)
 154             || (strcmp(dp->d_name, "tab") == 0)
 155 #endif
 156             || (strcmp(dp->d_name, "localtime") == 0)) {


 183             RESTARTABLE(read(fd, dbuf, size), res);
 184             if (res != (ssize_t) size) {
 185                 break;
 186             }
 187             if (memcmp(buf, dbuf, size) == 0) {
 188                 tz = getZoneName(pathname);
 189                 if (tz != NULL) {
 190                     tz = strdup(tz);
 191                 }
 192                 break;
 193             }
 194             free((void *) dbuf);
 195             dbuf = NULL;
 196             (void) close(fd);
 197             fd = -1;
 198         }
 199         free((void *) pathname);
 200         pathname = NULL;
 201     }
 202 



 203     if (dirp != NULL) {
 204         (void) closedir(dirp);
 205     }
 206     if (pathname != NULL) {
 207         free((void *) pathname);
 208     }
 209     if (fd != -1) {
 210         (void) close(fd);
 211     }
 212     if (dbuf != NULL) {
 213         free((void *) dbuf);
 214     }
 215     return tz;
 216 }
 217 
 218 #if defined(__linux__) || defined(MACOSX)
 219 
 220 /*
 221  * Performs Linux specific mapping and returns a zone ID
 222  * if found. Otherwise, NULL is returned.


< prev index next >