Энциклопедия разработчика модулей ядра Linux | страница 33



> struct file *file, /* The file itself */

> const char *buf, /* The buffer with the input */

> int length) /* The buffer's length */

>#endif

>{

> int i;

> /* Put the input into Message, where module_output

> * will later be able to use it */

> for(i=0; i

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

> get_user(Message[i], buf+i);

>#else

> Message[i] = get_user(buf+i);

>#endif

> /* we want a standard, zero terminated string */

> Message[i] = '\0';

> /* We need to return the number of input characters used */

> return i;

>}


>/* 1 if the file is currently open by somebody */

>int Already_Open = 0;


> /* Queue of processes who want our file */

>static struct wait_queue *WaitQ = NULL;


>/* Called when the /proc file is opened */

>static int module_open(struct inode *inode, struct file *file) {

> /* If the file's flags include O_NONBLOCK, it means

> * the process doesn't want to wait for the file.

> * In this case, if the file is already open, we

> * should fail with -EAGAIN, meaning "you'll have to

> * try again", instead of blocking a process which

> * would rather stay awake. */

> if ((file->f_flags & O_NONBLOCK) && Already_Open) return -EAGAIN;

> /* This is the correct place for MOD_INC_USE_COUNT

> * because if a process is in the loop, which is

> * within the kernel module, the kernel module must

> * not be removed. */

> MOD_INC_USE_COUNT;

> /* If the file is already open, wait until it isn't */

> while (Already_Open) {

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>  int i, is_sig=0;

>#endif

>  /* This function puts the current process,

>  * including any system calls, such as us, to sleep.

>  * Execution will be resumed right after the function

>  * call, either because somebody called

>  * wake_up(&WaitQ) (only module_close does that,

>  * when the file is closed) or when a signal, such

>  * as Ctrl-C, is sent to the process */

>  module_interruptible_sleep_on(&WaitQ);

>  /* If we woke up because we got a signal we're not

>  * blocking, return -EINTR (fail the system call).

>  * This allows processes to be killed or stopped. */

>  /*

>  * Emmanuel Papirakis:

>  *

>  * This is a little update to work with 2.2.*. Signals

>  * now are contained in two words (64 bits) and are

>  * stored in a structure that contains an array of two

>  * unsigned longs. We now have to make 2 checks in our if.

>  *

>  * Ori Pomerantz:

>  *

>  * Nobody promised me they'll never use more than 64

>  * bits, or that this book won't be used for a version

>  * of Linux with a word size of 16 bits. This code