Cross platform C++ filesystem watcher - c++

I'm looking for a cross platform file system watcher, similar to the FileSystemWatcher class in .NET. As it's for a daemon/service, I'm not keen on Qt's QFileSystemWatcher. I'd really like to avoid it as I don't want to have a dependency on Qt as my program is going to be a daemon.
I've also seen a proposal for such a class to be included in Boost, but as far as I know such a class has not yet been included.
Is there a cross platform C++ file system watcher?

Qt is divided into modules, so using this feature doesn't mean you have to use the GUI library.
QFileSystemWatcher is in QtCore, which has no GUI functionality.

I have not used this (I came to this question looking for alternatives), but http://code.google.com/p/simplefilewatcher seems to be a good option. It is not currently maintained, but the relevant APIs are probably fairly stable. I'll try to remember to update this answer if I use this library.

As an alternative there is also "Entropia File System Watcher"
https://bitbucket.org/SpartanJ/efsw which is a fork of the simple-file-watcher.
efsw currently supports the following platforms:
Linux via inotify
Windows via I/O Completion Ports
Mac OS X via FSEvents or kqueue
FreeBSD/BSD via kqueue
OS-independent generic watcher (polling the disk for directory
snapshots and comparing them periodically)
If any of the backend fails to start by any reason, it will fallback
to the OS-independent implementation.

For completeness sake, it is also worth mentioning Poco's DirectoryWatcher.

Related

Adding Qt to a C-Socket program?

I am working on a simple socket application written in C, which allows two members to communicate over the internet using basic command line prompt.
I would like to add a proper GUI to it, just to use a decent UI and not basic standard input/output.
Right now I am developing with Cygwin to use POSIX threads and sockets. Is there anyway to hook it up to Qt?
As Shawn mentioned above, using Qt entails the use of an object-based language (probably C++ in your case). But there's another consideration -- Qt is a multi-platform framework; it can be thought of as a layer between your application and the OS it runs on. So, while the literal answer to your question is "yes," if you're going to use Qt for its UI abilities, you're better off (IMO) using its socket facility QAbstractSocket as well, rather than use the native (or Cygwin) socket API.

Creating many native GUI frontends for a cross-platform application

I've been away from GUI programming for quite some time so please pardon my ignorance.
I would like to attempt the following:
Write a Mac OSX app but still be able to port to Win/Linux (i.e. C++ core with Obj-C GUI)
Avoid Qt/other toolkits on OSX (i.e. talk to Cocoa directly - I feel that many Qt apps I use stick out like sore thumbs compared to the rest of my system)
Not as important, but it would be nice to avoid Visual Studio if it means I can have the freedom to use newer C++ features even on Windows if they help create better code.
I believe this configuration might get me what I'm looking for:
Core C++ Static Library
OSX GUI (Cocoa)
Windows GUI (Qt+MinGW?) OR (no new C++ features, Visual Studio + ManagedC++/C#/????)
Linux GUI (Qt)
Once again, sorry for my ignorance but is this possible? Is this sane? Are there any real-world open source examples accomplish something like this?
There is quite a few OS X applications that have completely custom-designed looks that don't use very many stock controls. iStat Menus comes to mind, but there are many other examples. They still look good, but it's done by manually designing them to look good and to "mesh" with the overall look of OS X applications. Even their preferences pane doesn't use stock buttons.
Thus, you can go quite far using Qt, you just have to pay close attention to what you're doing - similarly to the way other developers are paying close attention even when using Cocoa. You'll find that Qt's controls offer functionality often above and beyond what's offered in Cocoa.
That said, on OS X sometimes you may need to run some native code that expects a CFRunLoop to be present. It's good to know that Qt's event loop already spins a runloop for you, so as long as you have an event loop spinning in a given thread, you can use runloop-based code - the default runloop is provided by Qt's implementation of QEventDispatcher (somewhere in its guts). For non-gui threads, the unmodified QThread does it for you. This is useful for using asynchronous IOKit functionality, for example. Another answer of mine presents some Cocoa mouse event grabbing code. A previous version that used Carbon can be found in the edit history of that answer.
Same goes for Windows: Qt runs a message sink for all top-level windows it owns, and you can integrate native controls/windows using qtwinmigrate. You can also integrate ActiveX controls using the Active Qt framework.
Well I think you should try Qt even on OSX. Qt allows native/custom look of applications (those cases you mentioned are probably bad examples - you probably haven't noticed that lots of other applications also use Qt).
Tools I usually use for multi-platform development:
C++ (now C++11 since all major compilers more or less support it)
Boost
Qt
CMake as build system generator
If you use this tool-set you can choose whichever platform you like for development and still be multi-platform without extensive work on the other platforms.

Alternatives to inotify to detect when a new file is created under a folder

I am developing my program on Linux, is there a programmatic way to detect when another application creates/copies a file under/to a specific folder. I want to detect the new file as fast as it is created and I would like to process the file.
As far as I researched I can accomplish this using inotify. Are there any better alternatives?
inotify is the proper API provided by the Linux kernel. Your toolkit may have convenience on top of it, e.g. KDirWatch from libkdecore, but that uses inotify internally.
Using API from a toolkit is a good idea when your program is cross-platform.
http://www.highscore.de/boost/dir_monitor.zip on http://en.highscore.de/cpp/boost/asio.html is a cross-platform C++ Boost solution, though I haven't tried it yet.
http://boost.2283326.n4.nabble.com/ASIO-file-monitoring-help-td4645105.html has code using it that is wrong, the fix looks to be to make a few more objects the author assumed could be temporary permanent instead.
http://man7.org/linux/man-pages/man7/fanotify.7.html is another option
This is a nice article which sums all methods http://www.lanedo.com/filesystem-monitoring-linux-kernel/

Logging facilities and Qt

What logging facilities do you use whit Qt ?
Do you choose qDebug(), qWarning(), qCritical(), qFatal() methods, or maybe something like Log4cpp (Log4cplus etc.), or maybe some custom-maked code ?
If you are just working in a single thread, qDebug and such work pretty well, or you can modify them somewhat by installing your own handler with qInstallMessageHandler in QT 5.0+, or qInstallMsgHandler in old versions.
Note: Older versions of qDebug() etc., where you used qInstallMsgHandler (now deprecated, e.g. http://doc.qt.io/archives/4.6/qtglobal.html#qDebug) were not thread-safe. If you use threads, they would crash/break badly. Internally it was using QTextStream, which was reentrant, but not thread-safe.
Since Qt 5.2 supports categorized logging: http://qt-project.org/doc/qt-5/qloggingcategory.html . This allows you to split up your logging messages into a (hierarchy of) categories, and fine tune which is logged, and what not.
Existing C++ logging libraries are too heavy for my tastes, so I have created a custom front-end based on ideas from Logging in C++ for the Qt qInstallMsgHandlerq back-end. It's cross-platform and thread-safe. Someday I'll clean up the code and release it to the world :)
An interesting alternative for Qt is QxtLogger.
Log4Qt is a port of famous log4j to the Qt world.
QDebug is the best way to go, as it presents out-of-the-box integration with the rest of the framework, doesn't make you dependent on 3rd party code and covers pretty all of the logging needs.
I'm not using Qt, but for logging I'm using a modified version of Dr'Dobb's Logging in C++. The original code can be found here.
My modifications are specific to the Microsoft Windows platform (fopen doesn't allow file read sharing) and can be found here.
Regarding the answer saying "Unfortunately qDebug() etc. are not thread-safe. If you use threads, they will crash/break badly. Internally it uses QTextStream, which is reentrant, but not thread-safe."
I seriously doubt that, qDebug is designed to be used concurrently. File a bug if that isn't true.
Depends on how you want to use that log data.
If it is used for debugging at runtime, qWarning() would do just fine.
If you need to debug retrospective (usually server side code), plain old text files are the best. It is best to organize these log files by day log is written.
You can have a look at: https://github.com/netresultsit/uniqlogger
LGPL
thread-safe
multiple backends: file, colored console, network, rsyslog
file rotation by size and number of files
support compression of previous files
etc.

How to be notified of file/directory change in C/C++, ideally using POSIX

The subject says it all - normally easy and cross platform way is to poll, intelligently. But every OS has some means to notify without polling. Is it possible in a reasonably cross platform way? (I only really care about Windows and Linux, but I use mac, so I thought posix may help?)
Linux users can use inotify
inotify is a Linux kernel subsystem
that provides file system event
notification.
Some goodies for Windows fellows:
File Change Notification on MSDN
"When Folders Change" article
File System Notification on Change
The Qt library has a QFileSystemWatcher class which provides cross platform notifications when a file changes. Even if you are not using Qt, because the source is available you could have a look at it as a sample for your own implementation. Qt has separate implementations for Windows, Linux and Mac.
There's File System Events API as of Leopard.
I don't think POSIX itself has facilities for that. The closest to cross-platform I've seen is FAM, which seems to work for Linux, BSD, and Irix, but I'm not how easy it would be to port it to Windows and MacOS.
I've actually built this system before for use in a commercial C++ code base- as long as you don't need every weird thing under the sun, the Windows and POSIX systems have a lot of overlap you can abstract.
POSIX: Use inotify- it is a whole system literally built for this job
Windows: Use "change events". You have to build more of the glue and reporting yourself (all the APIs you need are available, there's just not the 1-stop-shopping inotify gives you).
The common things you can detect in your "notification thread" for forwarding events are:
1) Basically any invasive operation boost::filesystem supports, with the (possible) exception of modifying permissions. This is things like moving, creating, deleting, copying folders and files.
2) Reads and writes to files (esp. writes). Be aware that if you're using async I/O the notifications can show up out-of-order.
3) When a new volume comes in, such as somebody connecting a flash drive.
inotify especially gives you an insane level of fine-grained control, Windows less so. With inotify you can literally monitor everything the filesystem is doing in near-real time if you really want to. I know #3 is possible with both without polling, but be aware that it can be really tricky to get it working correctly- on either system.
I believe OS X now has appropriate hooks/callbacks because they were needed for Spotlight indexing.
On linux you'll have the additional trouble that there are multiple file systems commonly used. If you need the functionality for only a limited amount of files/directories, I'd try about actively looking for modifications at regular intervals.
libevent or libev seem to be what you want, though I haven't used them.