1 /* -*- linux-c -*- --------------------------------------------------------- *
3 * linux/fs/devpts/root.c
5 * Copyright 1998 H. Peter Anvin -- All Rights Reserved
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
11 * ------------------------------------------------------------------------- */
13 #include <linux/errno.h>
14 #include <linux/stat.h>
15 #include <linux/param.h>
16 #include <linux/string.h>
19 static int devpts_root_readdir(struct file
*,void *,filldir_t
);
20 static int devpts_root_lookup(struct inode
*,struct dentry
*);
21 static int devpts_revalidate(struct dentry
*);
23 static struct file_operations devpts_root_operations
= {
27 devpts_root_readdir
, /* readdir */
36 NULL
, /* check_media_change */
37 NULL
, /* revalidate */
41 struct inode_operations devpts_root_inode_operations
= {
42 &devpts_root_operations
, /* file operations */
44 devpts_root_lookup
, /* lookup */
53 NULL
, /* follow_link */
58 NULL
, /* permission */
60 NULL
, /* updatepage */
64 static struct dentry_operations devpts_dentry_operations
= {
65 devpts_revalidate
, /* d_revalidate */
71 * The normal naming convention is simply /dev/pts/<number>; this conforms
72 * to the System V naming convention
75 #define genptsname(buf,num) sprintf(buf, "%d", num)
77 static int devpts_root_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
79 struct inode
* inode
= filp
->f_dentry
->d_inode
;
80 struct devpts_sb_info
* sbi
= SBI(filp
->f_dentry
->d_inode
->i_sb
);
84 if (!inode
|| !S_ISDIR(inode
->i_mode
))
92 if (filldir(dirent
, ".", 1, nr
, inode
->i_ino
) < 0)
97 if (filldir(dirent
, "..", 2, nr
, inode
->i_ino
) < 0)
102 while ( nr
< sbi
->max_ptys
) {
104 if ( sbi
->inodes
[ptynr
] ) {
105 genptsname(numbuf
, ptynr
);
106 if ( filldir(dirent
, numbuf
, strlen(numbuf
), nr
, nr
) < 0 )
118 * Revalidate is called on every cache lookup. We use it to check that
119 * the pty really does still exist. Never revalidate negative dentries;
120 * for simplicity (fix later?)
122 static int devpts_revalidate(struct dentry
* dentry
)
124 struct devpts_sb_info
*sbi
;
126 if ( !dentry
->d_inode
)
129 sbi
= SBI(dentry
->d_inode
->i_sb
);
131 return ( sbi
->inodes
[dentry
->d_inode
->i_ino
- 2] == dentry
->d_inode
);
134 static int devpts_root_lookup(struct inode
* dir
, struct dentry
* dentry
)
136 struct devpts_sb_info
*sbi
= SBI(dir
->i_sb
);
140 if (!S_ISDIR(dir
->i_mode
))
143 dentry
->d_inode
= NULL
; /* Assume failure */
144 dentry
->d_op
= &devpts_dentry_operations
;
146 if ( dentry
->d_name
.len
== 1 && dentry
->d_name
.name
[0] == '0' ) {
148 } else if ( dentry
->d_name
.len
< 1 ) {
151 p
= dentry
->d_name
.name
;
152 if ( *p
< '1' || *p
> '9' )
156 for ( i
= dentry
->d_name
.len
-1 ; i
; i
-- ) {
157 if ( *p
< '0' || *p
> '9' )
160 entry
+= (*p
++ - '0');
164 dentry
->d_inode
= sbi
->inodes
[entry
];
165 if ( dentry
->d_inode
)
166 dentry
->d_inode
->i_count
++;
168 d_add(dentry
, dentry
->d_inode
);