mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-24 09:12:28 +02:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user