< prev index next >
src/hotspot/share/runtime/os.cpp
Print this page
*** 277,286 ****
--- 277,299 ----
return os::stat(buffer, &statbuf) == 0;
}
return false;
}
+ // Frees all memory allocated on the heap for the
+ // supplied array of arrays of chars (a), where n
+ // is the number of elements in the array.
+ static void free_array_of_char_arrays(char** a, size_t n) {
+ while (n > 0) {
+ n--;
+ if (a[n] != NULL) {
+ FREE_C_HEAP_ARRAY(char, a[n]);
+ }
+ }
+ FREE_C_HEAP_ARRAY(char*, a);
+ }
+
bool os::dll_locate_lib(char *buffer, size_t buflen,
const char* pname, const char* fname) {
bool retval = false;
size_t fullfnamelen = strlen(JNI_LIB_PREFIX) + strlen(fname) + strlen(JNI_LIB_SUFFIX);
*** 297,310 ****
retval = conc_path_file_and_check(buffer, &buffer[plen], buflen - plen,
"", lastchar, fullfname);
}
} else if (strchr(pname, *os::path_separator()) != NULL) {
// A list of paths. Search for the path that contains the library.
! int n;
! char** pelements = split_path(pname, &n);
if (pelements != NULL) {
! for (int i = 0; i < n; i++) {
char* path = pelements[i];
// Really shouldn't be NULL, but check can't hurt.
size_t plen = (path == NULL) ? 0 : strlen(path);
if (plen == 0) {
continue; // Skip the empty path values.
--- 310,323 ----
retval = conc_path_file_and_check(buffer, &buffer[plen], buflen - plen,
"", lastchar, fullfname);
}
} else if (strchr(pname, *os::path_separator()) != NULL) {
// A list of paths. Search for the path that contains the library.
! size_t n;
! char** pelements = split_path(pname, &n, fullfnamelen);
if (pelements != NULL) {
! for (size_t i = 0; i < n; i++) {
char* path = pelements[i];
// Really shouldn't be NULL, but check can't hurt.
size_t plen = (path == NULL) ? 0 : strlen(path);
if (plen == 0) {
continue; // Skip the empty path values.
*** 312,327 ****
const char lastchar = path[plen - 1];
retval = conc_path_file_and_check(buffer, buffer, buflen, path, lastchar, fullfname);
if (retval) break;
}
// Release the storage allocated by split_path.
! for (int i = 0; i < n; i++) {
! if (pelements[i] != NULL) {
! FREE_C_HEAP_ARRAY(char, pelements[i]);
! }
! }
! FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
// A definite path.
const char lastchar = pname[pnamelen-1];
retval = conc_path_file_and_check(buffer, buffer, buflen, pname, lastchar, fullfname);
--- 325,335 ----
const char lastchar = path[plen - 1];
retval = conc_path_file_and_check(buffer, buffer, buflen, path, lastchar, fullfname);
if (retval) break;
}
// Release the storage allocated by split_path.
! free_array_of_char_arrays(pelements, n);
}
} else {
// A definite path.
const char lastchar = pname[pnamelen-1];
retval = conc_path_file_and_check(buffer, buffer, buflen, pname, lastchar, fullfname);
*** 1310,1370 ****
FREE_C_HEAP_ARRAY(char, base_classes);
return false;
}
! /*
! * Splits a path, based on its separator, the number of
! * elements is returned back in n.
! * It is the callers responsibility to:
! * a> check the value of n, and n may be 0.
! * b> ignore any empty path elements
! * c> free up the data.
! */
! char** os::split_path(const char* path, int* n) {
! *n = 0;
! if (path == NULL || strlen(path) == 0) {
return NULL;
}
const char psepchar = *os::path_separator();
char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal);
if (inpath == NULL) {
return NULL;
}
strcpy(inpath, path);
! int count = 1;
char* p = strchr(inpath, psepchar);
// Get a count of elements to allocate memory
while (p != NULL) {
count++;
p++;
p = strchr(p, psepchar);
}
char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
- if (opath == NULL) {
- return NULL;
- }
// do the actual splitting
p = inpath;
! for (int i = 0 ; i < count ; i++) {
size_t len = strcspn(p, os::path_separator());
! if (len > JVM_MAXPATHLEN) {
! return NULL;
}
// allocate the string and add terminator storage
! char* s = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
if (s == NULL) {
return NULL;
}
strncpy(s, p, len);
s[len] = '\0';
opath[i] = s;
p += len + 1;
}
FREE_C_HEAP_ARRAY(char, inpath);
! *n = count;
return opath;
}
// Returns true if the current stack pointer is above the stack shadow
// pages, false otherwise.
--- 1318,1386 ----
FREE_C_HEAP_ARRAY(char, base_classes);
return false;
}
! // Splits a path, based on its separator, the number of
! // elements is returned back in "elements".
! // file_name_length is used as a modifier for each path's
! // length when compared to JVM_MAXPATHLEN. So if you know
! // each returned path will have something appended when
! // in use, you can pass the length of that in
! // file_name_length, to ensure we detect if any path
! // exceeds the maximum path length once prepended onto
! // the sub-path/file name.
! // It is the callers responsibility to:
! // a> check the value of "elements", which may be 0.
! // b> ignore any empty path elements
! // c> free up the data.
! char** os::split_path(const char* path, size_t* elements, size_t file_name_length) {
! *elements = (size_t)0;
! if (path == NULL || strlen(path) == 0 || file_name_length == (size_t)NULL) {
return NULL;
}
const char psepchar = *os::path_separator();
char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal);
if (inpath == NULL) {
return NULL;
}
strcpy(inpath, path);
! size_t count = 1;
char* p = strchr(inpath, psepchar);
// Get a count of elements to allocate memory
while (p != NULL) {
count++;
p++;
p = strchr(p, psepchar);
}
char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
// do the actual splitting
p = inpath;
! for (size_t i = 0 ; i < count ; i++) {
size_t len = strcspn(p, os::path_separator());
! if (len + file_name_length > JVM_MAXPATHLEN) {
! // release allocated storage before exiting the vm
! free_array_of_char_arrays(opath, i++);
! vm_exit_during_initialization("The VM tried to use a path that exceeds the maximum path length for "
! "this system. Review path-containing parameters and properties, such as "
! "sun.boot.library.path, to identify potential sources for this path.");
}
// allocate the string and add terminator storage
! char* s = (char*)NEW_C_HEAP_ARRAY_RETURN_NULL(char, len + 1, mtInternal);
if (s == NULL) {
+ // release allocated storage before returning null
+ free_array_of_char_arrays(opath, i++);
return NULL;
}
strncpy(s, p, len);
s[len] = '\0';
opath[i] = s;
p += len + 1;
}
FREE_C_HEAP_ARRAY(char, inpath);
! *elements = count;
return opath;
}
// Returns true if the current stack pointer is above the stack shadow
// pages, false otherwise.
< prev index next >