00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <fcntl.h>
00040
00041 #ifndef LINUX
00042 #include <procfs.h>
00043 #endif
00044
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <sys/socket.h>
00049 #include <sys/errno.h>
00050 #include <unistd.h>
00051 #include <errno.h>
00052 #include <dlfcn.h>
00053 #include <sys/time.h>
00054
00055 #include <netdb.h>
00056 #include <netinet/in.h>
00057 #include <sys/param.h>
00058 #include <time.h>
00059
00060 #include "jni.h"
00061 #include "hprof.h"
00062
00063 #define PATH_SEPARATOR ":"
00064 #define PATH_SEPARATOR_CHAR ':'
00065
00066 int
00067 md_getpid(void)
00068 {
00069 static int pid = -1;
00070
00071 if ( pid >= 0 ) {
00072 return pid;
00073 }
00074 pid = getpid();
00075 return pid;
00076 }
00077
00078 void
00079 md_sleep(unsigned seconds)
00080 {
00081 sleep(seconds);
00082 }
00083
00084 void
00085 md_init(void)
00086 {
00087 #ifdef LINUX
00088
00089 #else
00090 if ( gdata->micro_state_accounting ) {
00091 char proc_ctl_fn[48];
00092 int procfd;
00093
00094
00095 (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
00096 "/proc/%d/ctl", md_getpid());
00097
00098 procfd = open(proc_ctl_fn, O_WRONLY);
00099 if (procfd >= 0) {
00100 long ctl_op[2];
00101
00102 ctl_op[0] = PCSET;
00103 ctl_op[1] = PR_MSACCT;
00104 (void)write(procfd, ctl_op, sizeof(ctl_op));
00105 (void)close(procfd);
00106 }
00107 }
00108 #endif
00109 }
00110
00111 int
00112 md_connect(char *hostname, unsigned short port)
00113 {
00114 struct hostent *hentry;
00115 struct sockaddr_in s;
00116 int fd;
00117
00118
00119 fd = socket(AF_INET, SOCK_STREAM, 0);
00120
00121
00122 if ((hentry = gethostbyname(hostname)) == NULL) {
00123 return -1;
00124 }
00125 (void)memset((char *)&s, 0, sizeof(s));
00126
00127 (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list),
00128 (int)sizeof(s.sin_addr.s_addr));
00129
00130 s.sin_port = htons(port);
00131 s.sin_family = AF_INET;
00132
00133
00134 if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
00135 return 0;
00136 }
00137 return fd;
00138 }
00139
00140 int
00141 md_recv(int f, char *buf, int len, int option)
00142 {
00143 return recv(f, buf, len, option);
00144 }
00145
00146 int
00147 md_shutdown(int filedes, int option)
00148 {
00149 return shutdown(filedes, option);
00150 }
00151
00152 int
00153 md_open(const char *filename)
00154 {
00155 return open(filename, O_RDONLY);
00156 }
00157
00158 int
00159 md_open_binary(const char *filename)
00160 {
00161 return md_open(filename);
00162 }
00163
00164 int
00165 md_creat(const char *filename)
00166 {
00167 return open(filename, O_WRONLY | O_CREAT | O_TRUNC,
00168 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
00169 }
00170
00171 int
00172 md_creat_binary(const char *filename)
00173 {
00174 return md_creat(filename);
00175 }
00176
00177 jlong
00178 md_seek(int filedes, jlong cur)
00179 {
00180 jlong new_pos;
00181
00182 if ( cur == (jlong)-1 ) {
00183 new_pos = lseek(filedes, 0, SEEK_END);
00184 } else {
00185 new_pos = lseek(filedes, cur, SEEK_SET);
00186 }
00187 return new_pos;
00188 }
00189
00190 void
00191 md_close(int filedes)
00192 {
00193 (void)close(filedes);
00194 }
00195
00196 int
00197 md_send(int s, const char *msg, int len, int flags)
00198 {
00199 int res;
00200
00201 do {
00202 res = send(s, msg, len, flags);
00203 } while ((res < 0) && (errno == EINTR));
00204
00205 return res;
00206 }
00207
00208 int
00209 md_write(int filedes, const void *buf, int nbyte)
00210 {
00211 int res;
00212
00213 do {
00214 res = write(filedes, buf, nbyte);
00215 } while ((res < 0) && (errno == EINTR));
00216
00217 return res;
00218 }
00219
00220 int
00221 md_read(int filedes, void *buf, int nbyte)
00222 {
00223 int res;
00224
00225 do {
00226 res = read(filedes, buf, nbyte);
00227 } while ((res < 0) && (errno == EINTR));
00228
00229 return res;
00230 }
00231
00232
00233 static jlong
00234 md_timeofday(void)
00235 {
00236 struct timeval tv;
00237
00238 if ( gettimeofday(&tv, (void *)0) != 0 ) {
00239 return (jlong)0;
00240 }
00241
00242 return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
00243 }
00244
00245
00246 jlong
00247 md_get_microsecs(void)
00248 {
00249 #ifdef LINUX
00250 return (jlong)(md_timeofday() * (jlong)1000);
00251 #else
00252 return (jlong)(gethrtime()/(hrtime_t)1000);
00253 #endif
00254 }
00255
00256
00257 jlong
00258 md_get_timemillis(void)
00259 {
00260 return md_timeofday();
00261 }
00262
00263
00264 jlong
00265 md_get_thread_cpu_timemillis(void)
00266 {
00267 #ifdef LINUX
00268 return md_timeofday();
00269 #else
00270 return (jlong)(gethrvtime()/1000);
00271 #endif
00272 }
00273
00274 void
00275 md_get_prelude_path(char *path, int path_len, char *filename)
00276 {
00277 void *addr;
00278 char libdir[FILENAME_MAX+1];
00279 Dl_info dlinfo;
00280
00281 libdir[0] = 0;
00282 #ifdef LINUX
00283 addr = (void*)&Agent_OnLoad;
00284 #else
00285
00286
00287
00288
00289 addr = dlsym(RTLD_SELF, "Agent_OnLoad");
00290
00291 if ( addr == NULL ) {
00292 addr = (void*)&Agent_OnLoad;
00293 }
00294 #endif
00295
00296
00297
00298
00299 dlinfo.dli_fname = NULL;
00300 (void)dladdr(addr, &dlinfo);
00301 if ( dlinfo.dli_fname != NULL ) {
00302 char * lastSlash;
00303
00304
00305 (void)strcpy(libdir, (char *)dlinfo.dli_fname);
00306 lastSlash = strrchr(libdir, '/');
00307 if ( lastSlash != NULL ) {
00308 *lastSlash = '\0';
00309 }
00310 lastSlash = strrchr(libdir, '/');
00311 if ( lastSlash != NULL ) {
00312 *lastSlash = '\0';
00313 }
00314 }
00315 (void)snprintf(path, path_len, "%s/%s", libdir, filename);
00316 }
00317
00318
00319 int
00320 md_vsnprintf(char *s, int n, const char *format, va_list ap)
00321 {
00322 return vsnprintf(s, n, format, ap);
00323 }
00324
00325 int
00326 md_snprintf(char *s, int n, const char *format, ...)
00327 {
00328 int ret;
00329 va_list ap;
00330
00331 va_start(ap, format);
00332 ret = md_vsnprintf(s, n, format, ap);
00333 va_end(ap);
00334 return ret;
00335 }
00336
00337 void
00338 md_system_error(char *buf, int len)
00339 {
00340 char *p;
00341
00342 buf[0] = 0;
00343 p = strerror(errno);
00344 if ( p != NULL ) {
00345 (void)strcpy(buf, p);
00346 }
00347 }
00348
00349 unsigned
00350 md_htons(unsigned short s)
00351 {
00352 return htons(s);
00353 }
00354
00355 unsigned
00356 md_htonl(unsigned l)
00357 {
00358 return htonl(l);
00359 }
00360
00361 unsigned
00362 md_ntohs(unsigned short s)
00363 {
00364 return ntohs(s);
00365 }
00366
00367 unsigned
00368 md_ntohl(unsigned l)
00369 {
00370 return ntohl(l);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 static char** split_path(const char* path, int* n) {
00382 char* inpath;
00383 char** opath;
00384 char* p;
00385 int count = 1;
00386 int i;
00387
00388 *n = 0;
00389 if (path == NULL || strlen(path) == 0) {
00390 return NULL;
00391 }
00392 inpath = strdup(path);
00393 if (inpath == NULL) {
00394 return NULL;
00395 }
00396 p = strchr(inpath, PATH_SEPARATOR_CHAR);
00397
00398 while (p != NULL) {
00399 count++;
00400 p++;
00401 p = strchr(p, PATH_SEPARATOR_CHAR);
00402 }
00403 opath = (char**) calloc(count, sizeof(char*));
00404 if (opath == NULL) {
00405 return NULL;
00406 }
00407
00408
00409 p = inpath;
00410 for (i = 0 ; i < count ; i++) {
00411 size_t len = strcspn(p, PATH_SEPARATOR);
00412
00413 char* s = (char*)malloc((len + 1)*sizeof(char));
00414 if (s == NULL) {
00415 return NULL;
00416 }
00417 strncpy(s, p, len);
00418 s[len] = '\0';
00419 opath[i] = s;
00420 p += len + 1;
00421 }
00422 free(inpath);
00423 *n = count;
00424 return opath;
00425 }
00426
00427
00428 void
00429 md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
00430 {
00431 int n;
00432 int i;
00433 char** pelements;
00434 struct stat statbuf;
00435 const int pnamelen = pname ? strlen(pname) : 0;
00436
00437
00438 if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
00439 *holder = '\0';
00440 return;
00441 }
00442
00443
00444 if (pnamelen == 0) {
00445 (void)snprintf(holder, holderlen, "lib%s.so", fname);
00446 } else if (strchr(pname, PATH_SEPARATOR_CHAR) != NULL) {
00447 pelements = split_path(pname, &n);
00448 for (i = 0 ; i < n ; i++) {
00449
00450 if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
00451 continue;
00452 }
00453 snprintf(holder, holderlen, "%s/lib%s.so", pelements[i], fname);
00454 if (stat(holder, &statbuf) == 0) {
00455 break;
00456 }
00457 }
00458
00459 for (i = 0 ; i < n ; i++) {
00460 if (pelements[i] != NULL) {
00461 free(pelements[i]);
00462 }
00463 }
00464 if (pelements != NULL) {
00465 free(pelements);
00466 }
00467 } else {
00468 (void)snprintf(holder, holderlen, "%s/lib%s.so", pname, fname);
00469 }
00470 }
00471
00472
00473 void *
00474 md_load_library(const char *name, char *err_buf, int err_buflen)
00475 {
00476 void * result;
00477
00478 result = dlopen(name, RTLD_LAZY);
00479 if (result == NULL) {
00480 (void)strncpy(err_buf, dlerror(), err_buflen-2);
00481 err_buf[err_buflen-1] = '\0';
00482 }
00483 return result;
00484 }
00485
00486
00487 void
00488 md_unload_library(void *handle)
00489 {
00490 (void)dlclose(handle);
00491 }
00492
00493
00494 void *
00495 md_find_library_entry(void *handle, const char *name)
00496 {
00497 void * sym;
00498
00499 sym = dlsym(handle, name);
00500 return sym;
00501 }
00502