在Linux上植入C++ ifstream(GCC 4.6)

Bas*_*tch 5 c++ linux g++ flock

上下文

我正在慢慢地用C++编写一个专门的Web服务器应用程序(使用C 洋葱http服务器库和用于JSON序列化的JSONCPP库,如果这很重要的话).对于带有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" ;
 }
Run Code Online (Sandbox Code Playgroud)

使用约定(à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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

显然,我想要flocklockf密码文件,以确保只有一个进程正在读或写它.要调用这些函数,我需要获取文件描述符(用Unix的说法)ifstream jsinpass.但谷歌给了我大部分Kreckel的fileno(我觉得完整,但有点疯狂)来获取一个文件描述符,std::ifstream我不确定构造函数是不会预读它的一些.因此我的问题是:

如何锁定C++ ifstream(Linux,GCC 4.6)?

(或者您是否找到其他方法来解决这个问题?)

谢谢

Has*_*kun 1

您可能想要使用单独的锁文件,而不是尝试从ifstream. 它更容易实现,并且您可以将其包装ifstream在一个自动执行此操作的类中。

如果您想确保原子打开/锁定,您可能需要使用此 SO 答案中建议的方法构造一个流,以下openflock

  • 注意:您可能不想按原样使用 Sutur 的 RWLock,它似乎包含内存泄漏并且不使用 `flock`/`lockf` 等 (2认同)