/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2014 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
+
/* CFStringDefaultEncoding.h
- Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+ Copyright (c) 1998-2014, Apple Inc. All rights reserved.
*/
#if !defined(__COREFOUNDATION_CFSTRINGDEFAULTENCODING__)
#define __COREFOUNDATION_CFSTRINGDEFAULTENCODING__ 1
-/* This file defines static inline functions used both by CarbonCore & CF. */
-
#include <CoreFoundation/CFBase.h>
-#if defined(__MACH__)
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#include <stdlib.h>
#include <fcntl.h>
#include <pwd.h>
CF_EXTERN_C_BEGIN
#define __kCFUserEncodingEnvVariableName ("__CF_USER_TEXT_ENCODING")
-#define __kCFMaxDefaultEncodingFileLength (24)
+#define __kCFMaxDefaultEncodingFileLength (64)
#define __kCFUserEncodingFileName ("/.CFUserTextEncoding")
-/* This function is used to obtain users' default script/region code.
- The function first looks at environment variable __kCFUserEncodingEnvVariableName, then, reads the configuration file in user's home directory.
-*/
-CF_INLINE void __CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue) {
- char *stringValue;
- char buffer[__kCFMaxDefaultEncodingFileLength];
- int uid = getuid();
-
- if ((stringValue = getenv(__kCFUserEncodingEnvVariableName)) != NULL) {
- if ((uid == strtol_l(stringValue, &stringValue, 0, NULL)) && (':' == *stringValue)) {
- ++stringValue;
- } else {
- stringValue = NULL;
- }
- }
-
- if ((stringValue == NULL) && ((uid > 0) || getenv("HOME"))) {
- struct passwd *passwdp;
-
- if ((passwdp = getpwuid((uid_t)uid))) {
- char filename[MAXPATHLEN + 1];
-
- const char *path = NULL;
- if (!issetugid()) {
- path = getenv("CFFIXED_USER_HOME");
- }
- if (!path) {
- path = passwdp->pw_dir;
- }
-
- strlcpy(filename, path, sizeof(filename));
- strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
-
- int no_hang_fd = open("/dev/autofs_nowait", 0);
- int fd = open(filename, O_RDONLY, 0);
- if (fd == -1) {
- // Cannot open the file. Let's fallback to smRoman/verUS
- snprintf(filename, sizeof(filename), "0x%X:0:0", uid);
- setenv(__kCFUserEncodingEnvVariableName, filename, 1);
- } else {
- int readSize;
-
- // cjk: We do not turn on F_NOCACHE on the fd here, because
- // many processes read this file on startup, and caching the
- // is probably a good thing, for the system as a whole.
- readSize = read(fd, buffer, __kCFMaxDefaultEncodingFileLength - 1);
- buffer[(readSize < 0 ? 0 : readSize)] = '\0';
- close(fd);
- stringValue = buffer;
-
- // Well, we already have a buffer, let's reuse it
- snprintf(filename, sizeof(filename), "0x%X:%s", uid, buffer);
- setenv(__kCFUserEncodingEnvVariableName, filename, 1);
- }
- close(no_hang_fd);
- }
- }
-
- if (stringValue) {
- *oScriptValue = strtol_l(stringValue, &stringValue, 0, NULL);
- if (*stringValue == ':') {
- if (oRegionValue) *oRegionValue = strtol_l(++stringValue, NULL, 0, NULL);
- return;
- }
- }
+CF_EXPORT void _CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue);
+CF_EXPORT void _CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *region);
+CF_EXPORT Boolean _CFStringSaveUserDefaultEncoding(UInt32 iScriptValue, UInt32 iRegionValue);
- // Falling back
- *oScriptValue = 0; // smRoman
- if (oRegionValue) *oRegionValue = 0; // verUS
-}
-
-CF_INLINE uint32_t __CFStringGetInstallationRegion() {
- char *stringValue = NULL;
- char buffer[__kCFMaxDefaultEncodingFileLength];
- struct passwd *passwdp;
-
- if ((passwdp = getpwuid((uid_t)0))) {
- char filename[MAXPATHLEN + 1];
-
- const char *path = NULL;
- if (!issetugid()) {
- path = getenv("CFFIXED_USER_HOME");
- }
- if (!path) {
- path = passwdp->pw_dir;
- }
-
- strlcpy(filename, path, sizeof(filename));
- strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
-
- int no_hang_fd = open("/dev/autofs_nowait", 0);
- int fd = open(filename, O_RDONLY, 0);
- if (fd == -1) {
- int readSize;
-
- // cjk: We do not turn on F_NOCACHE on the fd here, because
- // many processes read this file on startup, and caching the
- // is probably a good thing, for the system as a whole.
- readSize = read(fd, buffer, __kCFMaxDefaultEncodingFileLength - 1);
- buffer[(readSize < 0 ? 0 : readSize)] = '\0';
- close(fd);
- stringValue = buffer;
- }
- close(no_hang_fd);
- }
-
- if (stringValue) {
- (void)strtol_l(stringValue, &stringValue, 0, NULL);
- if (*stringValue == ':') return strtol_l(++stringValue, NULL, 0, NULL);
- }
-
- return 0; // verUS
-}
-
-CF_INLINE void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *region) {
- char *stringValue = NULL;
- char buffer[__kCFMaxDefaultEncodingFileLength];
- struct passwd *passwdp;
-
- *encoding = 0; *region = 0;
-
- if ((passwdp = getpwuid((uid_t)0))) {
- char filename[MAXPATHLEN + 1];
-
- const char *path = NULL;
- if (!issetugid()) {
- path = getenv("CFFIXED_USER_HOME");
- }
- if (!path) {
- path = passwdp->pw_dir;
- }
-
- strlcpy(filename, path, sizeof(filename));
- strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
-
- int no_hang_fd = open("/dev/autofs_nowait", 0);
- int fd = open(filename, O_RDONLY, 0);
- if (fd == -1) {
- int readSize;
-
- readSize = read(fd, buffer, __kCFMaxDefaultEncodingFileLength - 1);
- buffer[(readSize < 0 ? 0 : readSize)] = '\0';
- close(fd);
- stringValue = buffer;
- }
- close(no_hang_fd);
- }
-
- if (stringValue) {
- *encoding = strtol_l(stringValue, &stringValue, 0, NULL);
- if (*stringValue == ':') *region = strtol_l(++stringValue, NULL, 0, NULL);
- }
-}
-
-CF_INLINE void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue, UInt32 iRegionValue) {
- struct passwd *passwdp;
-
- if ((passwdp = getpwuid(getuid()))) {
- char filename[MAXPATHLEN + 1];
-
- const char *path = NULL;
- if (!issetugid()) {
- path = getenv("CFFIXED_USER_HOME");
- }
- if (!path) {
- path = passwdp->pw_dir;
- }
-
- strlcpy(filename, path, sizeof(filename));
- strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
-
- int no_hang_fd = open("/dev/autofs_nowait", 0);
- (void)unlink(filename); // In case, file exists
- int fd = open(filename, O_WRONLY|O_CREAT, 0400);
- if (fd == -1) {
- char buffer[__kCFMaxDefaultEncodingFileLength];
- unsigned int writeSize;
-
- writeSize = snprintf(buffer, __kCFMaxDefaultEncodingFileLength, "0x%X:0x%X", (unsigned int)iScriptValue, (unsigned int)iRegionValue);
- (void)write(fd, buffer, (writeSize > __kCFMaxDefaultEncodingFileLength ? __kCFMaxDefaultEncodingFileLength : writeSize));
- close(fd);
- }
- close(no_hang_fd);
- }
-}
+CF_INLINE void __CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue) { _CFStringGetUserDefaultEncoding(oScriptValue, oRegionValue); }
+CF_INLINE void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *region) { _CFStringGetInstallationEncodingAndRegion(encoding, region); }
+CF_INLINE void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue, UInt32 iRegionValue) { _CFStringSaveUserDefaultEncoding(iScriptValue, iRegionValue); }
CF_EXTERN_C_END
#endif /* ! __COREFOUNDATION_CFSTRINGDEFAULTENCODING__ */
+