[GNC-dev] Resolving symlinks in _br_find_exe in binreloc.c

John Ralls jralls at ceridwen.us
Thu May 21 14:41:38 EDT 2020

> On May 21, 2020, at 12:55 AM, Mike Alexander <mta at umich.edu> wrote:
> I've had some fixes in binreloc.c for some time that I'm trying to clean up and commit.  Part of the problem is that _br_find_exe doesn't work at all for non-Aqua Mac builds (i.e. using X11).  I've fixed this by calling _NSGetExecutablePath if GNC_PLATFORM_OSX is set and MAC_INTEGRATION is not set.  This has been working for me for several years.  It shouldn't affect any other platforms.
> The other problem is that it doesn't resolve symlinks properly.  There are bugs in that code that mean it never works, even in the simple case.  I can make simple cases (where the last path component is a symlink) work easily enough, but the general case is a bit more complicated if you limit yourself to using only readlink.  Is there any reason that we don't use the realpath function for this?  I think it exists in all non-Windows systems GnuCash cares about (Windows is a completely separate implementation of _br_find_exe).  It is in MacOS since 10.4, in Posix since POSIX.1-2001, in BSD4.4, and in Linux.  It's essentially trivial to call and will solve the problem.


The code that we have is gnomified from the original autopackage.org version. I agree it's pretty awful; the comparison of sizeof(ptr) to SSIZE_MAX particularly so; trying to allocate SSIZE_MAX-1 in the impossible case that sizeof(ptr) > SSIZE_MAX borders on comical. I suggest that rather than allocating the path buffers you just create two char[PATH_MAX +1] buffers on the stack.

There's another problem though, /proc/self/exe is Linux-only so it still won't work for the BSDs. They don't all have proc (OpenBSD doesn't, it's optional on FreeBSD; NetBSD has procfs and uses /proc/curproc/exe; DragonFly BSD uses /proc/curproc/file [1]). The most general solution is to store argv[0] in inner_main and then look for that file in $PATH. I dunno if it's that prominent a use case. There have been only 2 bugs about binreloc ever and neither of them is that it doesn't work.

John Ralls

[1] https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

More information about the gnucash-devel mailing list