Skip to content

[Tests] Fix RemoteMirror test to work when DYLD_LIBRARY_PATH is set. #38960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 24, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions test/RemoteMirror/Inputs/interop.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,55 @@
#import <Foundation/Foundation.h>
#import <mach/mach.h>
#import <mach-o/dyld.h>
#import <libgen.h>
#import <stdlib.h>
#import <string.h>

#import "SwiftRemoteMirrorLegacyInterop.h"

// dirname() is *not* safe - it may modify the input string; so instead just
// copy anything up to the last slash.
char *safe_dirname(const char *path) {
const char *slash = strrchr(path, '/');
if (!slash)
return strdup(".");
size_t len = slash - path;
char *result = (char *)malloc(len + 1);
memcpy(result, path, len);
result[len] = '\0';
return result;
}

void *Load(char *path) {
const char *libpath = getenv("DYLD_LIBRARY_PATH");
char *ourlibpath = NULL;
const char *oldlibpath = NULL;

if (libpath && path[0] == '/') {
// If DYLD_LIBRARY_PATH is set, and the path we've been given is absolute,
// then prepend the directory part of the path we've been given to it.
char *libdir = safe_dirname(path);
size_t dirlen = strlen(libdir);
if (asprintf(&ourlibpath, "%s:%s", libdir, oldlibpath) < 0) {
fprintf(stderr, "Unable to form new DYLD_LIBRARY_PATH!\n");
exit(1);
}
free(libdir);

oldlibpath = ourlibpath + dirlen + 1;

setenv("DYLD_LIBRARY_PATH", ourlibpath, 1);
}

// Actually open the dylib
void *Handle = dlopen(path, RTLD_LOCAL);

if (ourlibpath) {
// Reset DYLD_LIBRARY_PATH, if we changed it
setenv("DYLD_LIBRARY_PATH", oldlibpath, 1);
free(ourlibpath);
}

if (Handle == NULL) {
fprintf(stderr, "loading %s: %s\n", path, dlerror());
exit(1);
Expand Down