procfs_example.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * procfs_example.c: an example proc interface
  3.  *
  4.  * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
  5.  *
  6.  * This file accompanies the procfs-guide in the Linux kernel
  7.  * source. Its main use is to demonstrate the concepts and
  8.  * functions described in the guide.
  9.  *
  10.  * This software has been developed while working on the LART
  11.  * computing board (http://www.lart.tudelft.nl/), which is
  12.  * sponsored by the Mobile Multi-media Communications
  13.  * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications 
  14.  * (http://www.ubicom.tudelft.nl/) projects.
  15.  *
  16.  * The author can be reached at:
  17.  *
  18.  *  Erik Mouw
  19.  *  Information and Communication Theory Group
  20.  *  Faculty of Information Technology and Systems
  21.  *  Delft University of Technology
  22.  *  P.O. Box 5031
  23.  *  2600 GA Delft
  24.  *  The Netherlands
  25.  *
  26.  *
  27.  * This program is free software; you can redistribute
  28.  * it and/or modify it under the terms of the GNU General
  29.  * Public License as published by the Free Software
  30.  * Foundation; either version 2 of the License, or (at your
  31.  * option) any later version.
  32.  *
  33.  * This program is distributed in the hope that it will be
  34.  * useful, but WITHOUT ANY WARRANTY; without even the implied
  35.  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  36.  * PURPOSE.  See the GNU General Public License for more
  37.  * details.
  38.  * 
  39.  * You should have received a copy of the GNU General Public
  40.  * License along with this program; if not, write to the
  41.  * Free Software Foundation, Inc., 59 Temple Place,
  42.  * Suite 330, Boston, MA  02111-1307  USA
  43.  *
  44.  */
  45. #include <linux/module.h>
  46. #include <linux/kernel.h>
  47. #include <linux/init.h>
  48. #include <linux/proc_fs.h>
  49. #include <linux/sched.h>
  50. #include <asm/uaccess.h>
  51. #define MODULE_VERSION "1.0"
  52. #define MODULE_NAME "procfs_example"
  53. #define FOOBAR_LEN 8
  54. struct fb_data_t {
  55. char name[FOOBAR_LEN + 1];
  56. char value[FOOBAR_LEN + 1];
  57. };
  58. static struct proc_dir_entry *example_dir, *foo_file,
  59. *bar_file, *jiffies_file, *tty_device, *symlink;
  60. struct fb_data_t foo_data, bar_data;
  61. static int proc_read_jiffies(char *page, char **start,
  62.      off_t off, int count,
  63.      int *eof, void *data)
  64. {
  65. int len;
  66. MOD_INC_USE_COUNT;
  67. len = sprintf(page, "jiffies = %ldn",
  68.                       jiffies);
  69. MOD_DEC_USE_COUNT;
  70. return len;
  71. }
  72. static int proc_read_foobar(char *page, char **start,
  73.     off_t off, int count, 
  74.     int *eof, void *data)
  75. {
  76. int len;
  77. struct fb_data_t *fb_data = (struct fb_data_t *)data;
  78. MOD_INC_USE_COUNT;
  79. len = sprintf(page, "%s = '%s'n", 
  80.       fb_data->name, fb_data->value);
  81. MOD_DEC_USE_COUNT;
  82. return len;
  83. }
  84. static int proc_write_foobar(struct file *file,
  85.      const char *buffer,
  86.      unsigned long count, 
  87.      void *data)
  88. {
  89. int len;
  90. struct fb_data_t *fb_data = (struct fb_data_t *)data;
  91. MOD_INC_USE_COUNT;
  92. if(count > FOOBAR_LEN)
  93. len = FOOBAR_LEN;
  94. else
  95. len = count;
  96. if(copy_from_user(fb_data->value, buffer, len)) {
  97. MOD_DEC_USE_COUNT;
  98. return -EFAULT;
  99. }
  100. fb_data->value[len] = '';
  101. MOD_DEC_USE_COUNT;
  102. return len;
  103. }
  104. static int __init init_procfs_example(void)
  105. {
  106. int rv = 0;
  107. /* create directory */
  108. example_dir = proc_mkdir(MODULE_NAME, NULL);
  109. if(example_dir == NULL) {
  110. rv = -ENOMEM;
  111. goto out;
  112. }
  113. example_dir->owner = THIS_MODULE;
  114. /* create jiffies using convenience function */
  115. jiffies_file = create_proc_read_entry("jiffies", 
  116.       0444, example_dir, 
  117.       proc_read_jiffies,
  118.       NULL);
  119. if(jiffies_file == NULL) {
  120. rv  = -ENOMEM;
  121. goto no_jiffies;
  122. }
  123. jiffies_file->owner = THIS_MODULE;
  124. /* create foo and bar files using same callback
  125.  * functions 
  126.  */
  127. foo_file = create_proc_entry("foo", 0644, example_dir);
  128. if(foo_file == NULL) {
  129. rv = -ENOMEM;
  130. goto no_foo;
  131. }
  132. strcpy(foo_data.name, "foo");
  133. strcpy(foo_data.value, "foo");
  134. foo_file->data = &foo_data;
  135. foo_file->read_proc = proc_read_foobar;
  136. foo_file->write_proc = proc_write_foobar;
  137. foo_file->owner = THIS_MODULE;
  138. bar_file = create_proc_entry("bar", 0644, example_dir);
  139. if(bar_file == NULL) {
  140. rv = -ENOMEM;
  141. goto no_bar;
  142. }
  143. strcpy(bar_data.name, "bar");
  144. strcpy(bar_data.value, "bar");
  145. bar_file->data = &bar_data;
  146. bar_file->read_proc = proc_read_foobar;
  147. bar_file->write_proc = proc_write_foobar;
  148. bar_file->owner = THIS_MODULE;
  149. /* create tty device */
  150. tty_device = proc_mknod("tty", S_IFCHR | 0666,
  151. example_dir, MKDEV(5, 0));
  152. if(tty_device == NULL) {
  153. rv = -ENOMEM;
  154. goto no_tty;
  155. }
  156. tty_device->owner = THIS_MODULE;
  157. /* create symlink */
  158. symlink = proc_symlink("jiffies_too", example_dir, 
  159.        "jiffies");
  160. if(symlink == NULL) {
  161. rv = -ENOMEM;
  162. goto no_symlink;
  163. }
  164. symlink->owner = THIS_MODULE;
  165. /* everything OK */
  166. printk(KERN_INFO "%s %s initialisedn",
  167.        MODULE_NAME, MODULE_VERSION);
  168. return 0;
  169. no_symlink:
  170. remove_proc_entry("tty", example_dir);
  171. no_tty:
  172. remove_proc_entry("bar", example_dir);
  173. no_bar:
  174. remove_proc_entry("foo", example_dir);
  175. no_foo:
  176. remove_proc_entry("jiffies", example_dir);
  177. no_jiffies:       
  178. remove_proc_entry(MODULE_NAME, NULL);
  179. out:
  180. return rv;
  181. }
  182. static void __exit cleanup_procfs_example(void)
  183. {
  184. remove_proc_entry("jiffies_too", example_dir);
  185. remove_proc_entry("tty", example_dir);
  186. remove_proc_entry("bar", example_dir);
  187. remove_proc_entry("foo", example_dir);
  188. remove_proc_entry("jiffies", example_dir);
  189. remove_proc_entry(MODULE_NAME, NULL);
  190. printk(KERN_INFO "%s %s removedn",
  191.        MODULE_NAME, MODULE_VERSION);
  192. }
  193. module_init(init_procfs_example);
  194. module_exit(cleanup_procfs_example);
  195. MODULE_AUTHOR("Erik Mouw");
  196. MODULE_DESCRIPTION("procfs examples");
  197. EXPORT_NO_SYMBOLS;