Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>2016-09-02 14:57:20 +0300
committerCorinna Vinschen <corinna@vinschen.de>2016-09-08 14:36:32 +0300
commitf763e2dc88d04430dd2524a529eef91a2e517e4e (patch)
tree32de31ff7ff76234d1c60c5432cb7e21b4b9c45d
parentb37c3ed5e57e528adf73548882cf252a79c014dd (diff)
dlopen: on x/lib search x/bin if exe is in x/binnewlib-snapshot-20160923
On 09/02/2016 11:03 AM, Corinna Vinschen wrote: > On Sep 2 10:46, Michael Haubenwallner wrote: >> On 09/01/2016 03:32 PM, Corinna Vinschen wrote: >>> You could just use the global variable program_invocation_name. If in >>> doubt, use the Windows path global_progname and convert it to full POSIX >>> via cygwin_conv_path. >> >> Patch updated, using global_progname now. > > Looks good and you're right to do it this way since I just noticed > that program_invocation_name may return a relative pathname. Yep. > Btw., in other calls which require the full POSIX path we use > mount_table->conv_to_posix_path instead of cygwin_conv_path (see > e. g. fillout_pinfo()). It's a bit faster. Maybe something for a > followup patch. No problem - attached. This renders the original patch 4/4 valid again. > Note for some later improvement: I really wonder why we don't store > the absolute POSIX path of the current executable globally yet... Same here. Thanks! /haubi/ >From f7255edd33cb4abe34f27188aab8dccdfa5dd2a0 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com> Date: Wed, 31 Aug 2016 18:05:11 +0200 Subject: [PATCH 3/4] dlopen: on x/lib search x/bin if exe is in x/bin citing https://cygwin.com/ml/cygwin-developers/2016-08/msg00020.html > Consider the file /usr/bin/cygz.dll: > - dlopen (libz.so) success > - dlopen (/usr/bin/libz.so) success > - dlopen (/usr/lib/libz.so) fails * dlfcn.c (dlopen): For dlopen("x/lib/N"), when the application executable is in "x/bin/", search for "x/bin/N" before "x/lib/N".
-rw-r--r--winsup/cygwin/dlfcn.cc43
1 files changed, 42 insertions, 1 deletions
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index e592512ad..159d4fe88 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -20,6 +20,7 @@ details. */
#include "cygtls.h"
#include "tls_pbuf.h"
#include "ntdll.h"
+#include "shared_info.h"
#include "pathfinder.h"
/* Dumb allocator using memory from tmp_pathbuf.w_get ().
@@ -153,6 +154,31 @@ collect_basenames (pathfinder::basenamelist & basenames,
basenames.appendv (basename, baselen, ext, extlen, NULL);
}
+/* Identify dir of current executable into exedirbuf using wpathbuf buffer.
+ Return length of exedirbuf on success, or zero on error. */
+static int
+get_exedir (char * exedirbuf, wchar_t * wpathbuf)
+{
+ /* Unless we have a special cygwin loader, there is no such thing like
+ DT_RUNPATH on Windows we can use to search for dlls, except for the
+ directory of the main executable. */
+ *exedirbuf = '\0';
+
+ wchar_t * wlastsep = wcpcpy (wpathbuf, global_progname);
+ /* like wcsrchr(L'\\'), but we know the wcslen already */
+ while (--wlastsep > wpathbuf)
+ if (*wlastsep == L'\\')
+ break;
+ if (wlastsep <= wpathbuf)
+ return 0;
+ *wlastsep = L'\0';
+
+ if (mount_table->conv_to_posix_path (wpathbuf, exedirbuf, 0))
+ return 0;
+
+ return strlen (exedirbuf);
+}
+
extern "C" void *
dlopen (const char *name, int flags)
{
@@ -184,13 +210,28 @@ dlopen (const char *name, int flags)
/* handle for the named library */
path_conv real_filename;
wchar_t *wpath = tp.w_get ();
+ char *cpath = tp.c_get ();
pathfinder finder (allocator, basenames); /* eats basenames */
if (have_dir)
{
+ int dirlen = basename - 1 - name;
+
+ /* if the specified dir is x/lib, and the current executable
+ dir is x/bin, do the /lib -> /bin mapping, which is the
+ same actually as adding the executable dir */
+ if (dirlen >= 4 && !strncmp (name + dirlen - 4, "/lib", 4))
+ {
+ int exedirlen = get_exedir (cpath, wpath);
+ if (exedirlen == dirlen &&
+ !strncmp (cpath, name, dirlen - 4) &&
+ !strcmp (cpath + dirlen - 4, "/bin"))
+ finder.add_searchdir (cpath, exedirlen);
+ }
+
/* search the specified dir */
- finder.add_searchdir (name, basename - 1 - name);
+ finder.add_searchdir (name, dirlen);
}
else
{