Энциклопедия разработчика модулей ядра Linux - [8]

Шрифт
Интервал

procfs.c

>/* procfs.c - create a "file" in /proc, which allows

>* both input and output.

>*/

>/* Copyright (C) 1998-1999 by Ori Pomerantz */


>/* The necessary header files */

>/* Standard in kernel modules */

>#include /* We're doing kernel work */

>#include /* Specifically, a module */


>/* Deal with CONFIG_MODVERSIONS */

>#if CONFIG_MODVERSIONS==1

>#define MODVERSIONS

>#include

>#endif


>/* Necessary because we use proc fs */

>#include


>/* In 2.2.3 /usr/include/linux/version.h includes a

>* macro for this, but 2.0.35 doesn't - so I add it

>* here if necessary. */

>#ifndef KERNEL_VERSION

>#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))

>#endif


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

>#include /* for get_user and put_user */

>#endif


>/* The module's file functions ********************** */

>/* Here we keep the last message received, to prove

>* that we can process our input */

>#define MESSAGE_LENGTH 80

>static char Message[MESSAGE_LENGTH];


>/* Since we use the file operations struct, we can't

>* use the special proc output provisions - we have to

>* use a standard read function, which is this function */

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

>static ssize_t module_output(

> struct file *file, /* The file read */

> char *buf, /* The buffer to put data to (in the user segment) */

> size_t len, /* The length of the buffer */

> loff_t *offset) /* Offset in the file - ignore */

>#else

>static int module_output(

> struct inode *inode, /* The inode read */

> struct file *file, /* The file read */

> char *buf, /* The buffer to put data to (in the user segment) */

> int len) /* The length of the buffer */

>#endif

>{

> static int finished = 0;

> int i;

> char message[MESSAGE_LENGTH+30];


> /* We return 0 to indicate end of file, that we have

> * no more information. Otherwise, processes will

> * continue to read from us in an endless loop. */

> if (finished) {

>  finished = 0;

>  return 0;

> }


> /* We use put_user to copy the string from the kernel's

> * memory segment to the memory segment of the process

> * that called us. get_user, BTW, is

> * used for the reverse. */

> sprintf(message, "Last input:%s", Message);

> for(i=0; i


> /* Notice, we assume here that the size of the message

> * is below len, or it will be received cut. In a real

> * life situation, if the size of the message is less

> * than len then we'd return len and on the second call

> * start filling the buffer with the len+1'th byte of the message. */

> finished = 1;

> return i; /* Return the number of bytes "read" */

>}


>/* This function receives input from the user when the

>* user writes to the /proc file. */

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

>static ssize_t module_input(

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

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

> size_t length, /* The buffer's length */

> loff_t *offset) /* offset to file - ignore */

>#else

>static int module_input(

> struct inode *inode, /* The file's inode */

> 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);

>  /* In version 2.2 the semantics of get_user changed,

>  * it not longer returns a character, but expects a

>  * variable to fill up as its first argument and a

>  * user segment pointer to fill it from as the its  second.

>  *

>  * The reason for this change is that the version 2.2

>  * get_user can also read an short or an int. The way

>  * it knows the type of the variable it should read

>  * is by using sizeof, and for that it needs the

>  * variable itself. */

>#else

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

>#endif

> Message[i] = '\0'; /* we want a standard, zero terminated string */

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

> return i;

>}


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

>}


>/* The file is opened - we don't really care about

>* that, but it does mean we need to increment the

>* module's reference count. */

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

> MOD_INC_USE_COUNT;

> return 0;

>}


>/* The file is closed - again, interesting only because of the reference count. */


Рекомендуем почитать
Графика DirectX в Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Вторая жизнь старых компьютеров

Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.


DirectX 8. Начинаем работу с DirectX Graphics

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.