stdlib.c
1 /* 2 * Copyright (c) 2018 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 #include "internal.h" 24 25 #pragma mark API 26 void 27 os_localtime_file(char buff[static 32]) 28 { 29 struct timeval tv; 30 struct tm curtime; 31 32 posix_assert_zero(gettimeofday(&tv, NULL)); 33 (void)localtime_r(&tv.tv_sec, &curtime); 34 35 // Return a time representation that is ideal for use in filenames, so no 36 // spaces or things that need to be escaped. 37 snprintf(buff, 32, "%d-%02d-%02d_%02d.%02d.%02d.%06d", 38 curtime.tm_year + 1900, curtime.tm_mon + 1, curtime.tm_mday, 39 curtime.tm_hour, curtime.tm_min, curtime.tm_sec, tv.tv_usec); 40 } 41 42 // MurmurHash2 was written by Austin Appleby, and is placed in the public 43 // domain. The author hereby disclaims copyright to this source code. 44 uint64_t 45 os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed) 46 { 47 #ifdef __LP64__ 48 // MurmurHash64A 49 const uint64_t m = 0xc6a4a7935bd1e995; 50 const int r = 47; 51 uint64_t h = seed ^ (len * m); 52 const uint64_t * data = (const uint64_t *)buff; 53 const uint64_t * end = data + (len / 8); 54 while(data != end) { 55 uint64_t k = *data++; 56 k *= m; 57 k ^= k >> r; 58 k *= m; 59 h ^= k; 60 h *= m; 61 } 62 const unsigned char * data2 = (const unsigned char *)data; 63 switch(len & 7) { 64 case 7: h ^= ((uint64_t)data2[6]) << 48; 65 case 6: h ^= ((uint64_t)data2[5]) << 40; 66 case 5: h ^= ((uint64_t)data2[4]) << 32; 67 case 4: h ^= ((uint64_t)data2[3]) << 24; 68 case 3: h ^= ((uint64_t)data2[2]) << 16; 69 case 2: h ^= ((uint64_t)data2[1]) << 8; 70 case 1: h ^= ((uint64_t)data2[0]); 71 h *= m; 72 }; 73 h ^= h >> r; 74 h *= m; 75 h ^= h >> r; 76 #else // __LP64__ 77 // MurmurHash64B 78 const uint32_t m = 0x5bd1e995; 79 const int r = 24; 80 81 uint32_t h1 = (uint32_t)(seed) ^ len; 82 uint32_t h2 = (uint32_t)(seed >> 32); 83 84 const uint32_t * data = (const uint32_t *)buff; 85 86 #define MIX(k, h) \ 87 (k) *= m; (k) ^= (k) >> r; (k) *= m; (h) *= m; (h) ^= (k); len -= 4; 88 89 while(len >= 8) { 90 uint32_t k[2]; 91 memcpy(k, (const char*)data, sizeof(k)); 92 data += sizeof(k)/sizeof(k[0]); 93 94 MIX(k[0], h1) 95 MIX(k[1], h2) 96 } 97 98 if(len >= 4) { 99 uint32_t k[1]; 100 memcpy(k, (const char *)data, sizeof(k)); 101 data += sizeof(k)/sizeof(k[0]); 102 103 MIX(k[0], h1); 104 } 105 106 #undef MIX 107 108 switch(len) { 109 case 3: h2 ^= ((unsigned char*)data)[2] << 16; 110 case 2: h2 ^= ((unsigned char*)data)[1] << 8; 111 case 1: h2 ^= ((unsigned char*)data)[0]; 112 h2 *= m; 113 }; 114 115 h1 ^= h2 >> 18; h1 *= m; 116 h2 ^= h1 >> 22; h2 *= m; 117 h1 ^= h2 >> 17; h1 *= m; 118 h2 ^= h1 >> 19; h2 *= m; 119 120 uint64_t h = h1; 121 122 h = (h << 32) | h2; 123 #endif // __LP64__ 124 return h; 125 } 126 127 uint64_t 128 os_simple_hash(const void *buff, size_t len) 129 { 130 return os_simple_hash_with_seed(buff, len, 0); 131 } 132 133 uint64_t 134 os_simple_hash_string_with_seed(const char *string, uint64_t seed) 135 { 136 size_t len = strlen(string); 137 return os_simple_hash_with_seed(string, len, seed); 138 } 139 140 uint64_t 141 os_simple_hash_string(const char *string) 142 { 143 return os_simple_hash_string_with_seed(string, 0); 144 } 145 146 errno_t 147 realpath_np(os_fd_t fd, char buff[static PATH_MAX]) 148 { 149 errno_t error = -1; 150 int ret = -1; 151 152 ret = fcntl(fd, F_GETPATH, buff); 153 if (ret) { 154 error = errno; 155 } else { 156 error = 0; 157 } 158 159 return error; 160 } 161 162 errno_t 163 memdup_np(void **_new, const void *src, size_t len) 164 { 165 void *mynew = NULL; 166 167 mynew = malloc(len); 168 if (!mynew) { 169 return errno; 170 } 171 172 memcpy(mynew, src, len); 173 *_new = mynew; 174 return 0; 175 } 176 177 void * 178 memdup2_np(const void *src, size_t len) 179 { 180 void *_new = os_malloc(len); 181 memcpy(_new, src, len); 182 return _new; 183 }