diff --git a/src/server/auditserver/ldcs_audit_server_filemngt.c b/src/server/auditserver/ldcs_audit_server_filemngt.c index db2d163b..dc482a31 100644 --- a/src/server/auditserver/ldcs_audit_server_filemngt.c +++ b/src/server/auditserver/ldcs_audit_server_filemngt.c @@ -50,6 +50,7 @@ char *_ldcs_audit_server_cachepath; static char *normalized_tmpdir; static char *_ldcs_audit_server_commpath; extern int spindle_mkdir(char *path); +extern int spindle_mkdir_in_cache(char *path, char *cachepath); static char *filemngt_normalize_dir(char *dir) { char *newpath = realpath(dir, NULL); @@ -95,6 +96,32 @@ int ldcs_is_a_localfile(ldcs_process_data_t *procdata, char *filename) { #define MAX_FILENAME_LEN 256 +void filemngt_calc_dirname(const char *global_name, char *local_name_result, size_t local_name_result_size) +{ + char *lastslash, *endslash; + int starts_with_slash, endslash_position; + + lastslash = strrchr(_ldcs_audit_server_cachepath, '/'); + if (lastslash && lastslash[1] == '\0') + endslash = ""; + else + endslash = "/"; + + starts_with_slash = (global_name[0] == '/') ? 1 : 0; + + snprintf(local_name_result, local_name_result_size, "%s%s%s", _ldcs_audit_server_cachepath, endslash, global_name+starts_with_slash); + + //Take out any trailing slashes + endslash = strrchr(local_name_result, '/'); + endslash_position = endslash ? (int) (endslash - local_name_result) : 0; + if (endslash_position+1 >= local_name_result_size || endslash[1] == '\0') { + while (*endslash == '/' && endslash != local_name_result) { + *endslash = '\0'; + endslash--; + } + } +} + char *filemngt_calc_localname(char *global_name, calc_local_t reqtype) { //The naming decisions here need to be cordinated with name parsing in @@ -103,16 +130,11 @@ char *filemngt_calc_localname(char *global_name, calc_local_t reqtype) char target[MAX_PATH_LEN+1]; char dirpart[MAX_PATH_LEN+1]; char filepart[MAX_PATH_LEN+1]; - char *endslash, *lastslash; const char *prefix = NULL; + char *lastslash; size_t dirpart_size, filepart_size; - int cut_dirpart_slash; - - lastslash = strrchr(_ldcs_audit_server_cachepath, '/'); - if (lastslash && lastslash[1] == '\0') - endslash = ""; - else - endslash = "/"; + ssize_t bytes_left; + int result, error; GCC7_DISABLE_WARNING("-Wformat-truncation"); @@ -154,12 +176,20 @@ char *filemngt_calc_localname(char *global_name, calc_local_t reqtype) strncpy(filepart, target, sizeof(filepart)); filepart[sizeof(filepart)-1] = '\0'; - cut_dirpart_slash = (dirpart[0] == '/') ? 1 : 0; - - snprintf(target, sizeof(target), "%s%s%s", _ldcs_audit_server_cachepath, endslash, dirpart+cut_dirpart_slash); - spindle_mkdir(target); + filemngt_calc_dirname(dirpart, target, sizeof(target)); + debug_printf3("Calling spindle_mkdir(%s, %s)\n", target, _ldcs_audit_server_cachepath); + result = spindle_mkdir_in_cache(target, _ldcs_audit_server_cachepath); + if (result == -1) { + error = errno; + err_printf("spindle_mkdir_in_cache(%s, %s) failed with error %s\n", target, _ldcs_audit_server_cachepath, strerror(error)); + return NULL; + } + debug_printf3("Calculated local directory name for %s as %s and made directory\n", global_name, target); - snprintf(target, sizeof(target), "%s%s%s/%s", _ldcs_audit_server_cachepath, endslash, dirpart+cut_dirpart_slash, filepart); + bytes_left = sizeof(target) - strlen(target); + strncat(target, "/", --bytes_left); + strncat(target, filepart, bytes_left - strlen(filepart)); + target[sizeof(target)-1] = '\0'; GCC7_ENABLE_WARNING; diff --git a/src/server/auditserver/ldcs_audit_server_filemngt.h b/src/server/auditserver/ldcs_audit_server_filemngt.h index 592b9c82..4336f7c0 100644 --- a/src/server/auditserver/ldcs_audit_server_filemngt.h +++ b/src/server/auditserver/ldcs_audit_server_filemngt.h @@ -51,7 +51,8 @@ typedef struct size_t extended_stat_size(extended_stat_t *st); char *filemngt_calc_localname(char *global_name, calc_local_t reqtype); - +void filemngt_calc_dirname(const char *global_name, char *local_name_result, size_t local_name_result_size); + int ldcs_audit_server_filemngt_clean(); int filemngt_create_file_space(char *filename, size_t size, void **buffer_out, int *fd_out); diff --git a/src/server/auditserver/ldcs_audit_server_handlers.c b/src/server/auditserver/ldcs_audit_server_handlers.c index c7e73e6b..47e1e8d7 100644 --- a/src/server/auditserver/ldcs_audit_server_handlers.c +++ b/src/server/auditserver/ldcs_audit_server_handlers.c @@ -141,6 +141,7 @@ static int handle_send_file_query(ldcs_process_data_t *procdata, char *fullpath, static int handle_file_recv(ldcs_process_data_t *procdata, ldcs_message_t *msg, node_peer_t peer, broadcast_t bcast); static int handle_directory_recv(ldcs_process_data_t *procdata, ldcs_message_t *msg, broadcast_t bcast); +static int handle_process_directory(ldcs_process_data_t *procdata, const char *dirname); static int handle_alias_recv(ldcs_process_data_t *procdata, ldcs_message_t *msg, broadcast_t bcast); static int handle_exit_broadcast(ldcs_process_data_t *procdata); @@ -631,8 +632,11 @@ static int handle_read_directory(ldcs_process_data_t *procdata, char *dir) procdata->server_stat.procdir.bytes += rc; procdata->server_stat.procdir.time += (ldcs_get_time() - starttime); - if (cache_dir_result == LDCS_CACHE_DIR_PARSED_AND_EXISTS || - cache_dir_result == LDCS_CACHE_DIR_PARSED_AND_NOT_EXISTS) { + if (cache_dir_result == LDCS_CACHE_DIR_PARSED_AND_EXISTS) { + handle_process_directory(procdata, dir); + return 0; + } + if (cache_dir_result == LDCS_CACHE_DIR_PARSED_AND_NOT_EXISTS) { return 0; } else { @@ -1665,6 +1669,21 @@ static int handle_file_recv(ldcs_process_data_t *procdata, ldcs_message_t *msg, return global_error; } +/** + * We're processing a directory that exists, either from reading it or recv'ing it on the + * network. + **/ +extern int spindle_mkdir_in_cache(char *orig_path, char *cachepath); +static int handle_process_directory(ldcs_process_data_t *procdata, const char *dirname) +{ + char local_dirname[MAX_PATH_LEN+1]; + + debug_printf2("Creating directory %s in cache\n", dirname); + filemngt_calc_dirname(dirname, local_dirname, sizeof(local_dirname)); + spindle_mkdir_in_cache(local_dirname, procdata->cachepath); + return 0; +} + /** * We've received a packet with directory info. Process it. **/ @@ -1672,11 +1691,16 @@ static int handle_directory_recv(ldcs_process_data_t *procdata, ldcs_message_t * { double starttime = ldcs_get_time(); char dirname[MAX_PATH_LEN+1]; + int num_entries_in_dir; debug_printf2("New directory cache entries received from %s\n", bcast == preload_broadcast ? "preload" : "request"); - ldcs_cache_decodeDirContents(msg->data, msg->header.len, dirname, MAX_PATH_LEN); + num_entries_in_dir = ldcs_cache_decodeDirContents(msg->data, msg->header.len, dirname, MAX_PATH_LEN); + debug_printf2("Directory %s has %d entries\n", dirname, num_entries_in_dir); + if (num_entries_in_dir) { + handle_process_directory(procdata, dirname); + } handle_broadcast_dir(procdata, dirname, bcast); diff --git a/src/server/cache/ldcs_cache.cc b/src/server/cache/ldcs_cache.cc index 2930d888..5a6f78ac 100644 --- a/src/server/cache/ldcs_cache.cc +++ b/src/server/cache/ldcs_cache.cc @@ -445,6 +445,7 @@ int ldcs_cache_decodeDirContents(char *buffer, size_t len, while (pos < len) { int fn_length; string filename; + num_entries++; memcpy(&fn_length, buffer + pos, sizeof(int)); assert(fn_length <= MAX_PATH_LEN+1); pos += sizeof(int); @@ -459,14 +460,13 @@ int ldcs_cache_decodeDirContents(char *buffer, size_t len, assert(pos <= len); addFile(dirname, filename); - num_entries++; } strncpy(dirbuffer, dirname.c_str(), dirbuffer_sz); dirbuffer[dirbuffer_sz - 1] = '\0'; debug_printf3("Decoded packet for directory with %d entries: %s\n", num_entries, dirbuffer); - return 0; + return num_entries; } void ldcs_cache_addFileDir(char *dname, char *fname) diff --git a/src/utils/spindle_mkdir.c b/src/utils/spindle_mkdir.c index b820482b..e367db19 100644 --- a/src/utils/spindle_mkdir.c +++ b/src/utils/spindle_mkdir.c @@ -27,10 +27,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #define SPINDLE_DEBUG_H_ #endif -#include "ldcs_api.h" #include "config.h" - #if defined(TRACK_MKDIR) extern void track_mkdir(const char *dir); #endif @@ -38,132 +36,403 @@ extern void track_mkdir(const char *dir); extern int lookup_prev_mkdir(const char *dir); #endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif -static int checkdir(char *path) +#include +#include +#include +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +static int spindle_mkdir_lstat(const char *path, struct stat *buf) { - struct stat buf; - int result = stat(path, &buf); - if (result == -1) { - err_printf("spindle_mkdir failed because stat on existing directory %s failed: %s\n", - path, strerror(errno)); + return lstat(path, buf); +} + +static ssize_t spindle_mkdir_readlink(const char *path, char *buf, size_t size) +{ + return readlink(path, buf, size); +} + +static int spindle_mkdir_mkdir(const char *path, mode_t mode) +{ + return mkdir(path, mode); +} + +static int within(const char *path, const char *prefix, size_t length) +{ + return !strncmp(path, prefix, length) && + (length == 1 || path[length] == '/' || path[length] == '\0'); +} + +static int append(char *path, size_t *length, const char *part, size_t size) +{ + size_t separator = !(*length == 1 && path[0] == '/'); + + if (*length + separator > PATH_MAX - 1 || + size > PATH_MAX - 1 - *length - separator) { + errno = ENAMETOOLONG; + debug_printf("WARNING: append failing with ENAMETOLONG on '%s' and '%s'\n", path, part); return -1; } - if (!S_ISDIR(buf.st_mode) || S_ISLNK(buf.st_mode)) { - err_printf("spindle_mkdir failed because non-directory %s appeared in path during mkdir\n", - path); + if (separator) + path[(*length)++] = '/'; + memcpy(path + *length, part, size); + *length += size; + path[*length] = '\0'; + return 0; +} + +/* Move up from a resolved path. Relative paths retain leading '..' because + * the current directory cannot be named absolutely with the allowed calls. */ +static int parent(char path[PATH_MAX], size_t *length) +{ + if (path[0] != '/' && + ((*length == 1 && path[0] == '.') || + (*length >= 3 && path[*length - 3] == '/' && + path[*length - 2] == '.' && path[*length - 1] == '.'))) + return append(path, length, "..", 2); + + while (*length > 1 && path[*length - 1] != '/') + --*length; + if (*length > 1) + --*length; + path[*length] = '\0'; + return 0; +} + +static int check_directory(const char *path, struct stat *existing_stat) +{ + struct stat st; + int error; + + if (!existing_stat) { + if (spindle_mkdir_lstat(path, &st) < 0) { + error = errno; + debug_printf("WARNING: Failed to stat %s: %s\n", path, strerror(error)); + errno = error; + return -1; + } + existing_stat = &st; + } + if (!S_ISDIR(existing_stat->st_mode)) { + errno = ENOTDIR; + debug_printf("WARNING: %s is not a directory\n", path); return -1; } - if (buf.st_uid != geteuid()) { - err_printf("spindle_mkdir failed because component %s was owned by %d rather than expected %d\n", - path, buf.st_uid, geteuid()); + if (existing_stat->st_uid != geteuid() || existing_stat->st_gid != getegid() || + (existing_stat->st_mode & 07777) != 0700) { + errno = EACCES; + debug_printf("WARNING: Permissions error on %s\n", path); return -1; } - if (buf.st_gid != getegid()) { - err_printf("spindle_mkdir failed because component %s had group %d rather than expected %d\n", - path, buf.st_gid, getegid()); + return 0; +} + +/* EEXIST may come from another process; verify what is there either way. */ +static int make_directory(const char *path) +{ + int result; + if (spindle_mkdir_mkdir(path, 0700) < 0 && errno != EEXIST) { + debug_printf("WARNING: Failed to mkdir(%s)\n", path); return -1; } - if ((buf.st_mode & 0777) != 0700) { - err_printf("spindle_mkdir failed because component %s had unexpected permissions %o\n", - path, buf.st_mode & 0777); + result = check_directory(path, NULL); + if (result == -1) { + debug_printf("WARNING: check_directory failed here\n"); return -1; } - - return 0; +#if defined(TRACK_MKDIR) + track_mkdir(path); +#endif + return result; } -int spindle_mkdir(char *orig_path) +/* Process the path 'suffix' and make new directories. path starts at "/", ".", or the already + resolved cachepath. ../, ./, and symlinks are resolved and, if a cachepath is provided, + must stay within the cachepath. */ +static int mkdir_impl(const char *suffix, const char *cachepath, char path[PATH_MAX]) { - char path[MAX_PATH_LEN+1]; - int i, path_len, result, do_mkdir = 0, error; - struct stat buf; - char orig_char; + char pending[PATH_MAX], target[PATH_MAX]; + size_t length, cachepath_length; + size_t cursor = 0, pending_length; + int links = 0, result, error; - debug_printf2("spindle_mkdir on %s\n", orig_path); - + length = strlen(path); + cachepath_length = cachepath ? strlen(cachepath) : 0; + pending_length = strlen(suffix); + if (pending_length >= sizeof(pending)) { + debug_printf("WARNING: mkdir_impl ENAMETOLONG on '%s'\n", suffix); + errno = ENAMETOOLONG; + return -1; + } + /* Expansion can insert NUL separators, so pending_length, not strlen, + * defines the part of pending still in use. */ + memcpy(pending, suffix, pending_length); - strncpy(path, orig_path, sizeof(path)); - path[MAX_PATH_LEN] = '\0'; - path_len = strlen(path); - - i = 0; - while (path[i] == '/') - i++; + while (cursor < pending_length) { + size_t start, end, old_length; + size_t boundary; + struct stat st; + ssize_t symlink_target_size; - for (; i < path_len+1; i++) { - if (path[i] != '/' && path[i] != '\0') - continue; - orig_char = path[i]; - path[i] = '\0'; + /* Skip empty components. An inserted NUL ends one symlink target; + * check it before applying the caller's remaining components. */ + while (cursor < pending_length && pending[cursor] == '/') + ++cursor; + if (cursor == pending_length) + break; -#if defined(LOOKUP_PREV_MKDIR) - if (!do_mkdir) { - result = lookup_prev_mkdir(path); - if (result == 1) { - do_mkdir = 1; + /* A NUL marks the end of a symlink target, before its caller's tail. */ + if (pending[cursor] == '\0') { + if (cachepath && !within(path, cachepath, cachepath_length)) { + debug_printf("WARNING within failing with EACCES on '%s' in '%s'\n", path, cachepath); + errno = EACCES; + return -1; } + ++cursor; + continue; } -#endif - if (!do_mkdir) { - //Run a stat on an existing path component. As long as a directory - //component already exists, we won't be too picky about its ownership. - result = stat(path, &buf); - if (result == -1) { - error = errno; - if (error == ENOENT) { - do_mkdir = 1; - } - else { - err_printf("spindle_mkdir failed to stat path component %s: %s\n", - path, strerror(error)); + + start = cursor; + while (cursor < pending_length && pending[cursor] && pending[cursor] != '/') + ++cursor; + end = cursor; + + /* Path component is a './'. Move on. */ + if (end - start == 1 && pending[start] == '.') { + continue; + } + + /* Path component is a '../'. Use parent() to move up a directory as long, as we're not on the + cachepath root */ + if (end - start == 2 && pending[start] == '.' && pending[start + 1] == '.') { + /* Clamp at cachepath, just as '..' at '/' stays at '/'. */ + if (!cachepath || length > cachepath_length) { + result = parent(path, &length); + if (result < 0) { + error = errno; + debug_printf("WARNING mkdir_impl failing because could not determine parent of '%s' with cachepath '%s'\n", + path ? path : "[NULL]", cachepath ? cachepath : "[NULL]"); + errno = error; return -1; } } - if (!S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode)) { - err_printf("spindle_mkdir failed because path component %s is not a directory or symlink\n", - path); - return -1; - } + continue; } - - if (do_mkdir) { - result = mkdir(path, 0700); + + old_length = length; + if (append(path, &length, pending + start, end - start) < 0) + return -1; + /* Missing components are kept in the resolved path for the later + * mkdir pass. Existing non-directories cannot be traversed. */ + result = spindle_mkdir_lstat(path, &st); + + /* Create the directory if the path component does not exist */ + if (result == -1 && errno == ENOENT) { + result = make_directory(path); if (result == -1) { - error = errno; - if (error != EEXIST) { - err_printf("spindle_mkdir failed to make path component %s: %s\n", path, strerror(error)); + return -1; + } + continue; + } + if (result == -1) { + error = errno; + debug_printf("WARNING: lstat failed during mkdir_impl for '%s': %s\n", path, strerror(error)); + errno = error; + return -1; + } + if (S_ISDIR(st.st_mode)) { + if (cachepath && length > cachepath_length) { + /* We're strictly underneath the cachepath on an existing directory. Permissions should be locked down. */ + result = check_directory(path, &st); + if (result == -1) { + error = errno; + debug_printf("WARNING: Permission error underneath cachepath %s: %s\n", path, strerror(error)); + errno = error; return -1; } - //Someone created this path component while we were doing the mkdir. - //May be a race with other Spindle libraries. Check that it's owned - //by us with appropriate permissions. - if (checkdir(path) == -1) - return -1; - } - else { - debug_printf3("Did a mkdir(%s)\n", path); } -#if defined(TRACK_MKDIR) - track_mkdir(path); -#endif + continue; + } + if (!S_ISLNK(st.st_mode)) { + debug_printf("WARNING: mkdir_impl failing for '%s' because ENOTDIR\n", path); + errno = ENOTDIR; + return -1; + } + + /* Check targets of links inside the prefix, even if the caller's + * remaining path would later return inside. Links in a prefix alias + * may resolve to an ancestor, so they get no boundary check here. */ + boundary = cachepath && within(path, cachepath, cachepath_length); + if (++links > 40) { + debug_printf("WARNING: mkdir_impl failing for '%s' because ELOOP\n", path); + errno = ELOOP; + return -1; + } + symlink_target_size = spindle_mkdir_readlink(path, target, sizeof(target) - 1); + if (symlink_target_size < 0) { + error = errno; + debug_printf("WARNING: mkdir_impl failing for '%s' because readlink failed: %s\n", path, strerror(error)); + errno = error; + return -1; + } + if (symlink_target_size == 0) { + debug_printf("WARNING: mkdir_impl failing for '%s' with ENOENT\n", path); + errno = ENOENT; + return -1; + } + if ((size_t)symlink_target_size + boundary + pending_length - end >= sizeof(pending)) { + debug_printf("WARNING: mkdir_impl failing for '%s' with ENAMETOOLONG\n", path); + errno = ENAMETOOLONG; + return -1; + } + + /* Replace the link with its target and keep the unread tail. The + * optional NUL marks where this target ends. Nested expansions keep + * earlier markers in that tail without a separate stack. */ + memmove(pending + symlink_target_size + boundary, pending + end, pending_length - end); + memcpy(pending, target, symlink_target_size); + if (boundary) + pending[symlink_target_size] = '\0'; + pending_length = (size_t) symlink_target_size + boundary + pending_length - end; + cursor = 0; + /* Absolute targets restart at root; relative targets restart at the + * link's parent, saved in old_length. */ + if (target[0] == '/') { + path[0] = '/'; + path[1] = '\0'; + length = 1; + } else { + length = old_length; + path[length] = '\0'; } - path[i] = orig_char; + } + /* Also reject an ordinary path that ends outside the prefix. */ + if (cachepath && !within(path, cachepath, cachepath_length)) { + debug_printf("WARNING: mkdir_impl failing for '%s' with EACCESs and cachepath of %s\n", path, cachepath); + errno = EACCES; + return -1; + } + return 0; +} - if (path[i] == '/') - while (path[i+1] == '/') - i++; +static ssize_t validate_path_under_cachepath(const char *path, const char *cachepath) +{ + ssize_t prefix_length; + prefix_length = strlen(cachepath); + while (prefix_length > 1 && cachepath[prefix_length - 1] == '/') + --prefix_length; + if (prefix_length >= PATH_MAX) { + debug_printf("WARNING: spindle_mkdir failing with ENAMETOOLONG on '%s'\n", + path ? path : "[NULL]"); + errno = ENAMETOOLONG; + return -1; + } + if (!within(path, cachepath, prefix_length)) { + debug_printf("WARNING: spindle_mkdir failing with EACCESS on '%s' and '%s'\n", + path ? path : "[NULL]", cachepath ? cachepath : "[NULL]"); + errno = EACCES; + return -1; + } + return prefix_length; +} + +static int check_mkdir_args(const char *path, const char *cachepath) +{ + if (!path || !*path || (cachepath && (cachepath[0] != '/' || path[0] != '/'))) { + debug_printf("WARNING: spindle_mkdir failing with EINVAL on '%s' with cachepath '%s'\n", + path ? path : "[NULL]", cachepath ? cachepath : "[NULL]"); + errno = EINVAL; + return -1; } + return 0; +} - if (!do_mkdir) { - //We never did any mkdirs. Ensure that the final directory in the existing path - // is exclusively ours. - if (checkdir(path) == -1) { +static int spindle_mkdir_impl(const char *path, const char *cachepath) +{ + char resolved[PATH_MAX]; + ssize_t prefix_length; + int error; + + if (check_mkdir_args(path, cachepath) == -1) + return -1; + + if (cachepath) { + /* Validate that path is prefixed by the cachepath */ + prefix_length = validate_path_under_cachepath(path, cachepath); + if (prefix_length == -1) { + error = errno; + debug_printf("WARNING: Failed to validate that mkdir cache is under cachepath '%s' and '%s'\n", + path, cachepath); + errno = error; + return -1; + } + + strncpy(resolved, cachepath, sizeof(resolved)); + if (mkdir_impl(path + prefix_length, cachepath, resolved) < 0) { return -1; } -#if defined(TRACK_MKDIR) - track_mkdir(path); -#endif + } else { + /* Relative paths stay relative; absolute paths start at root. */ + strcpy(resolved, path[0] == '/' ? "/" : "."); + if (mkdir_impl(path, NULL, resolved) < 0) { + return -1; + } + } + + return 0; +} + +int spindle_mkdir(const char *path) +{ + char resolved[PATH_MAX]; + + if (check_mkdir_args(path, NULL) == -1) + return -1; + + strcpy(resolved, path[0] == '/' ? "/" : "."); + if (mkdir_impl(path, NULL, resolved) < 0) { + return -1; } + return 0; } +int spindle_mkdir_in_cache(const char *path, const char *cachepath) +{ + char resolved[PATH_MAX]; + ssize_t prefix_length; + int error; + + if (!cachepath) + return spindle_mkdir(path); + + if (check_mkdir_args(path, cachepath) == -1) + return -1; + + /* Validate that path is prefixed by the cachepath */ + prefix_length = validate_path_under_cachepath(path, cachepath); + if (prefix_length == -1) { + error = errno; + debug_printf("WARNING: Failed to validate that mkdir on '%s' is under cachepath '%s'\n", + path, cachepath); + errno = error; + return -1; + } + + strncpy(resolved, cachepath, sizeof(resolved)); + if (mkdir_impl(path + prefix_length, cachepath, resolved) < 0) { + return -1; + } + + return 0; +} diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 4e20fb8b..43a0d299 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -18,12 +18,12 @@ libgenerator_SOURCES = libgenerator.c test_driverSOURCES = $(top_srcdir)/testsuite/test_driver.c test_driverCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils $(MPI_CFLAGS) -Wall -I$(top_builddir) test_driverLDADD = -ldl -lpthread -ltestoutput -lfuncdict -lspindle -test_driverLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite -L$(top_builddir)/src/client/spindle_api $(MPI_CLDFLAGS) $(LDFLAGS) -L. $(DYNAMIC_FLAG) -no-install +test_driverLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite -L$(top_builddir)/src/client/spindle_api $(MPI_CLDFLAGS) $(LDFLAGS) -L. $(DYNAMIC_FLAG) -no-install '-Wl,-rpath,$$ORIGIN/exeorigin_dir' test_driver_libsSOURCES = $(top_srcdir)/testsuite/test_driver.c -test_driver_libsCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils $(MPI_CFLAGS) -Wall +test_driver_libsCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils -I$(top_builddir) $(MPI_CFLAGS) -Wall test_driver_libsLDADD = -ltest10 -ltest11 -ltest12 -ltest13 -ltest14 -ltest15 -ltest16 -ltest17 -ltest18 -ltest19 -ltest20 -ltest50 -ltest100 -ltest500 -ltest1000 -ltest2000 -ltest4000 -ltest6000 -ltest8000 -ltest10000 -ldepA -lcxxexceptA -loriginlib -ldl -lpthread -ltestoutput -lfuncdict -ldepB -ldepC -lcxxexceptB -lspindle -test_driver_libsLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite $(MPI_CLDFLAGS) -L$(top_builddir)/src/client/spindle_api -L. $(DYNAMIC_FLAG) -no-install $(LDFLAGS) -Wl,-rpath,$(PWD)/origin_dir -L$(PWD)/origin_dir -Wl,-rpath-link,$(PWD)/origin_dir/origin_subdir -I$(top_builddir) +test_driver_libsLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite $(MPI_CLDFLAGS) -L$(top_builddir)/src/client/spindle_api -L. $(DYNAMIC_FLAG) -no-install $(LDFLAGS) -Wl,-rpath,$(PWD)/origin_dir -L$(PWD)/origin_dir -Wl,-rpath-link,$(PWD)/origin_dir/origin_subdir -L$(PWD)/exeorigin_dir '-Wl,-rpath,$$ORIGIN/exeorigin_dir' REGLIB_SRC = $(srcdir)/registerlib.c LD_FUNCDICT = -L$(top_builddir)/testsuite -lfuncdict @@ -31,8 +31,8 @@ LD_FUNCDICT = -L$(top_builddir)/testsuite -lfuncdict test_driver: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driverSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ $(test_driverCFLAGS) $(test_driverLDFLAGS) $(test_driverLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 -test_driver_libs: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so libdepA.so libcxxexceptA.so libdepB.so libdepC.so libcxxexceptB.so origin_dir/liboriginlib.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so - $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driver_libsSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ -DUSE_NEEDED $(test_driver_libsCFLAGS) $(test_driver_libsLDFLAGS) $(test_driver_libsLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 +test_driver_libs: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so libdepA.so libcxxexceptA.so libdepB.so libdepC.so libcxxexceptB.so origin_dir/liboriginlib.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so exeorigin_dir/libexeorigin.so + $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driver_libsSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ -DUSE_NEEDED $(test_driver_libsCFLAGS) $(test_driver_libsLDFLAGS) $(test_driver_libsLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 -lexeorigin libtest10.c: libgenerator $(AM_V_GEN)./libgenerator libtest10.c 10 t10 @@ -307,6 +307,12 @@ libtestoutput.so: testoutput.c $(REGLIB_SRC) libfuncdict.so: funcdict.c $(REGLIB_SRC) $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=$@ -shared +exeorigin_dir: + $(AM_V_GEN) mkdir -p exeorigin_dir + +exeorigin_dir/libexeorigin.so: origintarget.c exeorigin_dir libfuncdict.so + $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -shared -Wall -DSO_NAME=libexeorigin.so -DFUNC_NAME=origintarget_calc $< $(REGLIB_SRC) $(LD_FUNCDICT) -L$(PWD) + origin_dir/origin_subdir: $(AM_V_GEN) mkdir -p origin_dir/origin_subdir @@ -315,7 +321,7 @@ origin_dir/origin_subdir/liborigintarget.so: origintarget.c origin_dir/origin_su @touch $@ origin_dir/liboriginlib.so: originlib.c $(REGLIB_SRC) origin_dir/origin_subdir/liborigintarget.so - $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=liboriginlib.so -DFUNC_NAME=origin_calc -shared '-Wl,-rpath,$$ORIGIN/origin_subdir' -Lorigin_dir/origin_subdir -lorigintarget + $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=liboriginlib.so -DFUNC_NAME=origintarget_calc -shared '-Wl,-rpath,$$ORIGIN/origin_subdir' -Lorigin_dir/origin_subdir -lm -lorigintarget libsymbind_a.so: $(srcdir)/symbindlib.c $(srcdir)/symbind_fileops.c libsymbind_b.so $(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ -shared -fPIC -Wall -DAUTORUN=a $(srcdir)/symbindlib.c -L. -Wl,--no-as-needed -lsymbind_b -I$(srcdir) -Wl,-rpath,$(top_builddir)/testsuite diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index ff41207b..ad2439e8 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -374,11 +374,11 @@ libgenerator_SOURCES = libgenerator.c test_driverSOURCES = $(top_srcdir)/testsuite/test_driver.c test_driverCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils $(MPI_CFLAGS) -Wall -I$(top_builddir) test_driverLDADD = -ldl -lpthread -ltestoutput -lfuncdict -lspindle -test_driverLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite -L$(top_builddir)/src/client/spindle_api $(MPI_CLDFLAGS) $(LDFLAGS) -L. $(DYNAMIC_FLAG) -no-install +test_driverLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite -L$(top_builddir)/src/client/spindle_api $(MPI_CLDFLAGS) $(LDFLAGS) -L. $(DYNAMIC_FLAG) -no-install '-Wl,-rpath,$$ORIGIN/exeorigin_dir' test_driver_libsSOURCES = $(top_srcdir)/testsuite/test_driver.c -test_driver_libsCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils $(MPI_CFLAGS) -Wall +test_driver_libsCFLAGS = -DLPATH=$(top_builddir)/testsuite -I$(top_srcdir)/src/client/spindle_api -I$(top_srcdir)/src/utils -I$(top_builddir) $(MPI_CFLAGS) -Wall test_driver_libsLDADD = -ltest10 -ltest11 -ltest12 -ltest13 -ltest14 -ltest15 -ltest16 -ltest17 -ltest18 -ltest19 -ltest20 -ltest50 -ltest100 -ltest500 -ltest1000 -ltest2000 -ltest4000 -ltest6000 -ltest8000 -ltest10000 -ldepA -lcxxexceptA -loriginlib -ldl -lpthread -ltestoutput -lfuncdict -ldepB -ldepC -lcxxexceptB -lspindle -test_driver_libsLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite $(MPI_CLDFLAGS) -L$(top_builddir)/src/client/spindle_api -L. $(DYNAMIC_FLAG) -no-install $(LDFLAGS) -Wl,-rpath,$(PWD)/origin_dir -L$(PWD)/origin_dir -Wl,-rpath-link,$(PWD)/origin_dir/origin_subdir -I$(top_builddir) +test_driver_libsLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite $(MPI_CLDFLAGS) -L$(top_builddir)/src/client/spindle_api -L. $(DYNAMIC_FLAG) -no-install $(LDFLAGS) -Wl,-rpath,$(PWD)/origin_dir -L$(PWD)/origin_dir -Wl,-rpath-link,$(PWD)/origin_dir/origin_subdir -L$(PWD)/exeorigin_dir '-Wl,-rpath,$$ORIGIN/exeorigin_dir' REGLIB_SRC = $(srcdir)/registerlib.c LD_FUNCDICT = -L$(top_builddir)/testsuite -lfuncdict EXTRA_DIST = run_crash_tests_template.sh crash_test.c crash_functions.c crash_functions.h libcrashfuncs.c libcrashctor.c libcrashfixed.c @@ -727,8 +727,8 @@ uninstall-am: test_driver: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driverSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ $(test_driverCFLAGS) $(test_driverLDFLAGS) $(test_driverLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 -test_driver_libs: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so libdepA.so libcxxexceptA.so libdepB.so libdepC.so libcxxexceptB.so origin_dir/liboriginlib.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so - $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driver_libsSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ -DUSE_NEEDED $(test_driver_libsCFLAGS) $(test_driver_libsLDFLAGS) $(test_driver_libsLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 +test_driver_libs: $(test_driverSOURCES) $(REGLIB_SRC) libtestoutput.so libfuncdict.so libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so libdepA.so libcxxexceptA.so libdepB.so libdepC.so libcxxexceptB.so origin_dir/liboriginlib.so libbigtls1048576.so libbigtls204800.so libbigtls1024.so exeorigin_dir/libexeorigin.so + $(AM_V_CCLD) $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(MPICC) -o $@ $(test_driver_libsSOURCES) $(REGLIB_SRC) -DSO_NAME=$@ -DUSE_NEEDED $(test_driver_libsCFLAGS) $(test_driver_libsLDFLAGS) $(test_driver_libsLDADD) -lbigtls1048576 -lbigtls204800 -lbigtls1024 -lexeorigin libtest10.c: libgenerator $(AM_V_GEN)./libgenerator libtest10.c 10 t10 @@ -1003,6 +1003,12 @@ libtestoutput.so: testoutput.c $(REGLIB_SRC) libfuncdict.so: funcdict.c $(REGLIB_SRC) $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=$@ -shared +exeorigin_dir: + $(AM_V_GEN) mkdir -p exeorigin_dir + +exeorigin_dir/libexeorigin.so: origintarget.c exeorigin_dir libfuncdict.so + $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -shared -Wall -DSO_NAME=libexeorigin.so -DFUNC_NAME=origintarget_calc $< $(REGLIB_SRC) $(LD_FUNCDICT) -L$(PWD) + origin_dir/origin_subdir: $(AM_V_GEN) mkdir -p origin_dir/origin_subdir @@ -1011,7 +1017,7 @@ origin_dir/origin_subdir/liborigintarget.so: origintarget.c origin_dir/origin_su @touch $@ origin_dir/liboriginlib.so: originlib.c $(REGLIB_SRC) origin_dir/origin_subdir/liborigintarget.so - $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=liboriginlib.so -DFUNC_NAME=origin_calc -shared '-Wl,-rpath,$$ORIGIN/origin_subdir' -Lorigin_dir/origin_subdir -lorigintarget + $(AM_V_CCLD)$(MPICC) -o $@ -fPIC -Wall $< $(REGLIB_SRC) -DSO_NAME=liboriginlib.so -DFUNC_NAME=origintarget_calc -shared '-Wl,-rpath,$$ORIGIN/origin_subdir' -Lorigin_dir/origin_subdir -lm -lorigintarget libsymbind_a.so: $(srcdir)/symbindlib.c $(srcdir)/symbind_fileops.c libsymbind_b.so $(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ -shared -fPIC -Wall -DAUTORUN=a $(srcdir)/symbindlib.c -L. -Wl,--no-as-needed -lsymbind_b -I$(srcdir) -Wl,-rpath,$(top_builddir)/testsuite diff --git a/testsuite/origintarget.c b/testsuite/origintarget.c index e6eab90f..8c5a9ecc 100644 --- a/testsuite/origintarget.c +++ b/testsuite/origintarget.c @@ -1,6 +1,20 @@ +#include + +__thread int tlsvar_originexe = -1; +static void on_load() __attribute__((constructor)); +static void on_load() { tlsvar_originexe = 10; } +int get_tlsvar_originexe() { return tlsvar_originexe; } + +volatile int is_zero = 0; + int origin_target() { + if (is_zero) + printf("HERE\n"); return 2; } - +int origintarget_calc() +{ + return origin_target(); +} diff --git a/testsuite/run_driver_template b/testsuite/run_driver_template index a486766b..a3d61ce3 100644 --- a/testsuite/run_driver_template +++ b/testsuite/run_driver_template @@ -75,7 +75,7 @@ if [ $1 == --serial ] ; then exec SPINDLE_EXEC --level=high --launcher=serial $2 fi -export LIBRARY_LIST="`pwd`/libcxxexceptA.so:`pwd`/libtest100.so:`pwd`/libtest2000.so:`pwd`/libtest500.so:`pwd`/libtest1000.so:`pwd`/libtest4000.so:`pwd`/libtest6000.so:`pwd`/libdepA.so:`pwd`/libtest10.so:`pwd`/libtest11.so:`pwd`/libtest12.so:`pwd`/libtest13.so:`pwd`/libtest14.so:`pwd`/libtest15.so:`pwd`/libtest16.so:`pwd`/libtest17.so:`pwd`/libtest18.so:`pwd`/libtest19.so:`pwd`/libtest20.so:`pwd`/libtest10000.so:`pwd`/libtest50.so:`pwd`/libtest8000.so:`pwd`/origin_dir/liboriginlib.so" +export LIBRARY_LIST="`pwd`/libcxxexceptA.so:`pwd`/libtest100.so:`pwd`/libtest2000.so:`pwd`/libtest500.so:`pwd`/libtest1000.so:`pwd`/libtest4000.so:`pwd`/libtest6000.so:`pwd`/libdepA.so:`pwd`/libtest10.so:`pwd`/libtest11.so:`pwd`/libtest12.so:`pwd`/libtest13.so:`pwd`/libtest14.so:`pwd`/libtest15.so:`pwd`/libtest16.so:`pwd`/libtest17.so:`pwd`/libtest18.so:`pwd`/libtest19.so:`pwd`/libtest20.so:`pwd`/libtest10000.so:`pwd`/libtest50.so:`pwd`/libtest8000.so:`pwd`/origin_dir/liboriginlib.so:`pwd`/exeorigin_dir/libexeorigin.so" if [ $1 == --dependency ] ; then diff --git a/testsuite/test_driver.c b/testsuite/test_driver.c index 50ed9102..6ff56783 100644 --- a/testsuite/test_driver.c +++ b/testsuite/test_driver.c @@ -112,8 +112,11 @@ typedef struct { #define FLAGS_TLSLIB (1 << 5) #define FLAGS_CHECKSYMT (1 << 6) #define FLAGS_LOCAL (1 << 7) +#define FLAGS_OPEN_AFTER_FORK (1 << 8) + int abort_mode = 0; int fork_mode = 0; +int fork_mode_is_child = 0; int fork_child = 0; int forkexec_mode = 0; int nompi_mode = 0; @@ -151,11 +154,11 @@ open_libraries_t libraries[] = { { "libtest6000.so", NULL, NULL, NULL, UNLOADED, 0, NULL }, { "libtest8000.so", NULL, NULL, NULL, UNLOADED, 0, NULL }, { "libtest10000.so", NULL, NULL, NULL, UNLOADED, 0, NULL }, - { "libdepA.so", NULL, NULL, NULL, UNLOADED, 0, NULL }, - { "libcxxexceptA.so", NULL, NULL, NULL, UNLOADED, 0, NULL }, + { "libdepA.so", NULL, NULL, NULL, UNLOADED, FLAGS_OPEN_AFTER_FORK, NULL }, + { "libcxxexceptA.so", NULL, NULL, NULL, UNLOADED, FLAGS_OPEN_AFTER_FORK, NULL }, { "libnoexist.so", NULL, NULL, NULL, UNLOADED, FLAGS_NOEXIST, NULL }, { "libsymlink.so", NULL, NULL, NULL, UNLOADED, FLAGS_SYMLINK | FLAGS_SKIP | FLAGS_WONTLOAD, NULL }, - { "liboriginlib.so", NULL, NULL, NULL, UNLOADED, 0, "origin_dir/" }, + { "liboriginlib.so", NULL, NULL, NULL, UNLOADED, FLAGS_OPEN_AFTER_FORK, "origin_dir/" }, { "libtls1.so", NULL, NULL, NULL, UNLOADED, FLAGS_TLSLIB | FLAGS_SKIP, NULL }, { "libtls2.so", NULL, NULL, NULL, UNLOADED, FLAGS_TLSLIB | FLAGS_SKIP, NULL }, { "libtls3.so", NULL, NULL, NULL, UNLOADED, FLAGS_TLSLIB | FLAGS_SKIP, NULL }, @@ -197,6 +200,7 @@ open_libraries_t libraries[] = { { "libtest8000.so", NULL, NULL, NULL, UNLOADED, FLAGS_CHECKSYMT | FLAGS_SKIP, NULL }, { "libtest10000.so", NULL, NULL, NULL, UNLOADED, FLAGS_CHECKSYMT | FLAGS_SKIP, NULL }, { "liblocal.so", NULL, NULL, NULL, UNLOADED, FLAGS_LOCAL, NULL }, + { "libexeorigin.so", NULL, NULL, NULL, UNLOADED, FLAGS_OPEN_AFTER_FORK, "exeorigin_dir/" }, { NULL, NULL, NULL, 0, 0 } }; int num_libraries; @@ -453,10 +457,11 @@ static char *create_local_file(int libnum) static void open_library(int i) { - char *fullpath, *result; + char *fullpath; + void *result; if (libraries[i].flags & FLAGS_TLSLIB) return; - if (!(libraries[i].flags & FLAGS_LOCAL)) + else if (!(libraries[i].flags & FLAGS_LOCAL)) fullpath = libpath(libraries[i].libname, libraries[i].subdir); else fullpath = create_local_file(i); @@ -465,12 +470,13 @@ static void open_library(int i) check_symt(fullpath); return; } - if (!(libraries[i].flags & FLAGS_WONTLOAD) && !(libraries[i].flags & FLAGS_LOCAL)) + if (!(libraries[i].flags & FLAGS_WONTLOAD) && !(libraries[i].flags & FLAGS_LOCAL)) { test_printf("dlstart %s\n", libraries[i].libname); - + } + result = dlopen(fullpath, RTLD_LAZY | RTLD_GLOBAL); if (libraries[i].flags & FLAGS_NOEXIST) { - if (result != 0) + if (result) err_printf("Failure, opened a library that doesn't exist\n"); return; } @@ -501,6 +507,11 @@ void dependency_mode() /* Should be auto loaded */ int i; for (i = 0; i