In this last example, we illustrate how to extend I/O services to encrypt and decrypt the data stream. Given the appropriate encryption algorithm, the extension should simply provide the routines that combine in the right order the encryption/decryption process and the I/O operation:
int crypt_read(int fd, char *b, int len)
{
int r;
r = read(fd, b, len);
if (encrypted_channel(fd))
decrypt(b, r);
return(r);
}
int crypt_write(int fd, char *b, int len)
{
int r;
if (encrypted_channel(fd))
crypt(b, len);
r = write(fd, b, len);
return(r);
}
These routines can be used to redefine previous read/write services. To make encryption transparent to the program, channels to be encrypted can be determined by the extension. For example, it can decide to encrypt only those data streams that are sent or received from the network.