Browse Source

Win32 version compiles ;)

master
Artyom Beilis 14 years ago
parent
commit
03c76ef120
2 changed files with 43 additions and 71 deletions
  1. +38
    -67
      session_win32_file_storage.cpp
  2. +5
    -4
      session_win32_file_storage.h

+ 38
- 67
session_win32_file_storage.cpp View File

@@ -17,8 +17,7 @@ namespace sessions {
struct session_file_storage::data {};
session_file_storage::session_file_storage(std::string path) :
memory_(MAP_FAILED)
session_file_storage::session_file_storage(std::string path)
{
if(path.empty()){
if(::getenv("TEMP"))
@@ -31,7 +30,7 @@ session_file_storage::session_file_storage(std::string path) :
else
path_=path;
if(!CreateDirectory(path_.c_str(),NULL)) {
if(!::CreateDirectory(path_.c_str(),NULL)) {
if(GetLastError()!=ERROR_ALREADY_EXISTS) {
throw cppcms_error("Failed to create a directory for session storage " + path_);
}
@@ -89,7 +88,7 @@ public:
::UnlockFileEx(h_,0,0,16,&ov);
::CloseHandle(h_);
}
int handle() { return h_; }
HANDLE handle() { return h_; }
std::string name() { return name_; }
private:
HANDLE h_;
@@ -119,29 +118,27 @@ void session_file_storage::remove(std::string const &sid)
::DeleteFile(file.name().c_str());
}
bool session_file_storage::read_timestamp(int fd)
bool session_file_storage::read_timestamp(HANDLE h)
{
::lseek(fd,0,SEEK_SET);
int64_t stamp;
if(!read_all(fd,&stamp,sizeof(stamp)) || stamp < ::time(0))
if(!read_all(h,&stamp,sizeof(stamp)) || stamp < ::time(0))
return false;
return true;
}
bool session_file_storage::read_from_file(int fd,time_t &timeout,std::string &data)
bool session_file_storage::read_from_file(HANDLE h,time_t &timeout,std::string &data)
{
int64_t f_timeout;
uint32_t crc;
uint32_t size;
::lseek(fd,0,SEEK_SET);
if(!read_all(fd,&f_timeout,sizeof(f_timeout)))
if(!read_all(h,&f_timeout,sizeof(f_timeout)))
return false;
if(f_timeout < time(0))
return false;
if(!read_all(fd,&crc,sizeof(crc)) || !read_all(fd,&size,sizeof(size)))
if(!read_all(h,&crc,sizeof(crc)) || !read_all(h,&size,sizeof(size)))
return false;
std::vector<char> buffer(size,0);
if(!read_all(fd,&buffer.front(),size))
if(!read_all(h,&buffer.front(),size))
return false;
boost::crc_32_type crc_calc;
crc_calc.process_bytes(&buffer.front(),size);
@@ -153,7 +150,7 @@ bool session_file_storage::read_from_file(int fd,time_t &timeout,std::string &da
return true;
}
void session_file_storage::save_to_file(int fd,time_t timeout,std::string const &in)
void session_file_storage::save_to_file(HANDLE h,time_t timeout,std::string const &in)
{
struct {
int64_t timeout;
@@ -163,90 +160,64 @@ void session_file_storage::save_to_file(int fd,time_t timeout,std::string const
boost::crc_32_type crc_calc;
crc_calc.process_bytes(in.data(),in.size());
tmp.crc=crc_calc.checksum();
if(!write_all(fd,&tmp,sizeof(tmp)) || !write_all(fd,in.data(),in.size()))
if(!write_all(h,&tmp,sizeof(tmp)) || !write_all(h,in.data(),in.size()))
throw cppcms_error(errno,"Failed to write to file");
}
bool session_file_storage::write_all(int fd,void const *vbuf,int n)
bool session_file_storage::write_all(HANDLE h,void const *vbuf,int n)
{
char const *buf=reinterpret_cast<char const *>(vbuf);
while(n > 0) {
int res = ::write(fd,buf,n);
if(res < 0 && errno==EINTR)
continue;
if(res <= 0)
return false;
n-=res;
}
DWORD written;
if(!::WriteFile(h,vbuf,n,&written,NULL) || written!=unsigned(n))
return false;
return true;
}
bool session_file_storage::read_all(int fd,void *vbuf,int n)
bool session_file_storage::read_all(HANDLE h,void *vbuf,int n)
{
char *buf=reinterpret_cast<char *>(vbuf);
while(n > 0) {
int res = ::read(fd,buf,n);
if(res < 0 && errno==EINTR)
continue;
if(res <= 0)
return false;
n-=res;
}
DWORD read;
if(!::ReadFile(h,vbuf,n,&read,NULL) || read!=unsigned(n))
return false;
return true;
}
void session_file_storage::gc()
{
DIR *d=0;
struct dirent *entry_st=0,*entry_p;
int path_len=pathconf(path_.c_str(),_PC_NAME_MAX);
if(path_len < 0 ) {
// Only "sessions" should be in this directory
// also this directory has high level of trust
// thus... Don't care about symlink exploits
#ifdef NAME_MAX
path_len=NAME_MAX;
#elif defined(PATH_MAX)
path_len=PATH_MAX;
#else
path_len=4096; // guess
#endif
}
// this is for Solaris...
entry_st=(struct dirent *)new char[sizeof(struct dirent)+path_len+1];
std::auto_ptr<WIN32_FIND_DATA> entry(new WIN32_FIND_DATA);
HANDLE d=INVALID_HANDLE_VALUE;
std::string search_path = path_ + "/*";
try{
if((d=::opendir(path_.c_str()))==NULL) {
int err=errno;
throw cppcms_error(err,"Failed to open directory :"+path_);
if((d=::FindFirstFile(search_path.c_str(),entry.get()))==INVALID_HANDLE_VALUE) {
if(GetLastError() == ERROR_FILE_NOT_FOUND)
return;
throw cppcms_error("Failed to open directory :"+path_);
}
while(::readdir_r(d,entry_st,&entry_p)==0 && entry_p!=NULL) {
do {
int i;
for(i=0;i<32;i++) {
if(!isxdigit(entry_st->d_name[i]))
if(!isxdigit(entry->cFileName[i]))
break;
}
if(i!=32 || entry_st->d_name[i]!=0)
if(i!=32 || entry->cFileName[i]!=0)
continue;
std::string sid=entry_st->d_name;
std::string sid=entry->cFileName;
{
locked_file file(this,sid,false);
if(file.fd() >=0 && !read_timestamp(file.fd()))
::unlink(file.name().c_str());
locked_file file(this,sid);
if(!read_timestamp(file.handle()))
::DeleteFile(file.name().c_str());
}
}
::closedir(d);
} while(::FindNextFile(d,entry.get()));
::FindClose(d);
}
catch(...) {
if(d) ::closedir(d);
delete [] entry_st;
if(d!=INVALID_HANDLE_VALUE) ::FindClose(d);
throw;
}
}
struct session_file_storage_factory::data {};
session_file_storage_factory::session_file_storage_factory(std::string path,int conc,int proc_no,bool force_lock) :
storage_(new session_file_storage(path,conc,proc_no,force_lock))
session_file_storage_factory::session_file_storage_factory(std::string path) :
storage_(new session_file_storage(path))
{
}


+ 5
- 4
session_win32_file_storage.h View File

@@ -4,7 +4,6 @@
#include "defs.h"
#include "session_storage.h"
#include "hold_ptr.h"
#include <pthread.h>
#include <vector>
@@ -23,9 +22,11 @@ namespace sessions {
private:
struct locked_file;
struct data;
bool read_timestamp(HANDLE h);
bool read_from_file(HANDLE h,time_t &timeout,std::string &data);
void save_to_file(HANDLE h,time_t timeout,std::string const &in);
bool read_timestamp(void *h);
bool read_from_file(void *h,time_t &timeout,std::string &data);
void save_to_file(void *h,time_t timeout,std::string const &in);
bool read_all(void *,void *vbuf,int n);
bool write_all(void *,void const *vbuf,int n);
void gc();
std::string file_name(std::string const &sid);


Loading…
Cancel
Save