forked from metin2/server
136 lines
3.5 KiB
C++
136 lines
3.5 KiB
C++
#include "stdafx.h"
|
|
#include "FileMonitor_FreeBSD.h"
|
|
#include "../../libthecore/include/log.h"
|
|
|
|
|
|
#define INVALID_KERNEL_EVENT -1
|
|
|
|
FileMonitorFreeBSD::FileMonitorFreeBSD()
|
|
{
|
|
m_KernelEventQueue = INVALID_KERNEL_EVENT;
|
|
}
|
|
|
|
FileMonitorFreeBSD::~FileMonitorFreeBSD()
|
|
{
|
|
if( m_KernelEventQueue != INVALID_KERNEL_EVENT )
|
|
{
|
|
close ( m_KernelEventQueue );
|
|
m_KernelEventQueue = INVALID_KERNEL_EVENT;
|
|
}
|
|
|
|
TMonitorFileHashMap::iterator it;
|
|
for( it = m_FileLists.begin(); it != m_FileLists.end(); ++it )
|
|
{
|
|
close(it->second.fhMonitor);
|
|
}
|
|
|
|
m_FileLists.clear();
|
|
|
|
m_MonitoredEventLists.clear();
|
|
m_TriggeredEventLists.clear();
|
|
}
|
|
|
|
|
|
void FileMonitorFreeBSD::Update(DWORD dwPulses)
|
|
{
|
|
if( m_KernelEventQueue == INVALID_KERNEL_EVENT || m_FileLists.size() == 0 )
|
|
return;
|
|
|
|
int nEvent = kevent(m_KernelEventQueue, &m_TriggeredEventLists[0], (int)m_TriggeredEventLists.size(), &m_MonitoredEventLists[0], (int)m_MonitoredEventLists.size(), NULL );
|
|
if( nEvent == INVALID_KERNEL_EVENT )
|
|
{
|
|
return;
|
|
}
|
|
else if( nEvent > 0 )
|
|
{
|
|
for( int i = 0; i < nEvent; ++i )
|
|
{
|
|
int nEventFlags = m_MonitoredEventLists[i].flags;
|
|
eFileUpdatedOptions eUpdateOption = e_FileUpdate_None;
|
|
|
|
if (nEventFlags & EV_ERROR)
|
|
eUpdateOption = e_FileUpdate_Error;
|
|
|
|
else if (nEventFlags & NOTE_DELETE)
|
|
eUpdateOption = e_FileUpdate_Deleted;
|
|
|
|
else if (nEventFlags & NOTE_EXTEND || nEventFlags & NOTE_WRITE)
|
|
eUpdateOption = e_FileUpdate_Modified;
|
|
|
|
else if (nEventFlags & NOTE_ATTRIB)
|
|
eUpdateOption = e_FileUpdate_AttrModified;
|
|
|
|
else if (nEventFlags & NOTE_LINK)
|
|
eUpdateOption = e_FileUpdate_Linked;
|
|
|
|
else if (nEventFlags & NOTE_RENAME)
|
|
eUpdateOption = e_FileUpdate_Renamed;
|
|
|
|
else if (nEventFlags & NOTE_REVOKE)
|
|
eUpdateOption = e_FileUpdate_Revoked;
|
|
|
|
if( eUpdateOption != e_FileUpdate_None )
|
|
{
|
|
TMonitorFileHashMap::iterator it;
|
|
for( it = m_FileLists.begin(); it != m_FileLists.end(); ++it )
|
|
{
|
|
FileIOContext_FreeBSD& context = it->second;
|
|
if( context.idxToEventList == i )
|
|
{
|
|
std::string strModifedFileName = it->first;
|
|
context.pListenFunc( strModifedFileName, eUpdateOption );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FileMonitorFreeBSD::AddWatch(const std::string& strFileName, PFN_FileChangeListener pListenerFunc)
|
|
{
|
|
int iFileHandle = -1;
|
|
if( (iFileHandle = open(strFileName.c_str(), O_RDONLY)) == -1)
|
|
{
|
|
sys_err("FileMonitorFreeBSD:AddWatch : can`t open file(%s).\n", strFileName.c_str());
|
|
return;
|
|
}
|
|
|
|
//create kqueue if not exists
|
|
if( m_KernelEventQueue == INVALID_KERNEL_EVENT )
|
|
m_KernelEventQueue = kqueue();
|
|
|
|
if( m_KernelEventQueue == INVALID_KERNEL_EVENT )
|
|
{
|
|
sys_err("FileMonitorFreeBSD:AddWatch : failed to create kqueue.\n");
|
|
return;
|
|
}
|
|
|
|
TMonitorFileHashMap::iterator it = m_FileLists.find( strFileName );
|
|
if( it != m_FileLists.end() )
|
|
{
|
|
sys_log(0, "FileMonitorFreeBSD:AddWatch : trying to add duplicated watch on file(%s).\n", strFileName.c_str() );
|
|
return;
|
|
}
|
|
|
|
//set file context
|
|
FileIOContext_FreeBSD context;
|
|
{
|
|
context.fhMonitor = iFileHandle;
|
|
context.idxToEventList = (int)m_MonitoredEventLists.size();
|
|
context.pListenFunc = pListenerFunc;
|
|
}
|
|
|
|
m_FileLists[strFileName] = context;
|
|
|
|
//set events
|
|
struct kevent kTriggerEvent, kMonitorEvent;
|
|
|
|
EV_SET(&kTriggerEvent, iFileHandle, EVFILT_VNODE,
|
|
EV_ADD | EV_ENABLE | EV_ONESHOT,
|
|
NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE,
|
|
0, 0);
|
|
|
|
m_TriggeredEventLists.push_back( kTriggerEvent );
|
|
m_MonitoredEventLists.push_back( kMonitorEvent );
|
|
} |