The FUSD library provides two (optional) utility functions that can make it easier to write applications that integrate FUSD into their own select() loops. Specifically:
The excerpt of drums3.c shown in Program 9 demonstrates the use of these helper functions. This program is similar to the earlier drums.c example: it creates a number of musical instruments such as /dev/drums/bam and /dev/drums/boom. However, in addition to servicing its musical callbacks, the driver also prints a prompt to standard input asking how ``loud'' the drums should be. Instead of turning control of main() over to fusd_run() as in the previous examples, drums3 uses select() to simultaneously watch its FUSD file descriptors and standard input. It responds to input from both sources.
On lines 2-5, an fd_set and its associated ``max'' value are initialized to contain stdin's file descriptor. On line 9, we use fusd_fdset_add to add the FUSD file descriptors for all registered devices. (Not shown in this excerpt is the device registration, which is the same as the registration code we saw in drums.c.) On line 13 we call select, which blocks until one of the fd's in the set is readable. On lines 17 and 18, we check to see if standard input is readable; if so, a function is called which reads the user's response from standard input and prints a new prompt. Finally, on line 21, we call fusd_dispatch_fdset, which in turn will activate the callbacks for devices that have pending system calls waiting to be serviced.
It's worth reiterating that drivers are not required to use the FUSD helper functions fusd_fdset_add and fusd_dispatch_fdset. If it's more convenient, a driver can manually save all of the file descriptors returned by fusd_register, construct its own fd_set, and then call fusd_dispatch on each descriptor that is readable. This method is sometimes required for integration with other frameworks that want to take over your main(). For example, the GTK user interface framework is event-driven and requires that you pass control of your main to it. However, it does allow you to give it a file descriptor and a function pointer, saying ``Call this callback when select indicates this file descriptor has become readable.'' A GTK application that implements FUSD devices can work by giving GTK all the FUSD file descriptors individually, and calling fusd_dispatch() when GTK calls the associated callbacks.