From e4ed47ef4a7fafbc63febc58d13eca247db64a05 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 23 Apr 2021 14:44:34 -0700 Subject: [PATCH] QCoreApplication::applicationFilePath: add ELF auxval support This implements getting the executable file name for FreeBSD. Linux has a similar functionality (but called AT_EXECFN), but the /proc/self/exe trick is actually better: it returns a full canonical path instead of the argument passed to execve(), and it follows a rename of the executable. Change-Id: I7a386ad4f0cb4e2ba629fffd16789acda415213f Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qcoreapplication.cpp | 27 ++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 78d836d4be..947d61a194 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2021 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -109,6 +109,10 @@ # include "qcore_unix_p.h" #endif +#if __has_include() // Linux and FreeBSD +# include +#endif + #ifdef Q_OS_VXWORKS # include #endif @@ -2288,11 +2292,24 @@ QString QCoreApplication::applicationDirPath() #if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) // qcoreapplication_win.cpp or qcoreapplication_mac.cpp static QString qAppFileName() { -# if defined(Q_OS_LINUX) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED)) - return QFile::decodeName(qt_readlink("/proc/self/exe")); -# endif - +# if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + // the actual process on Android is the Java VM, so this doesn't help us return QString(); +# elif defined(Q_OS_LINUX) + // this includes the Embedded Android builds + return QFile::decodeName(qt_readlink("/proc/self/exe")); +# elif defined(AT_EXECPATH) + // seen on FreeBSD, but I suppose the other BSDs could adopt this API + char execfn[PATH_MAX]; + if (elf_aux_info(AT_EXECPATH, execfn, sizeof(execfn)) != 0) + execfn[0] = '\0'; + + qsizetype len = qstrlen(execfn); + return QFile::decodeName(QByteArray::fromRawData(execfn, len)); +# else + // other OS or something + return QString(); +#endif } #endif