我有以下小程序:
#include <unistd.h>
#include <pwd.h>
#include <QCoreApplication>
#include <QDir>
const char * homeDir()
{
return getpwuid(geteuid())->pw_dir;
}
int main(int argc, char *argv[])
{
printf("Qt homedir: %s\n", qPrintable(QDir::homePath()));
printf("Native homedir: %s\n", homeDir());
QCoreApplication a(argc, argv);
return a.exec();
}
现在:
./program
运行时,输出为:
Qt homedir:/ home / user
本地homedir:/ home / usr
没关系
./program
运行时,输出为:
Qt homedir:/ root
本地homedir:/ root
没关系
sudo -u user ./program
,输出为:
Qt homedir:/ home / user
本地homedir:/ home / user
没关系
startproc -u user /full/path/to/program
,输出为:
Qt homedir:/ root
本地homedir:/ home / user
不确定,或者不期望(至少对我而言)
我的问题是:为什么最后一次运行会产生与其他运行不同的结果?它是Qt中的一个错误(没有考虑到有效用户与真实用户不同的事实,或者不同的东西),或者我是否缺少一些背景信息(例如startproc如何工作的机制)? / p>
有问题的Qt版本是5.6.1。
答案 0 :(得分:1)
Qt&#39; QFileSystemEngine
使用Unix上HOME
环境变量的内容 - 请参阅implementation。但是startproc -u
没有设置HOME
:这就是失败的原因。
getpwuid
电话可能非常昂贵并且可以阻止,即通过从LDAP或AD服务器等获取信息,如果您自己处理它,它是最好的。此外,它不是线程安全的,您应该使用getpwuid_r
代替。
实现可能如下所示:
static QString getHomeDir() {
auto const N = sysconf(_SC_GETPW_R_SIZE_MAX);
auto *buffer = std::make_unique<char[]>(N);
passwd pwd;
passwd *result;
getpwuid_r(geteuid(), &pwd, buffer.get(), N, &result);
if (result) {
auto *dir = result->pw_dir;
auto const decoded = QFile::decodeName(dir);
return QDir::cleanPath(decoded);
}
return {};
}
enum class HomeDir { Default, Init };
QString homeDir(HomeDir option = HomeDir::Default) {
// needs a C++11 compiler for thread-safe initialization
static QFuture<QString> home = QtConcurrent::run(getHomeDir);
return (option == HomeDir::Init) ? QString() : home;
};
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
homeDir(HomeDir::Init);
// do other time-consuming initializations here
QString () << homeDir();
}