/inotify-cxx/tags/inotify-cxx-0.6.0/inotify-cxx.cpp |
---|
0,0 → 1,577 |
/// inotify C++ interface implementation |
/** |
* \file inotify-cxx.cpp |
* |
* inotify C++ interface |
* |
* Copyright (C) 2006 Lukas Jelinek <lukas@aiken.cz> |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of one of the following licenses: |
* |
* \li 1. X11-style license (see LICENSE-X11) |
* \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL) |
* \li 3. GNU General Public License, version 2 (see LICENSE-GPL) |
* |
* If you want to help with choosing the best license for you, |
* please visit http://www.gnu.org/licenses/license-list.html. |
* |
*/ |
#include <errno.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include "inotify-cxx.h" |
/// procfs inotify base path |
#define PROCFS_INOTIFY_BASE "/proc/sys/fs/inotify/" |
/// dump separator (between particular entries) |
#define DUMP_SEP \ |
({ \ |
if (!rStr.empty()) { \ |
rStr.append(","); \ |
} \ |
}) |
int32_t InotifyEvent::GetDescriptor() const |
{ |
return m_pWatch != NULL // if watch exists |
? m_pWatch->GetDescriptor() // return its descriptor |
: -1; // else return -1 |
} |
uint32_t InotifyEvent::GetMaskByName(const std::string& rName) |
{ |
if (rName == "IN_ACCESS") |
return IN_ACCESS; |
else if (rName == "IN_MODIFY") |
return IN_MODIFY; |
else if (rName == "IN_ATTRIB") |
return IN_ATTRIB; |
else if (rName == "IN_CLOSE_WRITE") |
return IN_CLOSE_WRITE; |
else if (rName == "IN_CLOSE_NOWRITE") |
return IN_CLOSE_NOWRITE; |
else if (rName == "IN_OPEN") |
return IN_OPEN; |
else if (rName == "IN_MOVED_FROM") |
return IN_MOVED_FROM; |
else if (rName == "IN_MOVED_TO") |
return IN_MOVED_TO; |
else if (rName == "IN_CREATE") |
return IN_CREATE; |
else if (rName == "IN_DELETE") |
return IN_DELETE; |
else if (rName == "IN_DELETE_SELF") |
return IN_DELETE_SELF; |
else if (rName == "IN_UNMOUNT") |
return IN_UNMOUNT; |
else if (rName == "IN_Q_OVERFLOW") |
return IN_Q_OVERFLOW; |
else if (rName == "IN_IGNORED") |
return IN_IGNORED; |
else if (rName == "IN_CLOSE") |
return IN_CLOSE; |
else if (rName == "IN_MOVE") |
return IN_MOVE; |
else if (rName == "IN_ISDIR") |
return IN_ISDIR; |
else if (rName == "IN_ONESHOT") |
return IN_ONESHOT; |
else if (rName == "IN_ALL_EVENTS") |
return IN_ALL_EVENTS; |
#ifdef IN_DONT_FOLLOW |
else if (rName == "IN_DONT_FOLLOW") |
return IN_DONT_FOLLOW; |
#endif // IN_DONT_FOLLOW |
#ifdef IN_ONLYDIR |
else if (rName == "IN_ONLYDIR") |
return IN_ONLYDIR; |
#endif // IN_ONLYDIR |
#ifdef IN_MOVE_SELF |
else if (rName == "IN_MOVE_SELF") |
return IN_MOVE_SELF; |
#endif // IN_MOVE_SELF |
return (uint32_t) 0; |
} |
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr) |
{ |
rStr = ""; |
if (IsType(uValue, IN_ALL_EVENTS)) { |
rStr.append("IN_ALL_EVENTS"); |
} |
else { |
if (IsType(uValue, IN_ACCESS)) { |
DUMP_SEP; |
rStr.append("IN_ACCESS"); |
} |
if (IsType(uValue, IN_MODIFY)) { |
DUMP_SEP; |
rStr.append("IN_MODIFY"); |
} |
if (IsType(uValue, IN_ATTRIB)) { |
DUMP_SEP; |
rStr.append("IN_ATTRIB"); |
} |
if (IsType(uValue, IN_CREATE)) { |
DUMP_SEP; |
rStr.append("IN_CREATE"); |
} |
if (IsType(uValue, IN_DELETE)) { |
DUMP_SEP; |
rStr.append("IN_DELETE"); |
} |
if (IsType(uValue, IN_DELETE_SELF)) { |
DUMP_SEP; |
rStr.append("IN_DELETE_SELF"); |
} |
if (IsType(uValue, IN_OPEN)) { |
DUMP_SEP; |
rStr.append("IN_OPEN"); |
} |
if (IsType(uValue, IN_CLOSE)) { |
DUMP_SEP; |
rStr.append("IN_CLOSE"); |
} |
else { |
if (IsType(uValue, IN_CLOSE_WRITE)) { |
DUMP_SEP; |
rStr.append("IN_CLOSE_WRITE"); |
} |
if (IsType(uValue, IN_CLOSE_NOWRITE)) { |
DUMP_SEP; |
rStr.append("IN_CLOSE_NOWRITE"); |
} |
} |
if (IsType(uValue, IN_MOVE)) { |
DUMP_SEP; |
rStr.append("IN_MOVE"); |
} |
else { |
if (IsType(uValue, IN_MOVED_FROM)) { |
DUMP_SEP; |
rStr.append("IN_MOVED_FROM"); |
} |
if (IsType(uValue, IN_MOVED_TO)) { |
DUMP_SEP; |
rStr.append("IN_MOVED_TO"); |
} |
} |
} |
if (IsType(uValue, IN_UNMOUNT)) { |
DUMP_SEP; |
rStr.append("IN_UNMOUNT"); |
} |
if (IsType(uValue, IN_Q_OVERFLOW)) { |
DUMP_SEP; |
rStr.append("IN_Q_OVERFLOW"); |
} |
if (IsType(uValue, IN_IGNORED)) { |
DUMP_SEP; |
rStr.append("IN_IGNORED"); |
} |
if (IsType(uValue, IN_ISDIR)) { |
DUMP_SEP; |
rStr.append("IN_ISDIR"); |
} |
if (IsType(uValue, IN_ONESHOT)) { |
DUMP_SEP; |
rStr.append("IN_ONESHOT"); |
} |
#ifdef IN_DONT_FOLLOW |
if (IsType(uValue, IN_DONT_FOLLOW)) { |
DUMP_SEP; |
rStr.append("IN_DONT_FOLLOW"); |
} |
#endif // IN_DONT_FOLLOW |
#ifdef IN_ONLYDIR |
if (IsType(uValue, IN_ONLYDIR)) { |
DUMP_SEP; |
rStr.append("IN_ONLYDIR"); |
} |
#endif // IN_ONLYDIR |
#ifdef IN_MOVE_SELF |
if (IsType(uValue, IN_MOVE_SELF)) { |
DUMP_SEP; |
rStr.append("IN_MOVE_SELF"); |
} |
#endif // IN_MOVE_SELF |
} |
void InotifyEvent::DumpTypes(std::string& rStr) const |
{ |
DumpTypes(m_uMask, rStr); |
} |
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException) |
{ |
IN_WRITE_BEGIN |
if (m_wd != -1) { |
int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask); |
if (wd != m_wd) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this); |
} |
} |
m_uMask = uMask; |
IN_WRITE_END |
} |
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException) |
{ |
IN_WRITE_BEGIN |
if (fEnabled == m_fEnabled) { |
IN_WRITE_END_NOTHROW |
return; |
} |
if (m_pInotify != NULL) { |
if (fEnabled) { |
m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask); |
if (m_wd == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this); |
} |
m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this)); |
} |
else { |
if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this); |
} |
m_pInotify->m_watches.erase(m_wd); |
m_wd = -1; |
} |
} |
m_fEnabled = fEnabled; |
IN_WRITE_END |
} |
Inotify::Inotify() throw (InotifyException) |
{ |
IN_LOCK_INIT |
m_fd = inotify_init(); |
if (m_fd == -1) { |
IN_LOCK_DONE |
throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL); |
} |
} |
Inotify::~Inotify() |
{ |
Close(); |
IN_LOCK_DONE |
} |
void Inotify::Close() |
{ |
IN_WRITE_BEGIN |
if (m_fd != -1) { |
RemoveAll(); |
close(m_fd); |
m_fd = -1; |
} |
IN_WRITE_END |
} |
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException) |
{ |
IN_WRITE_BEGIN |
// invalid descriptor - this case shouldn't occur - go away |
if (m_fd == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
} |
// this path already watched - go away |
if (FindWatch(pWatch->GetPath()) != NULL) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this); |
} |
// for enabled watch |
if (pWatch->IsEnabled()) { |
// try to add watch to kernel |
int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask()); |
// adding failed - go away |
if (wd == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this); |
} |
// this path already watched (but defined another way) |
InotifyWatch* pW = FindWatch(wd); |
if (pW != NULL) { |
// try to recover old watch because it may be modified - then go away |
if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this); |
} |
else { |
// recovery failed - go away |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this); |
} |
} |
pWatch->m_wd = wd; |
m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch)); |
} |
m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch)); |
pWatch->m_pInotify = this; |
IN_WRITE_END |
} |
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException) |
{ |
IN_WRITE_BEGIN |
// invalid descriptor - this case shouldn't occur - go away |
if (m_fd == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
} |
// for enabled watch |
if (pWatch->m_wd != -1) { |
// removing watch failed - go away |
if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this); |
} |
m_watches.erase(pWatch->m_wd); |
pWatch->m_wd = -1; |
} |
m_paths.erase(pWatch->m_path); |
pWatch->m_pInotify = NULL; |
IN_WRITE_END |
} |
void Inotify::RemoveAll() |
{ |
IN_WRITE_BEGIN |
IN_WP_MAP::iterator it = m_paths.begin(); |
while (it != m_paths.end()) { |
InotifyWatch* pW = (*it).second; |
if (pW->m_wd != -1) { |
inotify_rm_watch(m_fd, pW->m_wd); |
pW->m_wd = -1; |
} |
pW->m_pInotify = NULL; |
it++; |
} |
m_watches.clear(); |
m_paths.clear(); |
IN_WRITE_END |
} |
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException) |
{ |
ssize_t len = 0; |
do { |
len = read(m_fd, m_buf, INOTIFY_BUFLEN); |
} while (fNoIntr && len == -1 && errno == EINTR); |
if (len == -1 && !(errno == EWOULDBLOCK || errno == EINTR)) |
throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this); |
if (len == -1) |
return; |
IN_WRITE_BEGIN |
ssize_t i = 0; |
while (i < len) { |
struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i]; |
InotifyWatch* pW = FindWatch(pEvt->wd); |
if (pW != NULL) { |
InotifyEvent evt(pEvt, pW); |
m_events.push_back(evt); |
} |
i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
} |
IN_WRITE_END |
} |
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException) |
{ |
if (pEvt == NULL) |
throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this); |
IN_WRITE_BEGIN |
bool b = !m_events.empty(); |
if (b) { |
*pEvt = m_events.front(); |
m_events.pop_front(); |
} |
IN_WRITE_END |
return b; |
} |
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException) |
{ |
if (pEvt == NULL) |
throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this); |
IN_READ_BEGIN |
bool b = !m_events.empty(); |
if (b) { |
*pEvt = m_events.front(); |
} |
IN_READ_END |
return b; |
} |
InotifyWatch* Inotify::FindWatch(int iDescriptor) |
{ |
IN_READ_BEGIN |
IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor); |
InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second; |
IN_READ_END |
return pW; |
} |
InotifyWatch* Inotify::FindWatch(const std::string& rPath) |
{ |
IN_READ_BEGIN |
IN_WP_MAP::iterator it = m_paths.find(rPath); |
InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second; |
IN_READ_END |
return pW; |
} |
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException) |
{ |
IN_WRITE_BEGIN |
if (m_fd == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
} |
int res = fcntl(m_fd, F_GETFL); |
if (res == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this); |
} |
if (fNonBlock) { |
res |= O_NONBLOCK; |
} |
else { |
res &= ~O_NONBLOCK; |
} |
if (fcntl(m_fd, F_SETFL, res) == -1) { |
IN_WRITE_END_NOTHROW |
throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this); |
} |
IN_WRITE_END |
} |
uint32_t Inotify::GetCapability(InotifyCapability_t cap) throw (InotifyException) |
{ |
FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r"); |
if (f == NULL) |
throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL); |
unsigned int val = 0; |
if (fscanf(f, "%u", &val) != 1) { |
fclose(f); |
throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL); |
} |
fclose(f); |
return (uint32_t) val; |
} |
void Inotify::SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException) |
{ |
FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w"); |
if (f == NULL) |
throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL); |
if (fprintf(f, "%u", (unsigned int) val) <= 0) { |
fclose(f); |
throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL); |
} |
fclose(f); |
} |
std::string Inotify::GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException) |
{ |
std::string path(PROCFS_INOTIFY_BASE); |
switch (cap) { |
case IN_MAX_EVENTS: |
path.append("max_queued_events"); |
break; |
case IN_MAX_INSTANCES: |
path.append("max_user_instances"); |
break; |
case IN_MAX_WATCHES: |
path.append("max_user_watches"); |
break; |
default: |
throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL); |
} |
return path; |
} |
/inotify-cxx/tags/inotify-cxx-0.6.0/TODO |
---|
0,0 → 1,3 |
Currently pending tasks: |
* recursive watches (for watching whole directory subtrees) |
/inotify-cxx/tags/inotify-cxx-0.6.0/CHANGELOG |
---|
0,0 → 1,73 |
0.6.0 2006-12-28 |
* added methods for getting/setting inotify capabilities and limits |
* added IN_SELF_MOVED flag (if defined) |
* added Inotify::IsRecursive() for identifying recursive watches |
(will be implemented in future versions) |
0.5.3 2006-12-06 |
* fixed incorrect error handling in WaitForEvents() |
0.5.2 2006-11-12 |
* problem with ignoring IN_OPEN has been fixed (#0000102) |
0.5.1 2006-11-10 |
* problems with includes have been fixed (#0000099) |
0.5.0 2006-10-29 |
* partial thread safety has been implemented (using rwlocks) |
* Inotify::GetEnabledCount() method has been added |
0.4.1 2006-10-14 |
* wrong value returned by Inotify::GetWatchCount() has been fixed |
(#0000092) |
0.4.0 2006-10-13 |
* two additional flags (IN_ONLYDIR and IN_DONT_FOLLOW) may be used |
if available (#0000086) |
* "errorneous" multiple watches on the same path are no longer |
possible (#0000087) |
* tarball structure has been fixed (#0000088) |
* inotify-syscalls.h is included only if inotify.h doesn't contain |
syscall definitions (#0000090) |
* enabling/disabling is now done through watch presence in the kernel |
instead of dropping events (#0000091) |
* InotifyWatch::SetMask() method has been added to allow later mask |
modification |
0.3.1 2006-10-03 |
* fixed: wrong behavior for EWOULDBLOCK (Inotify::WaitForEvents()) |
0.3.0 2006-10-03 |
* all errors now handled using exceptions (InotifyException) |
* InotifyEvent no longer use struct inotity_event as its |
internal data structure |
* removed InotifyEvent::GetData() - internal data changed |
* removed Inotify::IsReady() - no longer necessary |
* added Inotify::GetDescriptor() - returns inotify file descriptor |
* added Inotify::SetNonBlock() - switches nonblocking mode on/off |
* added possibility to enable/disable watches |
* some code cleanups |
0.2.0 2006-09-15 |
* InotifyEvent now contains a pointer to the source InotifyWatch |
* fixed: InotifyEvent::IsType() - it now handles the mask correctly |
* added a static method (InotifyEvent::GetMaskByName()) for finding a mask |
for a name |
* added a static version of InotifyEvent::DumpTypes() method |
* added a static version of InotifyEvent::IsType() method |
* dumped types (InotifyEvent::DumpTypes()) now separated by commas |
instead of spaces |
* InotifyEvent::DumpTypes() methods now use as general types as possible |
* InotifyWatch now contains a pointer to the related Inotify |
0.1.0 2006-09-04 |
first alpha version |
/inotify-cxx/tags/inotify-cxx-0.6.0/inotify-cxx.h |
---|
0,0 → 1,859 |
/// inotify C++ interface header |
/** |
* \file inotify-cxx.h |
* |
* inotify C++ interface |
* |
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz> |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of one of the following licenses: |
* |
* \li 1. X11-style license (see LICENSE-X11) |
* \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL) |
* \li 3. GNU General Public License, version 2 (see LICENSE-GPL) |
* |
* If you want to help with choosing the best license for you, |
* please visit http://www.gnu.org/licenses/license-list.html. |
* |
*/ |
#ifndef _INOTIFYCXX_H_ |
#define _INOTIFYCXX_H_ |
#include <string> |
#include <deque> |
#include <map> |
// Please ensure that the following headers take the right place |
#include <sys/syscall.h> |
#include <sys/inotify.h> |
// Use this if syscalls not defined |
#ifndef __NR_inotify_init |
#include <sys/inotify-syscalls.h> |
#endif // __NR_inotify_init |
/// Event struct size |
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event)) |
/// Event buffer length |
#define INOTIFY_BUFLEN (1024 * (INOTIFY_EVENT_SIZE + 16)) |
/// Helper macro for creating exception messages. |
/** |
* It prepends the message by the function name. |
*/ |
#define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg) |
/// inotify capability/limit identifiers |
typedef enum |
{ |
IN_MAX_EVENTS = 0, ///< max. events in the kernel queue |
IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process |
IN_MAX_WATCHES = 2 ///< max. watches per file descriptor |
} InotifyCapability_t; |
/// inotify-cxx thread safety |
/** |
* If this symbol is defined you can use this interface safely |
* threaded applications. Remember that it slightly degrades |
* performance. |
* |
* Even if INOTIFY_THREAD_SAFE is defined some classes stay |
* unsafe. If you must use them (must you?) in more than one |
* thread concurrently you need to implement explicite locking. |
* |
* You need not to define INOTIFY_THREAD_SAFE in that cases |
* where the application is multithreaded but all the inotify |
* infrastructure will be managed only in one thread. This is |
* the recommended way. |
* |
* Locking may fail (it is very rare but not impossible). In this |
* case an exception is thrown. But if unlocking fails in case |
* of an error it does nothing (this failure is ignored). |
*/ |
#ifdef INOTIFY_THREAD_SAFE |
#include <pthread.h> |
#define IN_LOCK_DECL mutable pthread_rwlock_t __m_lock; |
#define IN_LOCK_INIT \ |
{ \ |
pthread_rwlockattr_t attr; \ |
int res = 0; \ |
if ((res = pthread_rwlockattr_init(&attr)) != 0) \ |
throw InotifyException(IN_EXC_MSG("cannot initialize lock attributes"), res, this); \ |
if ((res = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP)) != 0) \ |
throw InotifyException(IN_EXC_MSG("cannot set lock kind"), res, this); \ |
if ((res = pthread_rwlock_init(&__m_lock, &attr)) != 0) \ |
throw InotifyException(IN_EXC_MSG("cannot initialize lock"), res, this); \ |
pthread_rwlockattr_destroy(&attr); \ |
} |
#define IN_LOCK_DONE pthread_rwlock_destroy(&__m_lock); |
#define IN_READ_BEGIN \ |
{ \ |
int res = pthread_rwlock_rdlock(&__m_lock); \ |
if (res != 0) \ |
throw InotifyException(IN_EXC_MSG("locking for reading failed"), res, (void*) this); \ |
} |
#define IN_READ_END \ |
{ \ |
int res = pthread_rwlock_unlock(&__m_lock); \ |
if (res != 0) \ |
throw InotifyException(IN_EXC_MSG("unlocking failed"), res, (void*) this); \ |
} |
#define IN_READ_END_NOTHROW pthread_rwlock_unlock(&__m_lock); |
#define IN_WRITE_BEGIN \ |
{ \ |
int res = pthread_rwlock_wrlock(&__m_lock); \ |
if (res != 0) \ |
throw InotifyException(IN_EXC_MSG("locking for writing failed"), res, (void*) this); \ |
} |
#define IN_WRITE_END IN_READ_END |
#define IN_WRITE_END_NOTHROW IN_READ_END_NOTHROW |
#else // INOTIFY_THREAD_SAFE |
#define IN_LOCK_DECL |
#define IN_LOCK_INIT |
#define IN_LOCK_DONE |
#define IN_READ_BEGIN |
#define IN_READ_END |
#define IN_READ_END_NOTHROW |
#define IN_WRITE_BEGIN |
#define IN_WRITE_END |
#define IN_WRITE_END_NOTHROW |
#endif // INOTIFY_THREAD_SAFE |
// forward declaration |
class InotifyWatch; |
class Inotify; |
/// Class for inotify exceptions |
/** |
* This class allows to acquire information about exceptional |
* events. It makes easier to log or display error messages |
* and to identify problematic code locations. |
* |
* Although this class is basically thread-safe it is not intended |
* to be shared between threads. |
*/ |
class InotifyException |
{ |
public: |
/// Constructor |
/** |
* \param[in] rMsg message |
* \param[in] iErr error number (see errno.h) |
* \param[in] pSrc source |
*/ |
InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL) |
: m_msg(rMsg), |
m_err(iErr) |
{ |
m_pSrc = pSrc; |
} |
/// Returns the exception message. |
/** |
* \return message |
*/ |
inline const std::string& GetMessage() const |
{ |
return m_msg; |
} |
/// Returns the exception error number. |
/** |
* If not applicable this value is 0 (zero). |
* |
* \return error number (standardized; see errno.h) |
*/ |
inline int GetErrorNumber() const |
{ |
return m_err; |
} |
/// Returns the exception source. |
/** |
* \return source |
*/ |
inline void* GetSource() const |
{ |
return m_pSrc; |
} |
protected: |
std::string m_msg; ///< message |
int m_err; ///< error number |
mutable void* m_pSrc; ///< source |
}; |
/// inotify event class |
/** |
* It holds all information about inotify event and provides |
* access to its particular values. |
* |
* This class is not (and is not intended to be) thread-safe |
* and therefore it must not be used concurrently in multiple |
* threads. |
*/ |
class InotifyEvent |
{ |
public: |
/// Constructor. |
/** |
* Creates a plain event. |
*/ |
InotifyEvent() |
: m_uMask(0), |
m_uCookie(0) |
{ |
m_pWatch = NULL; |
} |
/// Constructor. |
/** |
* Creates an event based on inotify event data. |
* For NULL pointers it works the same way as InotifyEvent(). |
* |
* \param[in] pEvt event data |
* \param[in] pWatch inotify watch |
*/ |
InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch) |
: m_uMask(0), |
m_uCookie(0) |
{ |
if (pEvt != NULL) { |
m_uMask = (uint32_t) pEvt->mask; |
m_uCookie = (uint32_t) pEvt->cookie; |
if (pEvt->name != NULL) |
m_name = pEvt->name; |
m_pWatch = pWatch; |
} |
else { |
m_pWatch = NULL; |
} |
} |
/// Destructor. |
~InotifyEvent() {} |
/// Returns the event watch descriptor. |
/** |
* \return watch descriptor |
* |
* \sa InotifyWatch::GetDescriptor() |
*/ |
int32_t GetDescriptor() const; |
/// Returns the event mask. |
/** |
* \return event mask |
* |
* \sa InotifyWatch::GetMask() |
*/ |
inline uint32_t GetMask() const |
{ |
return m_uMask; |
} |
/// Checks a value for the event type. |
/** |
* \param[in] uValue checked value |
* \param[in] uType type which is checked for |
* \return true = the value contains the given type, false = otherwise |
*/ |
inline static bool IsType(uint32_t uValue, uint32_t uType) |
{ |
return ((uValue & uType) != 0) && ((~uValue & uType) == 0); |
} |
/// Checks for the event type. |
/** |
* \param[in] uType type which is checked for |
* \return true = event mask contains the given type, false = otherwise |
*/ |
inline bool IsType(uint32_t uType) const |
{ |
return IsType(m_uMask, uType); |
} |
/// Returns the event cookie. |
/** |
* \return event cookie |
*/ |
inline uint32_t GetCookie() const |
{ |
return m_uCookie; |
} |
/// Returns the event name length. |
/** |
* \return event name length |
*/ |
inline uint32_t GetLength() const |
{ |
return (uint32_t) m_name.length(); |
} |
/// Returns the event name. |
/** |
* \return event name |
*/ |
inline const std::string& GetName() const |
{ |
return m_name; |
} |
/// Extracts the event name. |
/** |
* \param[out] rName event name |
*/ |
inline void GetName(std::string& rName) const |
{ |
rName = GetName(); |
} |
/// Returns the source watch. |
/** |
* \return source watch |
*/ |
inline InotifyWatch* GetWatch() |
{ |
return m_pWatch; |
} |
/// Finds the appropriate mask for a name. |
/** |
* \param[in] rName mask name |
* \return mask for name; 0 on failure |
*/ |
static uint32_t GetMaskByName(const std::string& rName); |
/// Fills the string with all types contained in an event mask value. |
/** |
* \param[in] uValue event mask value |
* \param[out] rStr dumped event types |
*/ |
static void DumpTypes(uint32_t uValue, std::string& rStr); |
/// Fills the string with all types contained in the event mask. |
/** |
* \param[out] rStr dumped event types |
*/ |
void DumpTypes(std::string& rStr) const; |
private: |
uint32_t m_uMask; ///< mask |
uint32_t m_uCookie; ///< cookie |
std::string m_name; ///< name |
InotifyWatch* m_pWatch; ///< source watch |
}; |
/// inotify watch class |
/** |
* It holds information about the inotify watch on a particular |
* inode. |
* |
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe. |
*/ |
class InotifyWatch |
{ |
public: |
/// Constructor. |
/** |
* Creates an inotify watch. Because this watch is |
* inactive it has an invalid descriptor (-1). |
* |
* \param[in] rPath watched file path |
* \param[in] uMask mask for events |
* \param[in] fEnabled events enabled yes/no |
*/ |
InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true) |
: m_path(rPath), |
m_uMask(uMask), |
m_wd((int32_t) -1), |
m_fEnabled(fEnabled) |
{ |
IN_LOCK_INIT |
} |
/// Destructor. |
~InotifyWatch() |
{ |
IN_LOCK_DONE |
} |
/// Returns the watch descriptor. |
/** |
* \return watch descriptor; -1 for inactive watch |
*/ |
inline int32_t GetDescriptor() const |
{ |
return m_wd; |
} |
/// Returns the watched file path. |
/** |
* \return file path |
*/ |
inline const std::string& GetPath() const |
{ |
return m_path; |
} |
/// Returns the watch event mask. |
/** |
* \return event mask |
*/ |
inline uint32_t GetMask() const |
{ |
return (uint32_t) m_uMask; |
} |
/// Sets the watch event mask. |
/** |
* If the watch is active (added to an instance of Inotify) |
* this method may fail due to unsuccessful re-setting |
* the watch in the kernel. |
* |
* \param[in] uMask event mask |
* |
* \throw InotifyException thrown if changing fails |
*/ |
void SetMask(uint32_t uMask) throw (InotifyException); |
/// Returns the appropriate inotify class instance. |
/** |
* \return inotify instance |
*/ |
inline Inotify* GetInotify() |
{ |
return m_pInotify; |
} |
/// Enables/disables the watch. |
/** |
* If the watch is active (added to an instance of Inotify) |
* this method may fail due to unsuccessful re-setting |
* the watch in the kernel. |
* |
* Re-setting the current state has no effect. |
* |
* \param[in] fEnabled set enabled yes/no |
* |
* \throw InotifyException thrown if enabling/disabling fails |
*/ |
void SetEnabled(bool fEnabled) throw (InotifyException); |
/// Checks whether the watch is enabled. |
/** |
* \return true = enables, false = disabled |
*/ |
inline bool IsEnabled() const |
{ |
return m_fEnabled; |
} |
/// Checks whether the watch is recursive. |
/** |
* A recursive watch monitors a directory itself and all |
* its subdirectories. This watch is a logical object |
* which may have many underlying kernel watches. |
* |
* \return currently always false (recursive watches not yet supported) |
* \attention Recursive watches are currently NOT supported. |
* They are planned for future versions. |
*/ |
inline bool IsRecursive() const |
{ |
return false; |
} |
private: |
friend class Inotify; |
std::string m_path; ///< watched file path |
uint32_t m_uMask; ///< event mask |
int32_t m_wd; ///< watch descriptor |
Inotify* m_pInotify; ///< inotify object |
bool m_fEnabled; ///< events enabled yes/no |
IN_LOCK_DECL |
}; |
/// Mapping from watch descriptors to watch objects. |
typedef std::map<int32_t, InotifyWatch*> IN_WATCH_MAP; |
/// Mapping from paths to watch objects. |
typedef std::map<std::string, InotifyWatch*> IN_WP_MAP; |
/// inotify class |
/** |
* It holds information about the inotify device descriptor |
* and manages the event queue. |
* |
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe. |
*/ |
class Inotify |
{ |
public: |
/// Constructor. |
/** |
* Creates and initializes an instance of inotify communication |
* object (opens the inotify device). |
* |
* \throw InotifyException thrown if inotify isn't available |
*/ |
Inotify() throw (InotifyException); |
/// Destructor. |
/** |
* Calls Close() due to clean-up. |
*/ |
~Inotify(); |
/// Removes all watches and closes the inotify device. |
void Close(); |
/// Adds a new watch. |
/** |
* \param[in] pWatch inotify watch |
* |
* \throw InotifyException thrown if adding failed |
*/ |
void Add(InotifyWatch* pWatch) throw (InotifyException); |
/// Adds a new watch. |
/** |
* \param[in] rWatch inotify watch |
* |
* \throw InotifyException thrown if adding failed |
*/ |
inline void Add(InotifyWatch& rWatch) throw (InotifyException) |
{ |
Add(&rWatch); |
} |
/// Removes a watch. |
/** |
* If the given watch is not present it does nothing. |
* |
* \param[in] pWatch inotify watch |
* |
* \throw InotifyException thrown if removing failed |
*/ |
void Remove(InotifyWatch* pWatch) throw (InotifyException); |
/// Removes a watch. |
/** |
* If the given watch is not present it does nothing. |
* |
* \param[in] rWatch inotify watch |
* |
* \throw InotifyException thrown if removing failed |
*/ |
inline void Remove(InotifyWatch& rWatch) throw (InotifyException) |
{ |
Remove(&rWatch); |
} |
/// Removes all watches. |
void RemoveAll(); |
/// Returns the count of watches. |
/** |
* This is the total count of all watches (regardless whether |
* enabled or not). |
* |
* \return count of watches |
* |
* \sa GetEnabledCount() |
*/ |
inline size_t GetWatchCount() const |
{ |
IN_READ_BEGIN |
size_t n = (size_t) m_paths.size(); |
IN_READ_END |
return n; |
} |
/// Returns the count of enabled watches. |
/** |
* \return count of enabled watches |
* |
* \sa GetWatchCount() |
*/ |
inline size_t GetEnabledCount() const |
{ |
IN_READ_BEGIN |
size_t n = (size_t) m_watches.size(); |
IN_READ_END |
return n; |
} |
/// Waits for inotify events. |
/** |
* It waits until one or more events occur. When called |
* in nonblocking mode it only retrieves occurred events |
* to the internal queue and exits. |
* |
* \param[in] fNoIntr if true it re-calls the system call after a handled signal |
* |
* \throw InotifyException thrown if reading events failed |
* |
* \sa SetNonBlock() |
*/ |
void WaitForEvents(bool fNoIntr = false) throw (InotifyException); |
/// Returns the count of received and queued events. |
/** |
* This number is related to the events in the queue inside |
* this object, not to the events pending in the kernel. |
* |
* \return count of events |
*/ |
inline size_t GetEventCount() |
{ |
IN_READ_BEGIN |
size_t n = (size_t) m_events.size(); |
IN_READ_END |
return n; |
} |
/// Extracts a queued inotify event. |
/** |
* The extracted event is removed from the queue. |
* If the pointer is NULL it does nothing. |
* |
* \param[in,out] pEvt event object |
* |
* \throw InotifyException thrown if the provided pointer is NULL |
*/ |
bool GetEvent(InotifyEvent* pEvt) throw (InotifyException); |
/// Extracts a queued inotify event. |
/** |
* The extracted event is removed from the queue. |
* |
* \param[in,out] rEvt event object |
* |
* \throw InotifyException thrown only in very anomalous cases |
*/ |
bool GetEvent(InotifyEvent& rEvt) throw (InotifyException) |
{ |
return GetEvent(&rEvt); |
} |
/// Extracts a queued inotify event (without removing). |
/** |
* The extracted event stays in the queue. |
* If the pointer is NULL it does nothing. |
* |
* \param[in,out] pEvt event object |
* |
* \throw InotifyException thrown if the provided pointer is NULL |
*/ |
bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException); |
/// Extracts a queued inotify event (without removing). |
/** |
* The extracted event stays in the queue. |
* |
* \param[in,out] rEvt event object |
* |
* \throw InotifyException thrown only in very anomalous cases |
*/ |
bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException) |
{ |
return PeekEvent(&rEvt); |
} |
/// Searches for a watch by a watch descriptor. |
/** |
* It tries to find a watch by the given descriptor. |
* |
* \param[in] iDescriptor watch descriptor |
* \return pointer to a watch; NULL if no such watch exists |
*/ |
InotifyWatch* FindWatch(int iDescriptor); |
/// Searches for a watch by a filesystem path. |
/** |
* It tries to find a watch by the given filesystem path. |
* |
* \param[in] rPath filesystem path |
* \return pointer to a watch; NULL if no such watch exists |
* |
* \attention The path must be exactly identical to the one |
* used for the searched watch. Be careful about |
* absolute/relative and case-insensitive paths. |
*/ |
InotifyWatch* FindWatch(const std::string& rPath); |
/// Returns the file descriptor. |
/** |
* The descriptor can be used in standard low-level file |
* functions (poll(), select(), fcntl() etc.). |
* |
* \return valid file descriptor or -1 for inactive object |
* |
* \sa SetNonBlock() |
*/ |
inline int GetDescriptor() const |
{ |
return m_fd; |
} |
/// Enables/disables non-blocking mode. |
/** |
* Use this mode if you want to monitor the descriptor |
* (acquired thru GetDescriptor()) in functions such as |
* poll(), select() etc. |
* |
* \param[in] fNonBlock enable/disable non-blocking mode |
* |
* \throw InotifyException thrown if setting mode failed |
* |
* \sa GetDescriptor() |
*/ |
void SetNonBlock(bool fNonBlock) throw (InotifyException); |
/// Acquires a particular inotify capability/limit. |
/** |
* \param[in] cap capability/limit identifier |
* \return capability/limit value |
* \throw InotifyException thrown if the given value cannot be acquired |
*/ |
static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException); |
/// Modifies a particular inotify capability/limit. |
/** |
* \param[in] cap capability/limit identifier |
* \param[in] val new capability/limit value |
* \throw InotifyException thrown if the given value cannot be set |
* \attention Using this function requires root privileges. |
* Beware of setting extensive values - it may seriously |
* affect system performance and/or stability. |
*/ |
static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException); |
/// Returns the maximum number of events in the kernel queue. |
/** |
* \return maximum number of events in the kernel queue |
* \throw InotifyException thrown if the given value cannot be acquired |
*/ |
inline static uint32_t GetMaxEvents() throw (InotifyException) |
{ |
return GetCapability(IN_MAX_EVENTS); |
} |
/// Sets the maximum number of events in the kernel queue. |
/** |
* \param[in] val new value |
* \throw InotifyException thrown if the given value cannot be set |
* \attention Using this function requires root privileges. |
* Beware of setting extensive values - the greater value |
* is set here the more physical memory may be used for the inotify |
* infrastructure. |
*/ |
inline static void SetMaxEvents(uint32_t val) throw (InotifyException) |
{ |
SetCapability(IN_MAX_EVENTS, val); |
} |
/// Returns the maximum number of inotify instances per process. |
/** |
* It means the maximum number of open inotify file descriptors |
* per running process. |
* |
* \return maximum number of inotify instances |
* \throw InotifyException thrown if the given value cannot be acquired |
*/ |
inline static uint32_t GetMaxInstances() throw (InotifyException) |
{ |
return GetCapability(IN_MAX_INSTANCES); |
} |
/// Sets the maximum number of inotify instances per process. |
/** |
* \param[in] val new value |
* \throw InotifyException thrown if the given value cannot be set |
* \attention Using this function requires root privileges. |
* Beware of setting extensive values - the greater value |
* is set here the more physical memory may be used for the inotify |
* infrastructure. |
*/ |
inline static void SetMaxInstances(uint32_t val) throw (InotifyException) |
{ |
SetCapability(IN_MAX_INSTANCES, val); |
} |
/// Returns the maximum number of inotify watches per instance. |
/** |
* It means the maximum number of inotify watches per inotify |
* file descriptor. |
* |
* \return maximum number of inotify watches |
* \throw InotifyException thrown if the given value cannot be acquired |
*/ |
inline static uint32_t GetMaxWatches() throw (InotifyException) |
{ |
return GetCapability(IN_MAX_WATCHES); |
} |
/// Sets the maximum number of inotify watches per instance. |
/** |
* \param[in] val new value |
* \throw InotifyException thrown if the given value cannot be set |
* \attention Using this function requires root privileges. |
* Beware of setting extensive values - the greater value |
* is set here the more physical memory may be used for the inotify |
* infrastructure. |
*/ |
inline static void SetMaxWatches(uint32_t val) throw (InotifyException) |
{ |
SetCapability(IN_MAX_WATCHES, val); |
} |
private: |
int m_fd; ///< file descriptor |
IN_WATCH_MAP m_watches; ///< watches (by descriptors) |
IN_WP_MAP m_paths; ///< watches (by paths) |
unsigned char m_buf[INOTIFY_BUFLEN]; ///< buffer for events |
std::deque<InotifyEvent> m_events; ///< event queue |
IN_LOCK_DECL |
friend class InotifyWatch; |
static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException); |
}; |
#endif //_INOTIFYCXX_H_ |
/inotify-cxx/tags/inotify-cxx-0.6.0/LICENSE-X11 |
---|
0,0 → 1,22 |
Copyright (c) 2006 Lukas Jelinek |
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
/inotify-cxx/tags/inotify-cxx-0.6.0/README |
---|
0,0 → 1,70 |
inotify C++ interface |
(c) Lukas Jelinek, 2006 |
1. About |
2. Requirements |
3. How to use |
4. Bugs, suggestions |
5. Licensing |
6. Documentation |
======================================================================== |
1. About |
This program is the inotify C++ interface. It is designed for easy use |
of Linux inotify technology in C++ applications. You need not to deal |
with file descriptors and such uncomfortable things. Instead you can |
use a few simple C++ classes. |
2. Requirements |
* Linux kernel 2.6.13 or later (with inotify compiled in) |
* inotify header(s) installed in <INCLUDE_DIR>/sys. The most common |
place is /usr/include/sys. Some Linux distributions contain only |
inotify.h which defines everything needed. But sometimes must |
be used inotify.h and inotify-syscalls.h as available e.g. at |
the inotify-cxx homepage. |
* GCC 4.x compiler (probably works also with GCC 3.4, possibly with |
older versions too) |
3. How to use |
Include inotify-cxx.h into your sources and add inotify-cxx.cpp for |
compiling (e.g. through your makefile). |
If you have installed it into your system-wide include dir (e.g. |
/usr/include), use #include <inotify-cxx.h> or similar. |
Otherwise use #include "inotify-cxx.h". |
For thread-safe behavior, define the INOTIFY_THREAD_SAFE symbol |
(eg. -DINOTIFY_THREAD_SAFE on gcc's command line). See documentation |
for details about thread safety. |
4. Bugs, suggestions |
THIS PROGRAM IS AN ALPHA VERSION. IT PROBABLY CONTAINS BUGS AND |
THEREFORE IT IS NOT INTENDED FOR PRODUCTION USE. |
If you find a bug or have a suggestion how to improve the program, |
please use the bug tracking system at http://bts.aiken.cz. |
5. Licensing |
This program is free software; you can redistribute it and/or |
modify it under the terms of one of the following licenses: |
1. X11 license (see LICENSE-X11) |
2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL) |
3. GNU General Public License, version 2 (see LICENSE-GPL) |
If you want to help with choosing the best license for you, |
please visit http://www.gnu.org/licenses/license-list.html. |
6. Documentation |
The API reference documentation is present in the HTML and man format. |
It was generated using the doxygen program. |
/inotify-cxx/tags/inotify-cxx-0.6.0/LICENSE-GPL |
---|
0,0 → 1,339 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
675 Mass Ave, Cambridge, MA 02139, USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
Appendix: How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) 19yy <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) 19yy name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/inotify-cxx/tags/inotify-cxx-0.6.0/COPYING |
---|
0,0 → 1,13 |
inotify C++ interface |
Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz> |
This program is free software; you can redistribute it and/or |
modify it under the terms of one of the following licenses: |
1. X11 license (see LICENSE-X11) |
2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL) |
3. GNU General Public License, version 2 (see LICENSE-GPL) |
If you want to help with choosing the best license for you, |
please visit http://www.gnu.org/licenses/license-list.html. |
/inotify-cxx/tags/inotify-cxx-0.6.0/LICENSE-LGPL |
---|
0,0 → 1,504 |
GNU LESSER GENERAL PUBLIC LICENSE |
Version 2.1, February 1999 |
Copyright (C) 1991, 1999 Free Software Foundation, Inc. |
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
[This is the first released version of the Lesser GPL. It also counts |
as the successor of the GNU Library Public License, version 2, hence |
the version number 2.1.] |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
Licenses are intended to guarantee your freedom to share and change |
free software--to make sure the software is free for all its users. |
This license, the Lesser General Public License, applies to some |
specially designated software packages--typically libraries--of the |
Free Software Foundation and other authors who decide to use it. You |
can use it too, but we suggest you first think carefully about whether |
this license or the ordinary General Public License is the better |
strategy to use in any particular case, based on the explanations below. |
When we speak of free software, we are referring to freedom of use, |
not price. Our General Public Licenses are designed to make sure that |
you have the freedom to distribute copies of free software (and charge |
for this service if you wish); that you receive source code or can get |
it if you want it; that you can change the software and use pieces of |
it in new free programs; and that you are informed that you can do |
these things. |
To protect your rights, we need to make restrictions that forbid |
distributors to deny you these rights or to ask you to surrender these |
rights. These restrictions translate to certain responsibilities for |
you if you distribute copies of the library or if you modify it. |
For example, if you distribute copies of the library, whether gratis |
or for a fee, you must give the recipients all the rights that we gave |
you. You must make sure that they, too, receive or can get the source |
code. If you link other code with the library, you must provide |
complete object files to the recipients, so that they can relink them |
with the library after making changes to the library and recompiling |
it. And you must show them these terms so they know their rights. |
We protect your rights with a two-step method: (1) we copyright the |
library, and (2) we offer you this license, which gives you legal |
permission to copy, distribute and/or modify the library. |
To protect each distributor, we want to make it very clear that |
there is no warranty for the free library. Also, if the library is |
modified by someone else and passed on, the recipients should know |
that what they have is not the original version, so that the original |
author's reputation will not be affected by problems that might be |
introduced by others. |
Finally, software patents pose a constant threat to the existence of |
any free program. We wish to make sure that a company cannot |
effectively restrict the users of a free program by obtaining a |
restrictive license from a patent holder. Therefore, we insist that |
any patent license obtained for a version of the library must be |
consistent with the full freedom of use specified in this license. |
Most GNU software, including some libraries, is covered by the |
ordinary GNU General Public License. This license, the GNU Lesser |
General Public License, applies to certain designated libraries, and |
is quite different from the ordinary General Public License. We use |
this license for certain libraries in order to permit linking those |
libraries into non-free programs. |
When a program is linked with a library, whether statically or using |
a shared library, the combination of the two is legally speaking a |
combined work, a derivative of the original library. The ordinary |
General Public License therefore permits such linking only if the |
entire combination fits its criteria of freedom. The Lesser General |
Public License permits more lax criteria for linking other code with |
the library. |
We call this license the "Lesser" General Public License because it |
does Less to protect the user's freedom than the ordinary General |
Public License. It also provides other free software developers Less |
of an advantage over competing non-free programs. These disadvantages |
are the reason we use the ordinary General Public License for many |
libraries. However, the Lesser license provides advantages in certain |
special circumstances. |
For example, on rare occasions, there may be a special need to |
encourage the widest possible use of a certain library, so that it becomes |
a de-facto standard. To achieve this, non-free programs must be |
allowed to use the library. A more frequent case is that a free |
library does the same job as widely used non-free libraries. In this |
case, there is little to gain by limiting the free library to free |
software only, so we use the Lesser General Public License. |
In other cases, permission to use a particular library in non-free |
programs enables a greater number of people to use a large body of |
free software. For example, permission to use the GNU C Library in |
non-free programs enables many more people to use the whole GNU |
operating system, as well as its variant, the GNU/Linux operating |
system. |
Although the Lesser General Public License is Less protective of the |
users' freedom, it does ensure that the user of a program that is |
linked with the Library has the freedom and the wherewithal to run |
that program using a modified version of the Library. |
The precise terms and conditions for copying, distribution and |
modification follow. Pay close attention to the difference between a |
"work based on the library" and a "work that uses the library". The |
former contains code derived from the library, whereas the latter must |
be combined with the library in order to run. |
GNU LESSER GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License Agreement applies to any software library or other |
program which contains a notice placed by the copyright holder or |
other authorized party saying it may be distributed under the terms of |
this Lesser General Public License (also called "this License"). |
Each licensee is addressed as "you". |
A "library" means a collection of software functions and/or data |
prepared so as to be conveniently linked with application programs |
(which use some of those functions and data) to form executables. |
The "Library", below, refers to any such software library or work |
which has been distributed under these terms. A "work based on the |
Library" means either the Library or any derivative work under |
copyright law: that is to say, a work containing the Library or a |
portion of it, either verbatim or with modifications and/or translated |
straightforwardly into another language. (Hereinafter, translation is |
included without limitation in the term "modification".) |
"Source code" for a work means the preferred form of the work for |
making modifications to it. For a library, complete source code means |
all the source code for all modules it contains, plus any associated |
interface definition files, plus the scripts used to control compilation |
and installation of the library. |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running a program using the Library is not restricted, and output from |
such a program is covered only if its contents constitute a work based |
on the Library (independent of the use of the Library in a tool for |
writing it). Whether that is true depends on what the Library does |
and what the program that uses the Library does. |
1. You may copy and distribute verbatim copies of the Library's |
complete source code as you receive it, in any medium, provided that |
you conspicuously and appropriately publish on each copy an |
appropriate copyright notice and disclaimer of warranty; keep intact |
all the notices that refer to this License and to the absence of any |
warranty; and distribute a copy of this License along with the |
Library. |
You may charge a fee for the physical act of transferring a copy, |
and you may at your option offer warranty protection in exchange for a |
fee. |
2. You may modify your copy or copies of the Library or any portion |
of it, thus forming a work based on the Library, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) The modified work must itself be a software library. |
b) You must cause the files modified to carry prominent notices |
stating that you changed the files and the date of any change. |
c) You must cause the whole of the work to be licensed at no |
charge to all third parties under the terms of this License. |
d) If a facility in the modified Library refers to a function or a |
table of data to be supplied by an application program that uses |
the facility, other than as an argument passed when the facility |
is invoked, then you must make a good faith effort to ensure that, |
in the event an application does not supply such function or |
table, the facility still operates, and performs whatever part of |
its purpose remains meaningful. |
(For example, a function in a library to compute square roots has |
a purpose that is entirely well-defined independent of the |
application. Therefore, Subsection 2d requires that any |
application-supplied function or table used by this function must |
be optional: if the application does not supply it, the square |
root function must still compute square roots.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Library, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Library, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote |
it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Library. |
In addition, mere aggregation of another work not based on the Library |
with the Library (or with a work based on the Library) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may opt to apply the terms of the ordinary GNU General Public |
License instead of this License to a given copy of the Library. To do |
this, you must alter all the notices that refer to this License, so |
that they refer to the ordinary GNU General Public License, version 2, |
instead of to this License. (If a newer version than version 2 of the |
ordinary GNU General Public License has appeared, then you can specify |
that version instead if you wish.) Do not make any other change in |
these notices. |
Once this change is made in a given copy, it is irreversible for |
that copy, so the ordinary GNU General Public License applies to all |
subsequent copies and derivative works made from that copy. |
This option is useful when you wish to copy part of the code of |
the Library into a program that is not a library. |
4. You may copy and distribute the Library (or a portion or |
derivative of it, under Section 2) in object code or executable form |
under the terms of Sections 1 and 2 above provided that you accompany |
it with the complete corresponding machine-readable source code, which |
must be distributed under the terms of Sections 1 and 2 above on a |
medium customarily used for software interchange. |
If distribution of object code is made by offering access to copy |
from a designated place, then offering equivalent access to copy the |
source code from the same place satisfies the requirement to |
distribute the source code, even though third parties are not |
compelled to copy the source along with the object code. |
5. A program that contains no derivative of any portion of the |
Library, but is designed to work with the Library by being compiled or |
linked with it, is called a "work that uses the Library". Such a |
work, in isolation, is not a derivative work of the Library, and |
therefore falls outside the scope of this License. |
However, linking a "work that uses the Library" with the Library |
creates an executable that is a derivative of the Library (because it |
contains portions of the Library), rather than a "work that uses the |
library". The executable is therefore covered by this License. |
Section 6 states terms for distribution of such executables. |
When a "work that uses the Library" uses material from a header file |
that is part of the Library, the object code for the work may be a |
derivative work of the Library even though the source code is not. |
Whether this is true is especially significant if the work can be |
linked without the Library, or if the work is itself a library. The |
threshold for this to be true is not precisely defined by law. |
If such an object file uses only numerical parameters, data |
structure layouts and accessors, and small macros and small inline |
functions (ten lines or less in length), then the use of the object |
file is unrestricted, regardless of whether it is legally a derivative |
work. (Executables containing this object code plus portions of the |
Library will still fall under Section 6.) |
Otherwise, if the work is a derivative of the Library, you may |
distribute the object code for the work under the terms of Section 6. |
Any executables containing that work also fall under Section 6, |
whether or not they are linked directly with the Library itself. |
6. As an exception to the Sections above, you may also combine or |
link a "work that uses the Library" with the Library to produce a |
work containing portions of the Library, and distribute that work |
under terms of your choice, provided that the terms permit |
modification of the work for the customer's own use and reverse |
engineering for debugging such modifications. |
You must give prominent notice with each copy of the work that the |
Library is used in it and that the Library and its use are covered by |
this License. You must supply a copy of this License. If the work |
during execution displays copyright notices, you must include the |
copyright notice for the Library among them, as well as a reference |
directing the user to the copy of this License. Also, you must do one |
of these things: |
a) Accompany the work with the complete corresponding |
machine-readable source code for the Library including whatever |
changes were used in the work (which must be distributed under |
Sections 1 and 2 above); and, if the work is an executable linked |
with the Library, with the complete machine-readable "work that |
uses the Library", as object code and/or source code, so that the |
user can modify the Library and then relink to produce a modified |
executable containing the modified Library. (It is understood |
that the user who changes the contents of definitions files in the |
Library will not necessarily be able to recompile the application |
to use the modified definitions.) |
b) Use a suitable shared library mechanism for linking with the |
Library. A suitable mechanism is one that (1) uses at run time a |
copy of the library already present on the user's computer system, |
rather than copying library functions into the executable, and (2) |
will operate properly with a modified version of the library, if |
the user installs one, as long as the modified version is |
interface-compatible with the version that the work was made with. |
c) Accompany the work with a written offer, valid for at |
least three years, to give the same user the materials |
specified in Subsection 6a, above, for a charge no more |
than the cost of performing this distribution. |
d) If distribution of the work is made by offering access to copy |
from a designated place, offer equivalent access to copy the above |
specified materials from the same place. |
e) Verify that the user has already received a copy of these |
materials or that you have already sent this user a copy. |
For an executable, the required form of the "work that uses the |
Library" must include any data and utility programs needed for |
reproducing the executable from it. However, as a special exception, |
the materials to be distributed need not include anything that is |
normally distributed (in either source or binary form) with the major |
components (compiler, kernel, and so on) of the operating system on |
which the executable runs, unless that component itself accompanies |
the executable. |
It may happen that this requirement contradicts the license |
restrictions of other proprietary libraries that do not normally |
accompany the operating system. Such a contradiction means you cannot |
use both them and the Library together in an executable that you |
distribute. |
7. You may place library facilities that are a work based on the |
Library side-by-side in a single library together with other library |
facilities not covered by this License, and distribute such a combined |
library, provided that the separate distribution of the work based on |
the Library and of the other library facilities is otherwise |
permitted, and provided that you do these two things: |
a) Accompany the combined library with a copy of the same work |
based on the Library, uncombined with any other library |
facilities. This must be distributed under the terms of the |
Sections above. |
b) Give prominent notice with the combined library of the fact |
that part of it is a work based on the Library, and explaining |
where to find the accompanying uncombined form of the same work. |
8. You may not copy, modify, sublicense, link with, or distribute |
the Library except as expressly provided under this License. Any |
attempt otherwise to copy, modify, sublicense, link with, or |
distribute the Library is void, and will automatically terminate your |
rights under this License. However, parties who have received copies, |
or rights, from you under this License will not have their licenses |
terminated so long as such parties remain in full compliance. |
9. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Library or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Library (or any work based on the |
Library), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Library or works based on it. |
10. Each time you redistribute the Library (or any work based on the |
Library), the recipient automatically receives a license from the |
original licensor to copy, distribute, link with or modify the Library |
subject to these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties with |
this License. |
11. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Library at all. For example, if a patent |
license would not permit royalty-free redistribution of the Library by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Library. |
If any portion of this section is held invalid or unenforceable under any |
particular circumstance, the balance of the section is intended to apply, |
and the section as a whole is intended to apply in other circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
12. If the distribution and/or use of the Library is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Library under this License may add |
an explicit geographical distribution limitation excluding those countries, |
so that distribution is permitted only in or among countries not thus |
excluded. In such case, this License incorporates the limitation as if |
written in the body of this License. |
13. The Free Software Foundation may publish revised and/or new |
versions of the Lesser General Public License from time to time. |
Such new versions will be similar in spirit to the present version, |
but may differ in detail to address new problems or concerns. |
Each version is given a distinguishing version number. If the Library |
specifies a version number of this License which applies to it and |
"any later version", you have the option of following the terms and |
conditions either of that version or of any later version published by |
the Free Software Foundation. If the Library does not specify a |
license version number, you may choose any version ever published by |
the Free Software Foundation. |
14. If you wish to incorporate parts of the Library into other free |
programs whose distribution conditions are incompatible with these, |
write to the author to ask for permission. For software which is |
copyrighted by the Free Software Foundation, write to the Free |
Software Foundation; we sometimes make exceptions for this. Our |
decision will be guided by the two goals of preserving the free status |
of all derivatives of our free software and of promoting the sharing |
and reuse of software generally. |
NO WARRANTY |
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO |
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. |
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY |
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE |
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME |
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN |
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY |
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU |
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Libraries |
If you develop a new library, and you want it to be of the greatest |
possible use to the public, we recommend making it free software that |
everyone can redistribute and change. You can do so by permitting |
redistribution under these terms (or, alternatively, under the terms of the |
ordinary General Public License). |
To apply these terms, attach the following notices to the library. It is |
safest to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least the |
"copyright" line and a pointer to where the full notice is found. |
<one line to give the library's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Also add information on how to contact you by electronic and paper mail. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the library, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the |
library `Frob' (a library for tweaking knobs) written by James Random Hacker. |
<signature of Ty Coon>, 1 April 1990 |
Ty Coon, President of Vice |
That's all there is to it! |