porting rev.1998 from 1.4.4 (except ODBC, which will be done later, and SQLite, which was ported in rev.1999)

This commit is contained in:
Aleksandar Fabijanic
2012-09-05 02:43:06 +00:00
parent 86bafbb27e
commit a221b14522
17 changed files with 224 additions and 48 deletions

View File

@@ -42,12 +42,17 @@
#include "Poco/Exception.h"
#include "Poco/Buffer.h"
#if defined(POCO_WIN32_UTF8)
#include "Poco/UnicodeConverter.h"
#include "Poco/UnicodeConverter.h"
#endif
#if POCO_OS == POCO_OS_LINUX
#include <sys/inotify.h>
#include <sys/select.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <sys/select.h>
#include <unistd.h>
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
#include <fcntl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#endif
#include <algorithm>
#include <map>
@@ -391,6 +396,89 @@ private:
};
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
class BSDDirectoryWatcherStrategy: public DirectoryWatcherStrategy
{
public:
BSDDirectoryWatcherStrategy(DirectoryWatcher& owner):
DirectoryWatcherStrategy(owner),
_queueFD(-1),
_dirFD(-1),
_stopped(false)
{
_dirFD = open(owner.directory().path().c_str(), O_EVTONLY);
if (_dirFD < 0) throw Poco::FileNotFoundException(owner.directory().path());
_queueFD = kqueue();
if (_queueFD < 0)
{
close(_dirFD);
throw Poco::SystemException("Cannot create kqueue", errno);
}
}
~BSDDirectoryWatcherStrategy()
{
close(_dirFD);
close(_queueFD);
}
void run()
{
Poco::Timestamp lastScan;
ItemInfoMap entries;
scan(entries);
while (!_stopped)
{
struct timespec timeout;
timeout.tv_sec = 0;
timeout.tv_nsec = 200000000;
unsigned eventFilter = NOTE_WRITE;
struct kevent event;
struct kevent eventData;
EV_SET(&event, _dirFD, EVFILT_VNODE, EV_ADD | EV_CLEAR, eventFilter, 0, 0);
int nEvents = kevent(_queueFD, &event, 1, &eventData, 1, &timeout);
if (nEvents < 0 || eventData.flags == EV_ERROR)
{
try
{
FileImpl::handleLastErrorImpl(owner().directory().path());
}
catch (Poco::Exception& exc)
{
owner().scanError(&owner(), exc);
}
}
else if (nEvents > 0 || ((owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED) && lastScan.isElapsed(owner().scanInterval()*1000000)))
{
ItemInfoMap newEntries;
scan(newEntries);
compare(entries, newEntries);
std::swap(entries, newEntries);
lastScan.update();
}
}
}
void stop()
{
_stopped = true;
}
bool supportsMoveEvents() const
{
return false;
}
private:
int _queueFD;
int _dirFD;
bool _stopped;
};
#else
@@ -495,6 +583,8 @@ void DirectoryWatcher::init()
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
#elif POCO_OS == POCO_OS_LINUX
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
#else
_pStrategy = new DefaultDirectoryWatcherStrategy(*this);
#endif

View File

@@ -129,18 +129,33 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
fdmap[1] = outPipe ? outPipe->writeHandle() : 1;
fdmap[2] = errPipe ? errPipe->writeHandle() : 2;
char* envPtr = 0;
char** envPtr = 0;
std::vector<char> envChars;
std::vector<char*> envPtrs;
if (!env.empty())
{
envChars = getEnvironmentVariablesBuffer(env);
envPtr = &environmentChars[0];
envPtrs.reserve(env.size() + 1);
char* p = &envChars[0];
while (*p)
{
envPtrs.push_back(p);
while (*p) ++p;
++p;
}
envPtrs.push_back(0);
envPtr = &envPtrs[0];
}
int pid = spawn(command.c_str(), 3, fdmap, &inherit, argv, envPtr);
delete [] argv;
if (pid == -1)
throw SystemException("cannot spawn", command);
if (inPipe) inPipe->close(Pipe::CLOSE_READ);
if (outPipe) outPipe->close(Pipe::CLOSE_WRITE);
if (errPipe) errPipe->close(Pipe::CLOSE_WRITE);
return new ProcessHandleImpl(pid);
}
else
{