1 /* 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 // To ensure winsock2.h is used, it has to be included ahead of 33 // windows.h, which includes winsock.h by default. 34 #include <winsock2.h> 35 #include <windows.h> 36 #include <io.h> 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #include <mmsystem.h> 40 #include <fcntl.h> 41 #include <process.h> 42 43 #include "jni.h" 44 #include "hprof.h" 45 46 int 47 md_getpid(void) 48 { 49 static int pid = -1; 50 51 if ( pid >= 0 ) { 52 return pid; 53 } 54 pid = getpid(); 55 return pid; 56 } 57 58 void 59 md_sleep(unsigned seconds) 60 { 61 Sleep((DWORD)seconds*1000); 62 } 63 64 void 65 md_init(void) 66 { 67 } 68 69 int 70 md_connect(char *hostname, unsigned short port) 71 { 72 struct hostent *hentry; 73 struct sockaddr_in s; 74 int fd; 75 76 /* create a socket */ 77 fd = (int)socket(AF_INET, SOCK_STREAM, 0); 78 79 /* find remote host's addr from name */ 80 if ((hentry = gethostbyname(hostname)) == NULL) { 81 return -1; 82 } 83 (void)memset((char *)&s, 0, sizeof(s)); 84 /* set remote host's addr; its already in network byte order */ 85 (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list), 86 (int)sizeof(s.sin_addr.s_addr)); 87 /* set remote host's port */ 88 s.sin_port = htons(port); 89 s.sin_family = AF_INET; 90 91 /* now try connecting */ 92 if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) { 93 return 0; 94 } 95 return fd; 96 } 97 98 int 99 md_recv(int f, char *buf, int len, int option) 100 { 101 return recv(f, buf, len, option); 102 } 103 104 int 105 md_shutdown(int filedes, int option) 106 { 107 return shutdown(filedes, option); 108 } 109 110 int 111 md_open(const char *filename) 112 { 113 return open(filename, O_RDONLY); 114 } 115 116 int 117 md_open_binary(const char *filename) 118 { 119 return open(filename, O_RDONLY|O_BINARY); 120 } 121 122 int 123 md_creat(const char *filename) 124 { 125 return open(filename, O_CREAT | O_WRONLY | O_TRUNC, 126 _S_IREAD | _S_IWRITE); 127 } 128 129 int 130 md_creat_binary(const char *filename) 131 { 132 return open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 133 _S_IREAD | _S_IWRITE); 134 } 135 136 jlong 137 md_seek(int filedes, jlong pos) 138 { 139 jlong new_pos; 140 141 if ( pos == (jlong)-1 ) { 142 new_pos = _lseeki64(filedes, 0L, SEEK_END); 143 } else { 144 new_pos = _lseeki64(filedes, pos, SEEK_SET); 145 } 146 return new_pos; 147 } 148 149 void 150 md_close(int filedes) 151 { 152 (void)closesocket(filedes); 153 } 154 155 int 156 md_send(int s, const char *msg, int len, int flags) 157 { 158 return send(s, msg, len, flags); 159 } 160 161 int 162 md_read(int filedes, void *buf, int nbyte) 163 { 164 return read(filedes, buf, nbyte); 165 } 166 167 int 168 md_write(int filedes, const void *buf, int nbyte) 169 { 170 return write(filedes, buf, nbyte); 171 } 172 173 jlong 174 md_get_microsecs(void) 175 { 176 return (jlong)(timeGetTime())*(jlong)1000; 177 } 178 179 #define FT2JLONG(ft) \ 180 ((jlong)(ft).dwHighDateTime << 32 | (jlong)(ft).dwLowDateTime) 181 182 jlong 183 md_get_timemillis(void) 184 { 185 static jlong fileTime_1_1_70 = 0; 186 SYSTEMTIME st0; 187 FILETIME ft0; 188 189 if (fileTime_1_1_70 == 0) { 190 /* Initialize fileTime_1_1_70 -- the Win32 file time of midnight 191 * 1/1/70. 192 */ 193 194 memset(&st0, 0, sizeof(st0)); 195 st0.wYear = 1970; 196 st0.wMonth = 1; 197 st0.wDay = 1; 198 SystemTimeToFileTime(&st0, &ft0); 199 fileTime_1_1_70 = FT2JLONG(ft0); 200 } 201 202 GetSystemTime(&st0); 203 SystemTimeToFileTime(&st0, &ft0); 204 205 return (FT2JLONG(ft0) - fileTime_1_1_70) / 10000; 206 } 207 208 jlong 209 md_get_thread_cpu_timemillis(void) 210 { 211 return md_get_timemillis(); 212 } 213 214 HINSTANCE hJavaInst; 215 static int nError = 0; 216 217 BOOL WINAPI 218 DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) 219 { 220 WSADATA wsaData; 221 switch (reason) { 222 case DLL_PROCESS_ATTACH: 223 hJavaInst = hinst; 224 nError = WSAStartup(MAKEWORD(2,0), &wsaData); 225 break; 226 case DLL_PROCESS_DETACH: 227 WSACleanup(); 228 hJavaInst = NULL; 229 default: 230 break; 231 } 232 return TRUE; 233 } 234 235 void 236 md_get_prelude_path(char *path, int path_len, char *filename) 237 { 238 char libdir[FILENAME_MAX+1]; 239 char *lastSlash; 240 241 GetModuleFileName(hJavaInst, libdir, FILENAME_MAX); 242 243 /* This is actually in the bin directory, so move above bin for lib */ 244 lastSlash = strrchr(libdir, '\\'); 245 if ( lastSlash != NULL ) { 246 *lastSlash = '\0'; 247 } 248 lastSlash = strrchr(libdir, '\\'); 249 if ( lastSlash != NULL ) { 250 *lastSlash = '\0'; 251 } 252 (void)md_snprintf(path, path_len, "%s\\lib\\%s", libdir, filename); 253 } 254 255 int 256 md_vsnprintf(char *s, int n, const char *format, va_list ap) 257 { 258 return _vsnprintf(s, n, format, ap); 259 } 260 261 int 262 md_snprintf(char *s, int n, const char *format, ...) 263 { 264 int ret; 265 va_list ap; 266 267 va_start(ap, format); 268 ret = md_vsnprintf(s, n, format, ap); 269 va_end(ap); 270 return ret; 271 } 272 273 void 274 md_system_error(char *buf, int len) 275 { 276 long errval; 277 278 errval = GetLastError(); 279 buf[0] = '\0'; 280 if (errval != 0) { 281 int n; 282 283 n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 284 NULL, errval, 285 0, buf, len, NULL); 286 if (n > 3) { 287 /* Drop final '.', CR, LF */ 288 if (buf[n - 1] == '\n') n--; 289 if (buf[n - 1] == '\r') n--; 290 if (buf[n - 1] == '.') n--; 291 buf[n] = '\0'; 292 } 293 } 294 } 295 296 unsigned 297 md_htons(unsigned short s) 298 { 299 return htons(s); 300 } 301 302 unsigned 303 md_htonl(unsigned l) 304 { 305 return htonl(l); 306 } 307 308 unsigned 309 md_ntohs(unsigned short s) 310 { 311 return ntohs(s); 312 } 313 314 unsigned 315 md_ntohl(unsigned l) 316 { 317 return ntohl(l); 318 } 319 320 static int 321 get_last_error_string(char *buf, int len) 322 { 323 long errval; 324 325 errval = GetLastError(); 326 if (errval != 0) { 327 /* DOS error */ 328 int n; 329 330 n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 331 NULL, errval, 332 0, buf, len, NULL); 333 if (n > 3) { 334 /* Drop final '.', CR, LF */ 335 if (buf[n - 1] == '\n') n--; 336 if (buf[n - 1] == '\r') n--; 337 if (buf[n - 1] == '.') n--; 338 buf[n] = '\0'; 339 } 340 return n; 341 } 342 343 if (errno != 0) { 344 /* C runtime error that has no corresponding DOS error code */ 345 const char *s; 346 int n; 347 348 s = strerror(errno); 349 n = (int)strlen(s); 350 if (n >= len) { 351 n = len - 1; 352 } 353 (void)strncpy(buf, s, n); 354 buf[n] = '\0'; 355 return n; 356 } 357 358 return 0; 359 } 360 361 /* Build a machine dependent library name out of a path and file name. */ 362 void 363 md_build_library_name(char *holder, int holderlen, char *pname, char *fname) 364 { 365 int pnamelen; 366 char c; 367 368 pnamelen = pname ? (int)strlen(pname) : 0; 369 c = (pnamelen > 0) ? pname[pnamelen-1] : 0; 370 371 /* Quietly truncates on buffer overflow. Should be an error. */ 372 if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) { 373 *holder = '\0'; 374 return; 375 } 376 377 if (pnamelen == 0) { 378 sprintf(holder, "%s.dll", fname); 379 } else if (c == ':' || c == '\\') { 380 sprintf(holder, "%s%s.dll", pname, fname); 381 } else { 382 sprintf(holder, "%s\\%s.dll", pname, fname); 383 } 384 } 385 386 void * 387 md_load_library(const char * name, char *err_buf, int err_buflen) 388 { 389 void *result; 390 391 result = LoadLibrary(name); 392 if (result == NULL) { 393 /* Error message is pretty lame, try to make a better guess. */ 394 long errcode; 395 396 errcode = GetLastError(); 397 if (errcode == ERROR_MOD_NOT_FOUND) { 398 strncpy(err_buf, "Can't find dependent libraries", err_buflen-2); 399 err_buf[err_buflen-1] = '\0'; 400 } else { 401 get_last_error_string(err_buf, err_buflen); 402 } 403 } 404 return result; 405 } 406 407 void 408 md_unload_library(void *handle) 409 { 410 FreeLibrary(handle); 411 } 412 413 void * 414 md_find_library_entry(void *handle, const char *name) 415 { 416 return GetProcAddress(handle, name); 417 }