/* Called when the /proc file is closed */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
int module_close(struct inode *inode, struct file *file)
#else
void module_close(struct inode *inode, struct file *file)
#endif
{
/* Set Already_Open to zero, so one of the processes
* in the WaitQ will be able to set Already_Open back
* to one and to open the file. All the other processes
* will be called when Already_Open is back to one, so
* they'll go back to sleep. */
Already_Open = 0;
/* Wake up all the processes in WaitQ, so if anybody
* is waiting for the file, they can have it. */
module_wake_up(&WaitQ);
MOD_DEC_USE_COUNT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
return 0; /* success */
#endif
}
/* This function decides whether to allow an operation
* (return zero) or not allow it (return a non-zero
* which indicates why it is not allowed).
*
* The operation can be one of the following values:
* 0 - Execute (run the "file" - meaningless in our case)
* 2 - Write (input to the kernel module)
* 4 - Read (output from the kernel module)
*
* This is the real function that checks file
* permissions. The permissions returned by ls -l are
* for referece only, and can be overridden here. */
static int module_permission(struct inode *inode, int op) {
/* We allow everybody to read from our module, but
* only root (uid 0) may write to it */
if (op == 4 || (op == 2 && current->euid == 0)) return 0;
/* If it's anything else, access is denied */
return -EACCES;
}
/* Structures to register as the /proc file, with
* pointers to all the relevant functions. *********** */
/* File operations for our proc file. This is where
* we place pointers to all the functions called when
* somebody tries to do something to our file. NULL
* means we don't want to deal with something. */
static struct file_operations File_Ops_4_Our_Proc_File = {
NULL, /* lseek */
module_output, /* "read" from the file */
module_input, /* "write" to the file */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
module_open,/* called when the /proc file is opened */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
NULL, /* flush */
#endif
module_close /* called when it's classed */
};
/* Inode operations for our proc file. We need it so
* we'll have somewhere to specify the file operations
* structure we want to use, and the function we use for
* permissions. It's also possible to specify functions
* to be called for anything else which could be done to an
* inode (although we don't bother, we just put NULL). */