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 <oswald.buddenhagen@gmx.de>
This commit is contained in:
Thiago Macieira 2021-04-23 14:44:34 -07:00
parent 831aea1ce1
commit e4ed47ef4a

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2021 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation. ** Copyright (C) 2021 Intel Corporation.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -109,6 +109,10 @@
# include "qcore_unix_p.h" # include "qcore_unix_p.h"
#endif #endif
#if __has_include(<sys/auxv.h>) // Linux and FreeBSD
# include <sys/auxv.h>
#endif
#ifdef Q_OS_VXWORKS #ifdef Q_OS_VXWORKS
# include <taskLib.h> # include <taskLib.h>
#endif #endif
@ -2288,11 +2292,24 @@ QString QCoreApplication::applicationDirPath()
#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) // qcoreapplication_win.cpp or qcoreapplication_mac.cpp #if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) // qcoreapplication_win.cpp or qcoreapplication_mac.cpp
static QString qAppFileName() static QString qAppFileName()
{ {
# if defined(Q_OS_LINUX) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED)) # if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
return QFile::decodeName(qt_readlink("/proc/self/exe")); // the actual process on Android is the Java VM, so this doesn't help us
# endif
return QString(); 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 #endif