4 * Copyright (C) 1991, 1992 Linus Torvalds 6 * gjh 3/'93 heim@peanuts.informatik.uni-tuebingen.de (Gerald J. Heim) 7 * most of this file is stolen from base.c 8 * it works, but you shouldn't use it as a guideline 9 * for new proc-fs entries. once i'll make it better. 10 * fvk 3/'93 waltje@uwalt.nl.mugnet.org (Fred N. van Kempen) 11 * cleaned up the whole thing, moved "net" specific code to 12 * the NET kernel layer (where it belonged in the first place). 13 * Michael K. Johnson (johnsonm@stolaf.edu) 3/93 14 * Added support from my previous inet.c. Cleaned things up 15 * quite a bit, modularized the code. 16 * fvk 4/'93 waltje@uwalt.nl.mugnet.org (Fred N. van Kempen) 17 * Renamed "route_get_info()" to "rt_get_info()" for consistency. 18 * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94 19 * Dusted off the code and added IPX. Fixed the 4K limit. 20 * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de) 22 * Alan Cox (gw4pts@gw4pts.ampr.org) 1/95 23 * Added Appletalk slots 25 * proc net directory handling functions 27 #include <linux/autoconf.h> 29 #include <asm/segment.h> 31 #include <linux/errno.h> 32 #include <linux/sched.h> 33 #include <linux/proc_fs.h> 34 #include <linux/stat.h> 35 #include <linux/fcntl.h> 36 #include <linux/config.h> 39 /* forward references */ 40 static intproc_readnet(struct inode
* inode
,struct file
* file
, 42 static intproc_readnetdir(struct inode
*,struct file
*, 43 void*, filldir_t filldir
); 44 static intproc_lookupnet(struct inode
*,const char*,int,struct inode
**); 46 static struct file_operations proc_net_operations
= { 47 NULL
,/* lseek - default */ 48 proc_readnet
,/* read - bad */ 49 NULL
,/* write - bad */ 50 proc_readnetdir
,/* readdir */ 51 NULL
,/* select - default */ 52 NULL
,/* ioctl - default */ 54 NULL
,/* no special open code */ 55 NULL
,/* no special release code */ 56 NULL
/* can't fsync */ 60 * proc directories can do almost nothing.. 62 struct inode_operations proc_net_inode_operations
= { 63 &proc_net_operations
,/* default net directory file-ops */ 65 proc_lookupnet
,/* lookup */ 74 NULL
,/* follow_link */ 80 #define NR_MAX_PROC_NET_DIR 100 81 static struct proc_dir_entry
*net_dir
[NR_MAX_PROC_NET_DIR
] = { 85 static int nr_net_direntry
=0; 87 intproc_net_register(struct proc_dir_entry
*dp
) 91 for(i
=0; net_dir
[i
] != NULL
; ++i
) ; 93 if(i
>= NR_MAX_PROC_NET_DIR
) 97 net_dir
[i
+1] = NULL
;/* Just make sure.. */ 102 intproc_net_unregister(int ino
) 105 for(i
=0; net_dir
[i
] != NULL
&& i
< nr_net_direntry
; ++i
) 106 if(net_dir
[i
]->low_ino
== ino
) { 107 for( ; net_dir
[i
] != NULL
; ++i
) 108 net_dir
[i
] = net_dir
[i
+1]; 115 static intdir_get_info(char* a
,char** b
, off_t d
,int e
,int f
) 120 voidproc_net_init(void) 122 static struct proc_dir_entry
123 nd_thisdir
= { PROC_NET
, dir_get_info
,1,"."}, 124 nd_rootdir
= { PROC_ROOT_INO
, dir_get_info
,1,".."}; 125 static int already
=0; 130 proc_net_register(&nd_thisdir
); 131 proc_net_register(&nd_rootdir
); 135 static intproc_lookupnet(struct inode
* dir
,const char* name
,int len
, 136 struct inode
** result
) 138 struct proc_dir_entry
**de
; 143 if(!S_ISDIR(dir
->i_mode
)) { 147 for(de
= net_dir
; (*de
)->name
; de
++) { 148 if(!proc_match(len
, name
, *de
)) 150 *result
=iget(dir
->i_sb
, (*de
)->low_ino
); 160 static intproc_readnetdir(struct inode
* inode
,struct file
* filp
, 161 void* dirent
, filldir_t filldir
) 163 struct proc_dir_entry
* de
; 166 if(!inode
|| !S_ISDIR(inode
->i_mode
)) 169 while(((unsigned) filp
->f_pos
) < nr_net_direntry
) { 170 de
= net_dir
[filp
->f_pos
]; 171 if(filldir(dirent
, de
->name
, de
->namelen
, filp
->f_pos
, de
->low_ino
) <0) 179 #define PROC_BLOCK_SIZE (3*1024)/* 4K page size but our output routines use some slack for overruns */ 181 static intproc_readnet(struct inode
* inode
,struct file
* file
, 190 struct proc_dir_entry
* dp
; 196 if(i
>= NR_MAX_PROC_NET_DIR
|| (dp
= net_dir
[i
]) == NULL
) 198 if(dp
->low_ino
== ino
) 201 if(!(page
= (char*)__get_free_page(GFP_KERNEL
))) 206 int length
, thistime
=bytes
; 207 if(bytes
> PROC_BLOCK_SIZE
) 208 thistime
=PROC_BLOCK_SIZE
; 210 length
= dp
->get_info(page
, &start
, 213 (file
->f_flags
& O_ACCMODE
) == O_RDWR
); 216 * We have been given a non page aligned block of 217 * the data we asked for + a bit. We have been given 218 * the start pointer and we know the length.. 226 memcpy_tofs(buf
+copied
, start
, length
); 227 file
->f_pos
+= length
;/* Move down the file */ 231 break;/* End of file */ 233 free_page((unsigned long) page
);