The vsound program uses a very interesting if unusual technique
to carry out its work. Linux and other unix-like systems allow
functions in a shared library to be overridden without having
to replace the whole library. This is done by writing a new
shared library which contains the definitions of the functions
you wish to override. In addition, by the use of the dlsym()
function, it is still possible to call the original function
by use of a function pointer.
In the case of vsound, the functions which need to be overridden
are; open(), ioctl(), write() and close(). By overridding these
functions, it is possible to detect all attempts to open the
/dev/dsp device. From there on, all ioctl() calls on
this device are recorded to a file which can later be used to
determine the data format of the file being played. In addition,
the standard write() function is also overridden so that all
audio data written to the audio device is also written to a
temporary file. Similarly, the close() function is overridden
so we know when to close the file containing the captured audio
data.
The functions we wish to override are gathered together in shared
library called libvsound.so. The other part of the vsound system
is a shell script called vsound. This shell script uses the
LD_PRELOAD variable to tell the system to preload libvsound.so
and then run the target program with all its command line arguments.
When the target program terminates, the vsound shell script
uses SoX to convert the AU format file into a WAV file named
vsound.wav in the current directory.