由 startproc 运行的程序的 QDir::homePath() 的非预期结果
Non-expected result of QDir::homePath() for a program run by startproc
>我有以下小程序:
#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: %sn", qPrintable(QDir::homePath()));
printf("Native homedir: %sn", homeDir());
QCoreApplication a(argc, argv);
return a.exec();
}
现在:
- 当由"普通"用户直接运行时,
./program
,输出为: Qt homedir:/home/user
Native homedir:/home/usr
这没关系
- 当直接由 root 运行时,
./program
,输出为: Qt homedir:/rootNative homedir:/root
这没关系
- 当由 root 作为其他用户通过 sudo 运行时,例如
sudo -u user ./program
,输出为: Qt homedir:/home/userNative homedir:/home/user
这没关系
- 当由 root 以其他用户身份通过 startproc 运行时,例如
startproc -u user /full/path/to/program
,输出为:Qt homedir:/root
Native homedir:/home/user
这是不行的,或者不是预期的(至少对我来说)
我的问题是:为什么最后一次运行给出的结果与其他运行不同?是Qt中的一个错误(没有考虑到有效用户与真实用户不同的事实,或者不同),还是我缺少一些背景信息(例如startproc的工作原理)?
有问题的Qt版本是5.6.1。
Qt的QFileSystemEngine
使用Unix上HOME
环境变量的内容 - 请参阅其实现。然而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();
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死
- 由 startproc 运行的程序的 QDir::homePath() 的非预期结果