语境
我正在慢慢地用 C++ 编写一个专门的 Web 服务器应用程序(使用 C onion http 服务器库和JSONCPP 库进行 JSON 序列化,如果这很重要的话)。对于带有 GCC 4.6 编译器的 Linux 系统(我不关心可移植性到非 Linux 系统,或 4.5 之前的 GCC 或 3.0 之前的 Clang)。
我决定将用户“数据库”(用户很少,可能只有一两个,所以性能不是问题,并且 O(n) 访问时间是可以接受的)以 JSON 格式保存,可能是 JSON 的小数组像这样的物体
{ "_user" : "basile" ;
"_crypasswd" : "XYZABC123" ;
"_email" : "basile@starynkevitch.net" ;
"firstname" : "Basile" ;
"lastname" : "Starynkevitch" ;
"privileges" : "all" ;
}
按照惯例(à la .htpasswd
),该_crypasswd
字段是用户密码的crypt(3) “加密”,按_user
名称加盐;
我想通过 Json 对象来描述用户的原因是我的应用程序可能会在描述用户的此类 Json 对象中添加(而不是替换)一些 JSON 字段(例如privileges
上面的)。我使用JsonCpp作为 C++ 的 Json 解析库。这个库想要一个ifstream
被解析的。
所以我正在阅读我的密码文件
extern char* iaca_passwd_path; // the path of the password file
std::ifstream jsinpass(iaca_passwd_path);
Json::Value jpassarr;
Json::Reader reader;
reader.parse(jsinpass,jpassarr,true);
jsinpass.close();
assert (jpassarr.isArray());
for (int ix=0; ix<nbu; ix++) {
const Json::Value&jcuruser= jpassarr[ix];
assert(jcuruser.isObject());
if (jcuruser["_user"].compare(user) == 0) {
std::string crypasswd = jcuruser["_crypasswd"].asString();
if (crypasswd.compare(crypted_password(user,password)) == 0) {
// good user
}
}
}
问题
显然,我想flock
或lockf
密码文件,以确保只有一个进程正在读取或写入它。要调用这些函数,我需要获取ifstream jsinpass
. 但是谷歌主要给了我Kreckel 的 fileno(我觉得它很完整,但有点疯狂)来获取 an 的文件描述符,std::ifstream
我不确定构造函数不会预先读取其中的一些。因此我的问题是:
如何锁定 C++ ifstream
(Linux、GCC 4.6)?
(或者您是否找到其他方法来解决该问题?)
谢谢