Вход/Регистрация
Энциклопедия разработчика модулей ядра Linux
вернуться

Померанц Ори

Шрифт:

 * 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

* would work in any case. */

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

for(i=0; i<_NSIG_WORDS && !is_sig; i++) is_sig = current->signal.sig[i] & current->blocked.sig[i];

if (is_sig) {

#else

if (current->signal & current->blocked) {

#endif

/* It's important to put MOD_DEC_USE_COUNT here,

* because for processes where the open is

* interrupted there will never be a corresponding

* close. If we don't decrement the usage count

* here, we will be left with a positive usage

* count which we'll have no way to bring down to

* zero, giving us an immortal module, which can

* only be killed by rebooting the machine. */

MOD_DEC_USE_COUNT;

return -EINTR;

}

 }

 /* If we got here, Already_Open must be zero */

 /* Open the file */

 Already_Open = 1;

 return 0; /* Allow the access */

}

/* 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

  • Читать дальше
  • 1
  • ...
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: