Writing a unix daemon using C++, the idea might seem odd. But it’s desirable in many ways :
- C++ provides a lot of methods which are inherently safe and neat regarding string treatments,
- STL(sgi) provides a lot of nice containers, particularly the associative map,
- convenient simple text input/output using iostream …
Now, coding a daemon implies a lot of very unix-native C details such as : properly detach from terminals, output some errors via syslog …
When one realises all those functionnalites have simple posix-C functions to take care of, a very convenient bridge from C to C++ is to bind a regular iostream to a FILE* descriptor.
Example : reading from a pipe using istream
The below posix-C function :
FILE *popen(const char *command, const char *type);
provides a very simple way to fork and read to (or write from) another process. The gnu iostream library documentation mentions some methods usable to turn FILE* into stream, but I would not say the said documentation made it straighforward. So here’s an example of such a pipe :
#include <errno.h> #include <string.h> // strerror #include <iostream> #include <ext/stdio_filebuf.h> // __gnu_cxx::stdio_filebuf using namespace std; void filter_uggly_uppercase (istream &in, ostream &out) { char c; while (in && in.get(c)) { if ((c>='a') && (c<='z')) out << (char)('A' - 'a' + c); else out << c; } } int main (void) { const char *command = "find . -type f"; FILE *f_pipe_in = popen (command, "r"); if (f_pipe_in == NULL) { int e = errno; cerr << "error at piping from " << command << " : " << strerror (e) << endl; return 1; } // let's build a buffer from the FILE* descriptor ... __gnu_cxx::stdio_filebuf<char> pipe_buf (f_pipe_in, ios_base::in); // there we are, a regular istream is build upon the buffer : istream stream_pipe_in (&pipe_buf); // let's read from that pipe now, the usual way ... filter_uggly_uppercase (stream_pipe_in, cout); pclose (f_pipe_in); return 0; }