procfs_example.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
- /*
- * procfs_example.c: an example proc interface
- *
- * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *
- * This file accompanies the procfs-guide in the Linux kernel
- * source. Its main use is to demonstrate the concepts and
- * functions described in the guide.
- *
- * This software has been developed while working on the LART
- * computing board (http://www.lart.tudelft.nl/), which is
- * sponsored by the Mobile Multi-media Communications
- * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications
- * (http://www.ubicom.tudelft.nl/) projects.
- *
- * The author can be reached at:
- *
- * Erik Mouw
- * Information and Communication Theory Group
- * Faculty of Information Technology and Systems
- * Delft University of Technology
- * P.O. Box 5031
- * 2600 GA Delft
- * The Netherlands
- *
- *
- * This program is free software; you can redistribute
- * it and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA 02111-1307 USA
- *
- */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/proc_fs.h>
- #include <linux/sched.h>
- #include <asm/uaccess.h>
- #define MODULE_VERSION "1.0"
- #define MODULE_NAME "procfs_example"
- #define FOOBAR_LEN 8
- struct fb_data_t {
- char name[FOOBAR_LEN + 1];
- char value[FOOBAR_LEN + 1];
- };
- static struct proc_dir_entry *example_dir, *foo_file,
- *bar_file, *jiffies_file, *tty_device, *symlink;
- struct fb_data_t foo_data, bar_data;
- static int proc_read_jiffies(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
- {
- int len;
- MOD_INC_USE_COUNT;
-
- len = sprintf(page, "jiffies = %ldn",
- jiffies);
- MOD_DEC_USE_COUNT;
- return len;
- }
- static int proc_read_foobar(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
- {
- int len;
- struct fb_data_t *fb_data = (struct fb_data_t *)data;
- MOD_INC_USE_COUNT;
-
- len = sprintf(page, "%s = '%s'n",
- fb_data->name, fb_data->value);
- MOD_DEC_USE_COUNT;
- return len;
- }
- static int proc_write_foobar(struct file *file,
- const char *buffer,
- unsigned long count,
- void *data)
- {
- int len;
- struct fb_data_t *fb_data = (struct fb_data_t *)data;
- MOD_INC_USE_COUNT;
- if(count > FOOBAR_LEN)
- len = FOOBAR_LEN;
- else
- len = count;
- if(copy_from_user(fb_data->value, buffer, len)) {
- MOD_DEC_USE_COUNT;
- return -EFAULT;
- }
- fb_data->value[len] = ' ';
- MOD_DEC_USE_COUNT;
- return len;
- }
- static int __init init_procfs_example(void)
- {
- int rv = 0;
- /* create directory */
- example_dir = proc_mkdir(MODULE_NAME, NULL);
- if(example_dir == NULL) {
- rv = -ENOMEM;
- goto out;
- }
-
- example_dir->owner = THIS_MODULE;
-
- /* create jiffies using convenience function */
- jiffies_file = create_proc_read_entry("jiffies",
- 0444, example_dir,
- proc_read_jiffies,
- NULL);
- if(jiffies_file == NULL) {
- rv = -ENOMEM;
- goto no_jiffies;
- }
- jiffies_file->owner = THIS_MODULE;
- /* create foo and bar files using same callback
- * functions
- */
- foo_file = create_proc_entry("foo", 0644, example_dir);
- if(foo_file == NULL) {
- rv = -ENOMEM;
- goto no_foo;
- }
- strcpy(foo_data.name, "foo");
- strcpy(foo_data.value, "foo");
- foo_file->data = &foo_data;
- foo_file->read_proc = proc_read_foobar;
- foo_file->write_proc = proc_write_foobar;
- foo_file->owner = THIS_MODULE;
-
- bar_file = create_proc_entry("bar", 0644, example_dir);
- if(bar_file == NULL) {
- rv = -ENOMEM;
- goto no_bar;
- }
- strcpy(bar_data.name, "bar");
- strcpy(bar_data.value, "bar");
- bar_file->data = &bar_data;
- bar_file->read_proc = proc_read_foobar;
- bar_file->write_proc = proc_write_foobar;
- bar_file->owner = THIS_MODULE;
-
- /* create tty device */
- tty_device = proc_mknod("tty", S_IFCHR | 0666,
- example_dir, MKDEV(5, 0));
- if(tty_device == NULL) {
- rv = -ENOMEM;
- goto no_tty;
- }
-
- tty_device->owner = THIS_MODULE;
- /* create symlink */
- symlink = proc_symlink("jiffies_too", example_dir,
- "jiffies");
- if(symlink == NULL) {
- rv = -ENOMEM;
- goto no_symlink;
- }
- symlink->owner = THIS_MODULE;
- /* everything OK */
- printk(KERN_INFO "%s %s initialisedn",
- MODULE_NAME, MODULE_VERSION);
- return 0;
- no_symlink:
- remove_proc_entry("tty", example_dir);
- no_tty:
- remove_proc_entry("bar", example_dir);
- no_bar:
- remove_proc_entry("foo", example_dir);
- no_foo:
- remove_proc_entry("jiffies", example_dir);
- no_jiffies:
- remove_proc_entry(MODULE_NAME, NULL);
- out:
- return rv;
- }
- static void __exit cleanup_procfs_example(void)
- {
- remove_proc_entry("jiffies_too", example_dir);
- remove_proc_entry("tty", example_dir);
- remove_proc_entry("bar", example_dir);
- remove_proc_entry("foo", example_dir);
- remove_proc_entry("jiffies", example_dir);
- remove_proc_entry(MODULE_NAME, NULL);
- printk(KERN_INFO "%s %s removedn",
- MODULE_NAME, MODULE_VERSION);
- }
- module_init(init_procfs_example);
- module_exit(cleanup_procfs_example);
- MODULE_AUTHOR("Erik Mouw");
- MODULE_DESCRIPTION("procfs examples");
- EXPORT_NO_SYMBOLS;