Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.cpp @ 1681:126ea7725993
6953477: Increase portability and flexibility of building Hotspot
Summary: A collection of portability improvements including shared code support for PPC, ARM platforms, software floating point, cross compilation support and improvements in error crash detail.
Reviewed-by: phh, never, coleenp, dholmes
author | bobv |
---|---|
date | Tue, 03 Aug 2010 08:13:38 -0400 |
parents | 0e7d2a08b605 |
children | c7004d700b49 |
comparison
equal
deleted
inserted
replaced
1680:a64438a2b7e8 | 1681:126ea7725993 |
---|---|
28 # include "incls/_os_linux.cpp.incl" | 28 # include "incls/_os_linux.cpp.incl" |
29 | 29 |
30 // put OS-includes here | 30 // put OS-includes here |
31 # include <sys/types.h> | 31 # include <sys/types.h> |
32 # include <sys/mman.h> | 32 # include <sys/mman.h> |
33 # include <sys/stat.h> | |
34 # include <sys/select.h> | |
33 # include <pthread.h> | 35 # include <pthread.h> |
34 # include <signal.h> | 36 # include <signal.h> |
35 # include <errno.h> | 37 # include <errno.h> |
36 # include <dlfcn.h> | 38 # include <dlfcn.h> |
37 # include <stdio.h> | 39 # include <stdio.h> |
186 static char cpu_arch[] = "ia64"; | 188 static char cpu_arch[] = "ia64"; |
187 #elif defined(IA32) | 189 #elif defined(IA32) |
188 static char cpu_arch[] = "i386"; | 190 static char cpu_arch[] = "i386"; |
189 #elif defined(AMD64) | 191 #elif defined(AMD64) |
190 static char cpu_arch[] = "amd64"; | 192 static char cpu_arch[] = "amd64"; |
193 #elif defined(ARM) | |
194 static char cpu_arch[] = "arm"; | |
195 #elif defined(PPC) | |
196 static char cpu_arch[] = "ppc"; | |
191 #elif defined(SPARC) | 197 #elif defined(SPARC) |
192 # ifdef _LP64 | 198 # ifdef _LP64 |
193 static char cpu_arch[] = "sparcv9"; | 199 static char cpu_arch[] = "sparcv9"; |
194 # else | 200 # else |
195 static char cpu_arch[] = "sparc"; | 201 static char cpu_arch[] = "sparc"; |
1135 long nice; | 1141 long nice; |
1136 long junk; | 1142 long junk; |
1137 long it_real; | 1143 long it_real; |
1138 uintptr_t start; | 1144 uintptr_t start; |
1139 uintptr_t vsize; | 1145 uintptr_t vsize; |
1140 uintptr_t rss; | 1146 intptr_t rss; |
1141 unsigned long rsslim; | 1147 uintptr_t rsslim; |
1142 uintptr_t scodes; | 1148 uintptr_t scodes; |
1143 uintptr_t ecode; | 1149 uintptr_t ecode; |
1144 int i; | 1150 int i; |
1145 | 1151 |
1146 // Figure what the primordial thread stack base is. Code is inspired | 1152 // Figure what the primordial thread stack base is. Code is inspired |
1166 i = 0; | 1172 i = 0; |
1167 if (s) { | 1173 if (s) { |
1168 // Skip blank chars | 1174 // Skip blank chars |
1169 do s++; while (isspace(*s)); | 1175 do s++; while (isspace(*s)); |
1170 | 1176 |
1171 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ | 1177 #define _UFM UINTX_FORMAT |
1172 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ | 1178 #define _DFM INTX_FORMAT |
1173 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " | 1179 |
1174 UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT | 1180 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ |
1175 " %lu " | 1181 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ |
1176 UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT, | 1182 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM, |
1177 &state, /* 3 %c */ | 1183 &state, /* 3 %c */ |
1178 &ppid, /* 4 %d */ | 1184 &ppid, /* 4 %d */ |
1179 &pgrp, /* 5 %d */ | 1185 &pgrp, /* 5 %d */ |
1180 &session, /* 6 %d */ | 1186 &session, /* 6 %d */ |
1181 &nr, /* 7 %d */ | 1187 &nr, /* 7 %d */ |
1191 &cstime, /* 17 %ld */ | 1197 &cstime, /* 17 %ld */ |
1192 &prio, /* 18 %ld */ | 1198 &prio, /* 18 %ld */ |
1193 &nice, /* 19 %ld */ | 1199 &nice, /* 19 %ld */ |
1194 &junk, /* 20 %ld */ | 1200 &junk, /* 20 %ld */ |
1195 &it_real, /* 21 %ld */ | 1201 &it_real, /* 21 %ld */ |
1196 &start, /* 22 UINTX_FORMAT */ | 1202 &start, /* 22 UINTX_FORMAT */ |
1197 &vsize, /* 23 UINTX_FORMAT */ | 1203 &vsize, /* 23 UINTX_FORMAT */ |
1198 &rss, /* 24 UINTX_FORMAT */ | 1204 &rss, /* 24 INTX_FORMAT */ |
1199 &rsslim, /* 25 %lu */ | 1205 &rsslim, /* 25 UINTX_FORMAT */ |
1200 &scodes, /* 26 UINTX_FORMAT */ | 1206 &scodes, /* 26 UINTX_FORMAT */ |
1201 &ecode, /* 27 UINTX_FORMAT */ | 1207 &ecode, /* 27 UINTX_FORMAT */ |
1202 &stack_start); /* 28 UINTX_FORMAT */ | 1208 &stack_start); /* 28 UINTX_FORMAT */ |
1203 } | 1209 } |
1210 | |
1211 #undef _UFM | |
1212 #undef _DFM | |
1204 | 1213 |
1205 if (i != 28 - 2) { | 1214 if (i != 28 - 2) { |
1206 assert(false, "Bad conversion from /proc/self/stat"); | 1215 assert(false, "Bad conversion from /proc/self/stat"); |
1207 // product mode - assume we are the initial thread, good luck in the | 1216 // product mode - assume we are the initial thread, good luck in the |
1208 // embedded case. | 1217 // embedded case. |
1334 | 1343 |
1335 #ifndef SYS_clock_getres | 1344 #ifndef SYS_clock_getres |
1336 | 1345 |
1337 #if defined(IA32) || defined(AMD64) | 1346 #if defined(IA32) || defined(AMD64) |
1338 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) | 1347 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) |
1348 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) | |
1339 #else | 1349 #else |
1340 #error Value of SYS_clock_getres not known on this platform | 1350 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time" |
1351 #define sys_clock_getres(x,y) -1 | |
1341 #endif | 1352 #endif |
1342 | 1353 |
1354 #else | |
1355 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) | |
1343 #endif | 1356 #endif |
1344 | |
1345 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) | |
1346 | 1357 |
1347 void os::Linux::fast_thread_clock_init() { | 1358 void os::Linux::fast_thread_clock_init() { |
1348 if (!UseLinuxPosixThreadCPUClocks) { | 1359 if (!UseLinuxPosixThreadCPUClocks) { |
1349 return; | 1360 return; |
1350 } | 1361 } |
1903 !_print_ascii_file("/etc/sun-release", st) && | 1914 !_print_ascii_file("/etc/sun-release", st) && |
1904 !_print_ascii_file("/etc/redhat-release", st) && | 1915 !_print_ascii_file("/etc/redhat-release", st) && |
1905 !_print_ascii_file("/etc/SuSE-release", st) && | 1916 !_print_ascii_file("/etc/SuSE-release", st) && |
1906 !_print_ascii_file("/etc/turbolinux-release", st) && | 1917 !_print_ascii_file("/etc/turbolinux-release", st) && |
1907 !_print_ascii_file("/etc/gentoo-release", st) && | 1918 !_print_ascii_file("/etc/gentoo-release", st) && |
1908 !_print_ascii_file("/etc/debian_version", st)) { | 1919 !_print_ascii_file("/etc/debian_version", st) && |
1920 !_print_ascii_file("/etc/ltib-release", st) && | |
1921 !_print_ascii_file("/etc/angstrom-version", st)) { | |
1909 st->print("Linux"); | 1922 st->print("Linux"); |
1910 } | 1923 } |
1911 st->cr(); | 1924 st->cr(); |
1912 | 1925 |
1913 // kernel | 1926 // kernel |
1968 // load average | 1981 // load average |
1969 st->print("load average:"); | 1982 st->print("load average:"); |
1970 double loadavg[3]; | 1983 double loadavg[3]; |
1971 os::loadavg(loadavg, 3); | 1984 os::loadavg(loadavg, 3); |
1972 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); | 1985 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); |
1986 st->cr(); | |
1987 | |
1988 // meminfo | |
1989 st->print("\n/proc/meminfo:\n"); | |
1990 _print_ascii_file("/proc/meminfo", st); | |
1973 st->cr(); | 1991 st->cr(); |
1974 } | 1992 } |
1975 | 1993 |
1976 void os::print_memory_info(outputStream* st) { | 1994 void os::print_memory_info(outputStream* st) { |
1977 | 1995 |
2095 char dli_fname[MAXPATHLEN]; | 2113 char dli_fname[MAXPATHLEN]; |
2096 bool ret = dll_address_to_library_name( | 2114 bool ret = dll_address_to_library_name( |
2097 CAST_FROM_FN_PTR(address, os::jvm_path), | 2115 CAST_FROM_FN_PTR(address, os::jvm_path), |
2098 dli_fname, sizeof(dli_fname), NULL); | 2116 dli_fname, sizeof(dli_fname), NULL); |
2099 assert(ret != 0, "cannot locate libjvm"); | 2117 assert(ret != 0, "cannot locate libjvm"); |
2100 if (realpath(dli_fname, buf) == NULL) | 2118 char *rp = realpath(dli_fname, buf); |
2119 if (rp == NULL) | |
2101 return; | 2120 return; |
2102 | 2121 |
2103 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { | 2122 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { |
2104 // Support for the gamma launcher. Typical value for buf is | 2123 // Support for the gamma launcher. Typical value for buf is |
2105 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at | 2124 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at |
2123 // Check the current module name "libjvm.so" or "libjvm_g.so". | 2142 // Check the current module name "libjvm.so" or "libjvm_g.so". |
2124 p = strrchr(buf, '/'); | 2143 p = strrchr(buf, '/'); |
2125 assert(strstr(p, "/libjvm") == p, "invalid library name"); | 2144 assert(strstr(p, "/libjvm") == p, "invalid library name"); |
2126 p = strstr(p, "_g") ? "_g" : ""; | 2145 p = strstr(p, "_g") ? "_g" : ""; |
2127 | 2146 |
2128 if (realpath(java_home_var, buf) == NULL) | 2147 rp = realpath(java_home_var, buf); |
2148 if (rp == NULL) | |
2129 return; | 2149 return; |
2130 | 2150 |
2131 // determine if this is a legacy image or modules image | 2151 // determine if this is a legacy image or modules image |
2132 // modules image doesn't have "jre" subdirectory | 2152 // modules image doesn't have "jre" subdirectory |
2133 len = strlen(buf); | 2153 len = strlen(buf); |
2145 // "libhpi[_g].so" in hpi::initialize_get_interface(). | 2165 // "libhpi[_g].so" in hpi::initialize_get_interface(). |
2146 len = strlen(buf); | 2166 len = strlen(buf); |
2147 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); | 2167 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); |
2148 } else { | 2168 } else { |
2149 // Go back to path of .so | 2169 // Go back to path of .so |
2150 if (realpath(dli_fname, buf) == NULL) | 2170 rp = realpath(dli_fname, buf); |
2171 if (rp == NULL) | |
2151 return; | 2172 return; |
2152 } | 2173 } |
2153 } | 2174 } |
2154 } | 2175 } |
2155 } | 2176 } |
2506 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; | 2527 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; |
2507 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; | 2528 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; |
2508 unsigned long* os::Linux::_numa_all_nodes; | 2529 unsigned long* os::Linux::_numa_all_nodes; |
2509 | 2530 |
2510 bool os::uncommit_memory(char* addr, size_t size) { | 2531 bool os::uncommit_memory(char* addr, size_t size) { |
2511 return ::mmap(addr, size, PROT_NONE, | 2532 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, |
2512 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) | 2533 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); |
2513 != MAP_FAILED; | 2534 return res != (uintptr_t) MAP_FAILED; |
2514 } | 2535 } |
2515 | 2536 |
2516 // Linux uses a growable mapping for the stack, and if the mapping for | 2537 // Linux uses a growable mapping for the stack, and if the mapping for |
2517 // the stack guard pages is not removed when we detach a thread the | 2538 // the stack guard pages is not removed when we detach a thread the |
2518 // stack cannot grow beyond the pages where the stack guard was | 2539 // stack cannot grow beyond the pages where the stack guard was |
2716 // If we can't determine the value (e.g. /proc is not mounted, or the text | 2737 // If we can't determine the value (e.g. /proc is not mounted, or the text |
2717 // format has been changed), we'll use the largest page size supported by | 2738 // format has been changed), we'll use the largest page size supported by |
2718 // the processor. | 2739 // the processor. |
2719 | 2740 |
2720 #ifndef ZERO | 2741 #ifndef ZERO |
2721 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M); | 2742 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M) |
2743 ARM_ONLY(2 * M) PPC_ONLY(4 * M); | |
2722 #endif // ZERO | 2744 #endif // ZERO |
2723 | 2745 |
2724 FILE *fp = fopen("/proc/meminfo", "r"); | 2746 FILE *fp = fopen("/proc/meminfo", "r"); |
2725 if (fp) { | 2747 if (fp) { |
2726 while (!feof(fp)) { | 2748 while (!feof(fp)) { |
3979 prio_init(); | 4001 prio_init(); |
3980 | 4002 |
3981 return JNI_OK; | 4003 return JNI_OK; |
3982 } | 4004 } |
3983 | 4005 |
4006 // this is called at the end of vm_initialization | |
4007 void os::init_3(void) { } | |
4008 | |
3984 // Mark the polling page as unreadable | 4009 // Mark the polling page as unreadable |
3985 void os::make_polling_page_unreadable(void) { | 4010 void os::make_polling_page_unreadable(void) { |
3986 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) | 4011 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) |
3987 fatal("Could not disable polling page"); | 4012 fatal("Could not disable polling page"); |
3988 }; | 4013 }; |
4059 } | 4084 } |
4060 | 4085 |
4061 //////////////////////////////////////////////////////////////////////////////// | 4086 //////////////////////////////////////////////////////////////////////////////// |
4062 // debug support | 4087 // debug support |
4063 | 4088 |
4064 #ifndef PRODUCT | |
4065 static address same_page(address x, address y) { | 4089 static address same_page(address x, address y) { |
4066 int page_bits = -os::vm_page_size(); | 4090 int page_bits = -os::vm_page_size(); |
4067 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) | 4091 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) |
4068 return x; | 4092 return x; |
4069 else if (x > y) | 4093 else if (x > y) |
4070 return (address)(intptr_t(y) | ~page_bits) + 1; | 4094 return (address)(intptr_t(y) | ~page_bits) + 1; |
4071 else | 4095 else |
4072 return (address)(intptr_t(y) & page_bits); | 4096 return (address)(intptr_t(y) & page_bits); |
4073 } | 4097 } |
4074 | 4098 |
4075 bool os::find(address addr) { | 4099 bool os::find(address addr, outputStream* st) { |
4076 Dl_info dlinfo; | 4100 Dl_info dlinfo; |
4077 memset(&dlinfo, 0, sizeof(dlinfo)); | 4101 memset(&dlinfo, 0, sizeof(dlinfo)); |
4078 if (dladdr(addr, &dlinfo)) { | 4102 if (dladdr(addr, &dlinfo)) { |
4079 tty->print(PTR_FORMAT ": ", addr); | 4103 st->print(PTR_FORMAT ": ", addr); |
4080 if (dlinfo.dli_sname != NULL) { | 4104 if (dlinfo.dli_sname != NULL) { |
4081 tty->print("%s+%#x", dlinfo.dli_sname, | 4105 st->print("%s+%#x", dlinfo.dli_sname, |
4082 addr - (intptr_t)dlinfo.dli_saddr); | 4106 addr - (intptr_t)dlinfo.dli_saddr); |
4083 } else if (dlinfo.dli_fname) { | 4107 } else if (dlinfo.dli_fname) { |
4084 tty->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); | 4108 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); |
4085 } else { | 4109 } else { |
4086 tty->print("<absolute address>"); | 4110 st->print("<absolute address>"); |
4087 } | 4111 } |
4088 if (dlinfo.dli_fname) { | 4112 if (dlinfo.dli_fname) { |
4089 tty->print(" in %s", dlinfo.dli_fname); | 4113 st->print(" in %s", dlinfo.dli_fname); |
4090 } | 4114 } |
4091 if (dlinfo.dli_fbase) { | 4115 if (dlinfo.dli_fbase) { |
4092 tty->print(" at " PTR_FORMAT, dlinfo.dli_fbase); | 4116 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); |
4093 } | 4117 } |
4094 tty->cr(); | 4118 st->cr(); |
4095 | 4119 |
4096 if (Verbose) { | 4120 if (Verbose) { |
4097 // decode some bytes around the PC | 4121 // decode some bytes around the PC |
4098 address begin = same_page(addr-40, addr); | 4122 address begin = same_page(addr-40, addr); |
4099 address end = same_page(addr+40, addr); | 4123 address end = same_page(addr+40, addr); |
4102 if (begin < lowest) begin = lowest; | 4126 if (begin < lowest) begin = lowest; |
4103 Dl_info dlinfo2; | 4127 Dl_info dlinfo2; |
4104 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr | 4128 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr |
4105 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) | 4129 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) |
4106 end = (address) dlinfo2.dli_saddr; | 4130 end = (address) dlinfo2.dli_saddr; |
4107 Disassembler::decode(begin, end); | 4131 Disassembler::decode(begin, end, st); |
4108 } | 4132 } |
4109 return true; | 4133 return true; |
4110 } | 4134 } |
4111 return false; | 4135 return false; |
4112 } | 4136 } |
4113 | |
4114 #endif | |
4115 | 4137 |
4116 //////////////////////////////////////////////////////////////////////////////// | 4138 //////////////////////////////////////////////////////////////////////////////// |
4117 // misc | 4139 // misc |
4118 | 4140 |
4119 // This does not do anything on Linux. This is basically a hook for being | 4141 // This does not do anything on Linux. This is basically a hook for being |
4319 int statlen; | 4341 int statlen; |
4320 char proc_name[64]; | 4342 char proc_name[64]; |
4321 int count; | 4343 int count; |
4322 long sys_time, user_time; | 4344 long sys_time, user_time; |
4323 char string[64]; | 4345 char string[64]; |
4346 char cdummy; | |
4324 int idummy; | 4347 int idummy; |
4325 long ldummy; | 4348 long ldummy; |
4326 FILE *fp; | 4349 FILE *fp; |
4327 | 4350 |
4328 // We first try accessing /proc/<pid>/cpu since this is faster to | 4351 // We first try accessing /proc/<pid>/cpu since this is faster to |
4379 if (s == NULL ) return -1; | 4402 if (s == NULL ) return -1; |
4380 | 4403 |
4381 // Skip blank chars | 4404 // Skip blank chars |
4382 do s++; while (isspace(*s)); | 4405 do s++; while (isspace(*s)); |
4383 | 4406 |
4384 count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", | 4407 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", |
4385 &idummy, &idummy, &idummy, &idummy, &idummy, | 4408 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy, |
4386 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, | 4409 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, |
4387 &user_time, &sys_time); | 4410 &user_time, &sys_time); |
4388 if ( count != 12 ) return -1; | 4411 if ( count != 13 ) return -1; |
4389 if (user_sys_cpu_time) { | 4412 if (user_sys_cpu_time) { |
4390 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); | 4413 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); |
4391 } else { | 4414 } else { |
4392 return (jlong)user_time * (1000000000 / clock_tics_per_sec); | 4415 return (jlong)user_time * (1000000000 / clock_tics_per_sec); |
4393 } | 4416 } |
4978 // Unknown exit code; pass it through | 5001 // Unknown exit code; pass it through |
4979 return status; | 5002 return status; |
4980 } | 5003 } |
4981 } | 5004 } |
4982 } | 5005 } |
5006 | |
5007 // is_headless_jre() | |
5008 // | |
5009 // Test for the existence of libmawt in motif21 or xawt directories | |
5010 // in order to report if we are running in a headless jre | |
5011 // | |
5012 bool os::is_headless_jre() { | |
5013 struct stat statbuf; | |
5014 char buf[MAXPATHLEN]; | |
5015 char libmawtpath[MAXPATHLEN]; | |
5016 const char *xawtstr = "/xawt/libmawt.so"; | |
5017 const char *motifstr = "/motif21/libmawt.so"; | |
5018 char *p; | |
5019 | |
5020 // Get path to libjvm.so | |
5021 os::jvm_path(buf, sizeof(buf)); | |
5022 | |
5023 // Get rid of libjvm.so | |
5024 p = strrchr(buf, '/'); | |
5025 if (p == NULL) return false; | |
5026 else *p = '\0'; | |
5027 | |
5028 // Get rid of client or server | |
5029 p = strrchr(buf, '/'); | |
5030 if (p == NULL) return false; | |
5031 else *p = '\0'; | |
5032 | |
5033 // check xawt/libmawt.so | |
5034 strcpy(libmawtpath, buf); | |
5035 strcat(libmawtpath, xawtstr); | |
5036 if (::stat(libmawtpath, &statbuf) == 0) return false; | |
5037 | |
5038 // check motif21/libmawt.so | |
5039 strcpy(libmawtpath, buf); | |
5040 strcat(libmawtpath, motifstr); | |
5041 if (::stat(libmawtpath, &statbuf) == 0) return false; | |
5042 | |
5043 return true; | |
5044 } | |
5045 |