If stat fails we simply return false, rather than throwing an error, we also clear any errno's that may have been set. We don't want to have to wrap is_dir(std::string) in try/catch's all over our code, especially since the return code is just supposed to tell us whether it is a directory or not!
This adds the copy and assignment operators for dspawn::directory, the defaults would probably have been okay, but I prefer being explicit about it.
I had been attempting to stick with make in an attempt to keep dependencies for building down to a minimum, however make was not nearly as flexible as I had hoped and was causing me to write so many extra entries that it was not worth my time and effort to continue to try bending make to my will. This also imports Google test into the tree and starts adding test cases.
We take the content of the struct dirent* and store it locally in variables that exist for the lifetime of the object rather than what may possibly be statically allocated memory. Also add in two operators, one to check if the two directory_entries are equal, the other to see if they are not equal (just calls the equality operator for its operation and negates it). This allows it to be used to see if two iterators are equal or not. The only two fields we pull out are the name and the file number, as those are the only two portable entries in a struct dirent*.
This also fixes a couple of issues: 1. When we reached the end of a directory were were creating an empty directory_entry, which doesn't make sense since the end iterator has those set to 0's anyway and thus comparing a null ptr to an otherwise empty object doesn't make much sense. 2. Fixes the operator!=, removes the old one that was created as a temporary place holder, and makes sure that proper checking is done for inequality.
This captures the errno and then uses it as a message when it gets thrown this way we can start tracking when and where we are hitting error numbers. We may also want to start adding a way to get the error number along-side of the message like what() does so that we can check later down the exception handling chain what happened, although for now it is strictly for errors that can not be "handled" and probably should cause the app to crash or error out at least. This class is now used everywhere there were TODO's in directory.cc.
A lot of the difficult work has moved to the iterators, each time you create a new iterator it will do the opendir and keep track of where it is, rather than the base class. The base class has basically become an empty shell that checks that you are trying to look at a directory and then allows you to create iterators. The reason this was done is so that if you have multiple iterators to the same directory they don't keep overwriting each others results because of the way that opendir/readdir/seekdir/and others work. These itererators are kind of special though, there is no container backing them, so that means that each time you start from the beginning, you start from scratch with a completely new opendir/readdir cycle. Hopefully the OS caching the results will be enough.
This wrapper is meant to wrap some of the functionality of opendir and friends. The reason why I want to wrap it is to provide iterators that make it easier to deal with directories which are going to playing a major part in the way services are going to be managed by dspawn.
We set up the umask to be 0 so that any process we spawn will have to explicitly set their own, and we set up the daemon to be running within the service directory. This way so long as the daemon is running nobody can unmount the service directory out from under our nose.
Start with some very basic options parsing for the program. Add some simple defaults like -B and -d for backgrounding and increasing the debug level respectively. Also, we have one positional argument that is the service directory for where we are to start looking for services to start.