[PATCH 3/4] dlopen: on x/lib search x/bin if exe is in x/bin

Michael Haubenwallner michael.haubenwallner@ssi-schaefer.com
Fri Sep 2 08:46:00 GMT 2016


Hi Corinna,

On 09/01/2016 03:32 PM, Corinna Vinschen wrote:
> On Aug 31 20:07, Michael Haubenwallner wrote:
>> 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".
>> ---
>>  winsup/cygwin/dlfcn.cc | 36 +++++++++++++++++++++++++++++++++++-
>>  1 file changed, 35 insertions(+), 1 deletion(-)
>>
>> diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
>> index e592512..f8b8743 100644
>> --- a/winsup/cygwin/dlfcn.cc
>> +++ b/winsup/cygwin/dlfcn.cc
>> @@ -153,6 +153,25 @@ 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. */
>> +  GetModuleFileNameW (NULL, wpathbuf, NT_MAX_PATH);
>> +  wchar_t * lastwsep = wcsrchr (wpathbuf, L'\\');
>> +  if (!lastwsep)
>> +    return 0;
>> +  *lastwsep = L'\0';
>> +  *exedirbuf = '\0';
>> +  if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, wpathbuf, exedirbuf, NT_MAX_PATH))
>> +    return 0;
>> +  return strlen (exedirbuf);
>> +}
> 
> 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.

>>  extern "C" void *
>>  dlopen (const char *name, int flags)
>>  {
>> @@ -184,13 +203,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
>>  	{
>> -- 
>> 2.7.3
> 
> Rest looks ok.

Thanks!
/haubi/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-dlopen-on-x-lib-search-x-bin-if-exe-is-in-x-bin.patch
Type: text/x-patch
Size: 2693 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20160902/114ea5e7/attachment.bin>


More information about the Cygwin-patches mailing list