[GNC-dev] Resolving symlinks in _br_find_exe in binreloc.c
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 ). The most general solution is to store argv 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.
More information about the gnucash-devel