next up previous
Next: Implementing selectable Devices Up: Implementing Blocking System Calls Previous: Using fusd_destroy() to clean

Retrieving a blocked system call's arguments from a fusd_file_info pointer

In the previous section, we showed how the fusd_return function can be used to specify the return value of a system call that was previously blocked. However, many system calls have side effects in addition to returning a value--for example, in a read() request, the data being returned has to be copied into the caller's buffer. To facilitate this, FUSD provides accessor functions that let drivers retrieve the arguments that had been passed to its callbacks at the time the call was originally issued. For example, the fusd_get_read_buffer() function will return a pointer to the data buffer that is provided with read() callbacks. Drivers can use these accessor functions to affect change to a client before calling fusd_return().

The following accessor functions are available, all of which take a single fusd_file_info * argument:

We got away without using these accessor functions in our pager.c example because the pager doesn't actually return data--it just blocks and unblocks read calls. However, the FUSD distribution contains another example program, logring, that demonstrates their use.

logring makes it easy to access the most recent (and only the most recent) output from a process. It works just like tail -f on a log file, except that the storage required never grows. This can be useful in embedded systems where there isn't enough memory or disk space for keeping complete log files, but the most recent debugging messages are sometimes needed (e.g., after an error is observed).

logring uses FUSD to implement a character device, /dev/logring, that acts like a named pipe that has a finite, circular buffer. The size of the buffer is given as a command-line argument. As more data is written into the buffer, the oldest data is discarded. A process that reads from the logring device will first read the existing buffer, then block and see new data as it's written, similar to monitoring a log file using tail -f.

You can run this example program by typing logring <logsize>, where logsize is the size of the circular buffer in bytes. Then, type cat /dev/logring in a shell. The cat process will block, waiting for data. From another shell, write to the logring (e.g., echo Hi there > /dev/logring). The cat process will see the message appear.

(This example program is based on emlog, a (real) Linux kernel module with identical functionality. If you find logring useful, but want to use it on a system that does not have FUSD, check out the original emlog.)


next up previous
Next: Implementing selectable Devices Up: Implementing Blocking System Calls Previous: Using fusd_destroy() to clean
Jeremy Elson 2003-08-20