This fixes a bug in PHP/HH's crypt_blowfish implementation that can cause a short...
[hiphop-php.git] / hphp / util / compatibility.cpp
blob519c829c6b8884c325758138308a7e51c5844d43
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/util/compatibility.h"
19 #include "hphp/util/assertions.h"
21 #include <cstdarg>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
29 #include <folly/portability/Fcntl.h>
30 #include <folly/portability/Unistd.h>
32 namespace HPHP {
33 ///////////////////////////////////////////////////////////////////////////////
35 #if defined(__APPLE__) || defined(__FreeBSD__)
36 char *strndup(const char* str, size_t len) {
37 size_t str_len = strlen(str);
38 if (len < str_len) {
39 str_len = len;
41 char *result = (char*)malloc(str_len + 1);
42 if (result == nullptr) {
43 return nullptr;
45 memcpy(result, str, str_len);
46 result[str_len] = '\0';
47 return result;
50 int dprintf(int fd, const char *format, ...) {
51 va_list ap;
52 char *ptr = nullptr;
53 int ret = 0;
55 va_start(ap, format);
56 vasprintf(&ptr, format, ap);
57 va_end(ap);
59 if (ptr) {
60 ret = write(fd, ptr, strlen(ptr));
61 free(ptr);
64 return ret;
67 int pipe2(int pipefd[2], int flags) {
68 if (flags & ~(O_CLOEXEC | O_NONBLOCK)) {
69 always_assert(!"Unknown flag passed to pipe2 compatibility layer");
72 if (pipe(pipefd) < 0) {
73 return -1;
76 if (flags & O_CLOEXEC) {
77 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1 ||
78 fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1) {
79 close(pipefd[0]);
80 close(pipefd[1]);
81 return -1;
85 if (flags & O_NONBLOCK) {
86 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1 ||
87 fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1) {
88 close(pipefd[0]);
89 close(pipefd[1]);
90 return -1;
94 return 0;
96 #endif
98 int fadvise_dontneed(int fd, off_t len) {
99 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(_MSC_VER)
100 return 0;
101 #else
102 return posix_fadvise(fd, 0, len, POSIX_FADV_DONTNEED);
103 #endif
106 int advise_out(const std::string& fileName) {
107 if (fileName.empty()) return -1;
108 int fd = open(fileName.c_str(), O_RDONLY);
109 if (fd == -1) return -1;
110 int result = fadvise_dontneed(fd, 0);
111 close(fd);
112 return result;
115 #ifdef _MSC_VER
116 #include <windows.h>
118 // since we only support win 7+
119 // capturestackbacktrace is always available in kernel
120 int backtrace(void **buffer, int size) {
121 USHORT frames;
123 if (size <= 0) {
124 return 0;
127 frames = CaptureStackBackTrace(0, (DWORD) size, buffer, nullptr);
129 return (int) frames;
132 int dladdr(const void *addr, Dl_info *info) {
133 MEMORY_BASIC_INFORMATION mem_info;
134 char moduleName[MAX_PATH];
136 if(!VirtualQuery(addr, &mem_info, sizeof(mem_info))) {
137 return 0;
140 if(!GetModuleFileNameA(nullptr, moduleName, sizeof(moduleName))) {
141 return 0;
144 info->dli_fname = (char *)(malloc(strlen(moduleName) + 1));
145 strcpy((char *)info->dli_fname, moduleName);
146 info->dli_fbase = mem_info.BaseAddress;
147 info->dli_sname = nullptr;
148 info->dli_saddr = (void *) addr;
150 return 1;
152 #endif
154 ///////////////////////////////////////////////////////////////////////////////