About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / DocBook / procfs_example.c

Based on kernel version 2.6.25. Page generated on 2008-04-18 21:22 EST.

1	/*
2	 * procfs_example.c: an example proc interface
3	 *
4	 * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw[AT]its.tudelft[DOT]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	
46	#include <linux/module.h>
47	#include <linux/kernel.h>
48	#include <linux/init.h>
49	#include <linux/proc_fs.h>
50	#include <linux/jiffies.h>
51	#include <asm/uaccess.h>
52	
53	
54	#define MODULE_VERS "1.0"
55	#define MODULE_NAME "procfs_example"
56	
57	#define FOOBAR_LEN 8
58	
59	struct fb_data_t {
60		char name[FOOBAR_LEN + 1];
61		char value[FOOBAR_LEN + 1];
62	};
63	
64	
65	static struct proc_dir_entry *example_dir, *foo_file,
66		*bar_file, *jiffies_file, *symlink;
67	
68	
69	struct fb_data_t foo_data, bar_data;
70	
71	
72	static int proc_read_jiffies(char *page, char **start,
73				     off_t off, int count,
74				     int *eof, void *data)
75	{
76		int len;
77	
78		len = sprintf(page, "jiffies = %ld\n",
79	                      jiffies);
80	
81		return len;
82	}
83	
84	
85	static int proc_read_foobar(char *page, char **start,
86				    off_t off, int count, 
87				    int *eof, void *data)
88	{
89		int len;
90		struct fb_data_t *fb_data = (struct fb_data_t *)data;
91	
92		/* DON'T DO THAT - buffer overruns are bad */
93		len = sprintf(page, "%s = '%s'\n", 
94			      fb_data->name, fb_data->value);
95	
96		return len;
97	}
98	
99	
100	static int proc_write_foobar(struct file *file,
101				     const char *buffer,
102				     unsigned long count, 
103				     void *data)
104	{
105		int len;
106		struct fb_data_t *fb_data = (struct fb_data_t *)data;
107	
108		if(count > FOOBAR_LEN)
109			len = FOOBAR_LEN;
110		else
111			len = count;
112	
113		if(copy_from_user(fb_data->value, buffer, len))
114			return -EFAULT;
115	
116		fb_data->value[len] = '\0';
117	
118		return len;
119	}
120	
121	
122	static int __init init_procfs_example(void)
123	{
124		int rv = 0;
125	
126		/* create directory */
127		example_dir = proc_mkdir(MODULE_NAME, NULL);
128		if(example_dir == NULL) {
129			rv = -ENOMEM;
130			goto out;
131		}
132		
133		example_dir->owner = THIS_MODULE;
134		
135		/* create jiffies using convenience function */
136		jiffies_file = create_proc_read_entry("jiffies", 
137						      0444, example_dir, 
138						      proc_read_jiffies,
139						      NULL);
140		if(jiffies_file == NULL) {
141			rv  = -ENOMEM;
142			goto no_jiffies;
143		}
144	
145		jiffies_file->owner = THIS_MODULE;
146	
147		/* create foo and bar files using same callback
148		 * functions 
149		 */
150		foo_file = create_proc_entry("foo", 0644, example_dir);
151		if(foo_file == NULL) {
152			rv = -ENOMEM;
153			goto no_foo;
154		}
155	
156		strcpy(foo_data.name, "foo");
157		strcpy(foo_data.value, "foo");
158		foo_file->data = &foo_data;
159		foo_file->read_proc = proc_read_foobar;
160		foo_file->write_proc = proc_write_foobar;
161		foo_file->owner = THIS_MODULE;
162			
163		bar_file = create_proc_entry("bar", 0644, example_dir);
164		if(bar_file == NULL) {
165			rv = -ENOMEM;
166			goto no_bar;
167		}
168	
169		strcpy(bar_data.name, "bar");
170		strcpy(bar_data.value, "bar");
171		bar_file->data = &bar_data;
172		bar_file->read_proc = proc_read_foobar;
173		bar_file->write_proc = proc_write_foobar;
174		bar_file->owner = THIS_MODULE;
175			
176		/* create symlink */
177		symlink = proc_symlink("jiffies_too", example_dir, 
178				       "jiffies");
179		if(symlink == NULL) {
180			rv = -ENOMEM;
181			goto no_symlink;
182		}
183	
184		symlink->owner = THIS_MODULE;
185	
186		/* everything OK */
187		printk(KERN_INFO "%s %s initialised\n",
188		       MODULE_NAME, MODULE_VERS);
189		return 0;
190	
191	no_symlink:
192		remove_proc_entry("tty", example_dir);
193	no_tty:
194		remove_proc_entry("bar", example_dir);
195	no_bar:
196		remove_proc_entry("foo", example_dir);
197	no_foo:
198		remove_proc_entry("jiffies", example_dir);
199	no_jiffies:			      
200		remove_proc_entry(MODULE_NAME, NULL);
201	out:
202		return rv;
203	}
204	
205	
206	static void __exit cleanup_procfs_example(void)
207	{
208		remove_proc_entry("jiffies_too", example_dir);
209		remove_proc_entry("tty", example_dir);
210		remove_proc_entry("bar", example_dir);
211		remove_proc_entry("foo", example_dir);
212		remove_proc_entry("jiffies", example_dir);
213		remove_proc_entry(MODULE_NAME, NULL);
214	
215		printk(KERN_INFO "%s %s removed\n",
216		       MODULE_NAME, MODULE_VERS);
217	}
218	
219	
220	module_init(init_procfs_example);
221	module_exit(cleanup_procfs_example);
222	
223	MODULE_AUTHOR("Erik Mouw");
224	MODULE_DESCRIPTION("procfs examples");
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.