About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / DocBook / procfs_example.c


Based on kernel version 2.6.32. Page generated on 2009-12-11 16:22 EST.

1	/*
2	 * procfs_example.c: an example proc interface
3	 *
4	 * Copyright (C) 2001, Erik Mouw (mouw[AT]nl.linux[DOT]org)
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.lartmaker.nl), which was sponsored
12	 * by the Delt University of Technology projects Mobile Multi-media
13	 * Communications and Ubiquitous Communications.
14	 *
15	 * This program is free software; you can redistribute
16	 * it and/or modify it under the terms of the GNU General
17	 * Public License as published by the Free Software
18	 * Foundation; either version 2 of the License, or (at your
19	 * option) any later version.
20	 *
21	 * This program is distributed in the hope that it will be
22	 * useful, but WITHOUT ANY WARRANTY; without even the implied
23	 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
24	 * PURPOSE.  See the GNU General Public License for more
25	 * details.
26	 * 
27	 * You should have received a copy of the GNU General Public
28	 * License along with this program; if not, write to the
29	 * Free Software Foundation, Inc., 59 Temple Place,
30	 * Suite 330, Boston, MA  02111-1307  USA
31	 *
32	 */
33	
34	#include <linux/module.h>
35	#include <linux/kernel.h>
36	#include <linux/init.h>
37	#include <linux/proc_fs.h>
38	#include <linux/jiffies.h>
39	#include <asm/uaccess.h>
40	
41	
42	#define MODULE_VERS "1.0"
43	#define MODULE_NAME "procfs_example"
44	
45	#define FOOBAR_LEN 8
46	
47	struct fb_data_t {
48		char name[FOOBAR_LEN + 1];
49		char value[FOOBAR_LEN + 1];
50	};
51	
52	
53	static struct proc_dir_entry *example_dir, *foo_file,
54		*bar_file, *jiffies_file, *symlink;
55	
56	
57	struct fb_data_t foo_data, bar_data;
58	
59	
60	static int proc_read_jiffies(char *page, char **start,
61				     off_t off, int count,
62				     int *eof, void *data)
63	{
64		int len;
65	
66		len = sprintf(page, "jiffies = %ld\n",
67	                      jiffies);
68	
69		return len;
70	}
71	
72	
73	static int proc_read_foobar(char *page, char **start,
74				    off_t off, int count, 
75				    int *eof, void *data)
76	{
77		int len;
78		struct fb_data_t *fb_data = (struct fb_data_t *)data;
79	
80		/* DON'T DO THAT - buffer overruns are bad */
81		len = sprintf(page, "%s = '%s'\n", 
82			      fb_data->name, fb_data->value);
83	
84		return len;
85	}
86	
87	
88	static int proc_write_foobar(struct file *file,
89				     const char *buffer,
90				     unsigned long count, 
91				     void *data)
92	{
93		int len;
94		struct fb_data_t *fb_data = (struct fb_data_t *)data;
95	
96		if(count > FOOBAR_LEN)
97			len = FOOBAR_LEN;
98		else
99			len = count;
100	
101		if(copy_from_user(fb_data->value, buffer, len))
102			return -EFAULT;
103	
104		fb_data->value[len] = '\0';
105	
106		return len;
107	}
108	
109	
110	static int __init init_procfs_example(void)
111	{
112		int rv = 0;
113	
114		/* create directory */
115		example_dir = proc_mkdir(MODULE_NAME, NULL);
116		if(example_dir == NULL) {
117			rv = -ENOMEM;
118			goto out;
119		}
120		/* create jiffies using convenience function */
121		jiffies_file = create_proc_read_entry("jiffies", 
122						      0444, example_dir, 
123						      proc_read_jiffies,
124						      NULL);
125		if(jiffies_file == NULL) {
126			rv  = -ENOMEM;
127			goto no_jiffies;
128		}
129	
130		/* create foo and bar files using same callback
131		 * functions 
132		 */
133		foo_file = create_proc_entry("foo", 0644, example_dir);
134		if(foo_file == NULL) {
135			rv = -ENOMEM;
136			goto no_foo;
137		}
138	
139		strcpy(foo_data.name, "foo");
140		strcpy(foo_data.value, "foo");
141		foo_file->data = &foo_data;
142		foo_file->read_proc = proc_read_foobar;
143		foo_file->write_proc = proc_write_foobar;
144			
145		bar_file = create_proc_entry("bar", 0644, example_dir);
146		if(bar_file == NULL) {
147			rv = -ENOMEM;
148			goto no_bar;
149		}
150	
151		strcpy(bar_data.name, "bar");
152		strcpy(bar_data.value, "bar");
153		bar_file->data = &bar_data;
154		bar_file->read_proc = proc_read_foobar;
155		bar_file->write_proc = proc_write_foobar;
156			
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	
165		/* everything OK */
166		printk(KERN_INFO "%s %s initialised\n",
167		       MODULE_NAME, MODULE_VERS);
168		return 0;
169	
170	no_symlink:
171		remove_proc_entry("bar", example_dir);
172	no_bar:
173		remove_proc_entry("foo", example_dir);
174	no_foo:
175		remove_proc_entry("jiffies", example_dir);
176	no_jiffies:			      
177		remove_proc_entry(MODULE_NAME, NULL);
178	out:
179		return rv;
180	}
181	
182	
183	static void __exit cleanup_procfs_example(void)
184	{
185		remove_proc_entry("jiffies_too", 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	
191		printk(KERN_INFO "%s %s removed\n",
192		       MODULE_NAME, MODULE_VERS);
193	}
194	
195	
196	module_init(init_procfs_example);
197	module_exit(cleanup_procfs_example);
198	
199	MODULE_AUTHOR("Erik Mouw");
200	MODULE_DESCRIPTION("procfs examples");
201	MODULE_LICENSE("GPL");
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog