Changes to the folder watcher system

Now that you have completed the first version of the folder watcher system it is time to construct a more full-featured second version. In this exercise you will construct a second version of the folder watcher system that is designed to run on a Linux system alongside other applications.

What your second version will do

The first noticable change in version two is that this time instead of constructing separate fw and fwd applications you will only be constructing the fwd application. When this application starts it will fork() and put itself in the background where it can run as a server application.

The second significant change is that we are going to rewrite the application so that it can keep watch over multiple folders instead of just one. To enable this feature we are going to be using threads in fwd, with one thread per watched folder. When the application starts up it will read a list of folders to watch from a configuration file instead of reading a single folder path from the command line.

Finally, we will have the application respond to signals so that it can shut down gracefully when we tell the application to shut down.

The specifics

Here are some specific things you will need to do in version two:

1. As soon as the application starts it will need to do a fork(). After forking, the parent process will save the process id of the child process to a file /run/fwd.pid and then exit, while the child process (which now runs in the background) will continue running.

2. When fwd starts it will open a configuration file located at /etc/fwd.conf. The configuration file will contain several lines, with each line having the format

<tag> <path>

where <tag> is a tag assigned to a folder and <path> is the full path to the folder. For example, a line may read

projectOne /home/joe/480/miniweb

3. At startup fwd will also open a log file located at /var/log/fwd.log.

4. Before starting any threads, call pthread_sigmask() to block the SIGTERM signal.

5. For each line in the configuration file fwd will start a thread that keeps watch over that particular folder. You should pass both the tag name and the path to the thread. That thread will be responsible for logging changes it sees in that folder to the log file.

6. Just as in the first version, each thread will run a scan in its folder every five minutes. When a thread notices that a file in its watch folder has been recently modified, it will write a line to the log file that takes the form

<tag> <filename> <modification time>

where <tag> is the tag the thread is using and <filename> is the name of the modified file.

Since you are going to have multiple threads all wanting to write to the same log file, you should write a function that the threads can call to write a log entry. That function should make use of a mutex to make sure that at most one thread at a time can write to the log.

7. After launching the threads to watch the folders, the main function in fwd should call sigwait() to wait for the SIGTERM signal. Upon receiving that signal fwd should close the log file, stop all of the running threads, and then exit.

You should not make any assumptions about the number of lines in the configuration file. Instead, you should start by counting the number of newline characters in the fwd.conf file: the number of threads you will need to launch is one greater than the number of newlines. Once you know the number of threads you will need to launch you can use malloc() to make an array of that many pthread_t elements. You can then use that array to store the thread ids for the threads you create.