| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include "platform/globals.h" | |
| #if defined(HOST_OS_MACOS) | |
| #include "platform/utils.h" | |
| #include <errno.h> // NOLINT | |
| #include <sys/utsname.h> // NOLINT | |
| namespace dart { | |
| char* Utils::StrNDup(const char* s, intptr_t n) { | |
| // strndup has only been added to Mac OS X in 10.7. We are supplying | |
| // our own copy here if needed. | |
| #if !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \ | |
| __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1060 | |
| intptr_t len = strlen(s); | |
| if ((n < 0) || (len < 0)) { | |
| return NULL; | |
| } | |
| if (n < len) { | |
| len = n; | |
| } | |
| char* result = reinterpret_cast<char*>(malloc(len + 1)); | |
| if (result == NULL) { | |
| return NULL; | |
| } | |
| result[len] = '\0'; | |
| return reinterpret_cast<char*>(memmove(result, s, len)); | |
| #else // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ... | |
| return strndup(s, n); | |
| #endif // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ... | |
| } | |
| char* Utils::StrDup(const char* s) { | |
| return strdup(s); | |
| } | |
| intptr_t Utils::StrNLen(const char* s, intptr_t n) { | |
| // strnlen has only been added to Mac OS X in 10.7. We are supplying | |
| // our own copy here if needed. | |
| #if !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \ | |
| __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1060 | |
| intptr_t len = 0; | |
| while ((len <= n) && (*s != '\0')) { | |
| s++; | |
| len++; | |
| } | |
| return len; | |
| #else // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ... | |
| return strnlen(s, n); | |
| #endif // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ... | |
| } | |
| int Utils::SNPrint(char* str, size_t size, const char* format, ...) { | |
| va_list args; | |
| va_start(args, format); | |
| int retval = VSNPrint(str, size, format, args); | |
| va_end(args); | |
| return retval; | |
| } | |
| int Utils::VSNPrint(char* str, size_t size, const char* format, va_list args) { | |
| int retval = vsnprintf(str, size, format, args); | |
| if (retval < 0) { | |
| FATAL1("Fatal error in Utils::VSNPrint with format '%s'", format); | |
| } | |
| return retval; | |
| } | |
| int Utils::Close(int fildes) { | |
| return close(fildes); | |
| } | |
| size_t Utils::Read(int filedes, void* buf, size_t nbyte) { | |
| return read(filedes, buf, nbyte); | |
| } | |
| int Utils::Unlink(const char* path) { | |
| return unlink(path); | |
| } | |
| namespace internal { | |
| // Returns the running system's Darwin major version. Don't call this, it's | |
| // an implementation detail and its result is meant to be cached by | |
| // MacOSXMinorVersion. | |
| int32_t DarwinMajorVersionInternal() { | |
| // uname is implemented as a simple series of sysctl system calls to | |
| // obtain the relevant data from the kernel. The data is | |
| // compiled right into the kernel, so no threads or blocking or other | |
| // funny business is necessary. | |
| struct utsname uname_info; | |
| if (uname(&uname_info) != 0) { | |
| FATAL("Fatal error in DarwinMajorVersionInternal : invalid return uname"); | |
| return 0; | |
| } | |
| if (strcmp(uname_info.sysname, "Darwin") != 0) { | |
| FATAL1( | |
| "Fatal error in DarwinMajorVersionInternal : unexpected uname" | |
| " sysname '%s'", | |
| uname_info.sysname); | |
| return 0; | |
| } | |
| int32_t darwin_major_version = 0; | |
| char* dot = strchr(uname_info.release, '.'); | |
| if (dot) { | |
| errno = 0; | |
| char* end_ptr = NULL; | |
| darwin_major_version = strtol(uname_info.release, &end_ptr, 10); | |
| if (errno != 0 || (end_ptr == uname_info.release)) { | |
| dot = NULL; | |
| } | |
| } | |
| if (!dot) { | |
| FATAL1( | |
| "Fatal error in DarwinMajorVersionInternal :" | |
| " could not parse uname release '%s'", | |
| uname_info.release); | |
| return 0; | |
| } | |
| return darwin_major_version; | |
| } | |
| // Returns the running system's Mac OS X minor version. This is the |y| value | |
| // in 10.y or 10.y.z. Don't call this, it's an implementation detail and the | |
| // result is meant to be cached by MacOSXMinorVersion. | |
| int32_t MacOSXMinorVersionInternal() { | |
| int darwin_major_version = DarwinMajorVersionInternal(); | |
| // The Darwin major version is always 4 greater than the Mac OS X minor | |
| // version for Darwin versions beginning with 6, corresponding to Mac OS X | |
| // 10.2. Since this correspondence may change in the future, warn when | |
| // encountering a version higher than anything seen before. Older Darwin | |
| // versions, or versions that can't be determined, result in | |
| // immediate death. | |
| ASSERT(darwin_major_version >= 6); | |
| return (darwin_major_version - 4); | |
| } | |
| int32_t MacOSXMinorVersion() { | |
| static int mac_os_x_minor_version = MacOSXMinorVersionInternal(); | |
| return mac_os_x_minor_version; | |
| } | |
| } // namespace internal | |
| } // namespace dart | |
| #endif // defined(HOST_OS_MACOS) |