~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/devpts/root.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* -*- linux-c -*- --------------------------------------------------------- *
  2  *
  3  * linux/fs/devpts/root.c
  4  *
  5  *  Copyright 1998 H. Peter Anvin -- All Rights Reserved
  6  *
  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.
 10  *
 11  * ------------------------------------------------------------------------- */
 12 
 13 #include <linux/errno.h>
 14 #include <linux/stat.h>
 15 #include <linux/param.h>
 16 #include <linux/string.h>
 17 #include "devpts_i.h"
 18 
 19 static int devpts_root_readdir(struct file *,void *,filldir_t);
 20 static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
 21 static int devpts_revalidate(struct dentry *, int);
 22 
 23 struct file_operations devpts_root_operations = {
 24         read:           generic_read_dir,
 25         readdir:        devpts_root_readdir,
 26 };
 27 
 28 struct inode_operations devpts_root_inode_operations = {
 29         lookup:         devpts_root_lookup,
 30 };
 31 
 32 static struct dentry_operations devpts_dentry_operations = {
 33         d_revalidate:   devpts_revalidate,
 34 };
 35 
 36 /*
 37  * The normal naming convention is simply /dev/pts/<number>; this conforms
 38  * to the System V naming convention
 39  */
 40 
 41 #define genptsname(buf,num) sprintf(buf, "%d", num)
 42 
 43 static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
 44 {
 45         struct inode * inode = filp->f_dentry->d_inode;
 46         struct devpts_sb_info * sbi = SBI(filp->f_dentry->d_inode->i_sb);
 47         off_t nr;
 48         char numbuf[16];
 49 
 50         nr = filp->f_pos;
 51 
 52         switch(nr)
 53         {
 54         case 0:
 55                 if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
 56                         return 0;
 57                 filp->f_pos = ++nr;
 58                 /* fall through */
 59         case 1:
 60                 if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
 61                         return 0;
 62                 filp->f_pos = ++nr;
 63                 /* fall through */
 64         default:
 65                 while ( nr - 2 < sbi->max_ptys ) {
 66                         int ptynr = nr - 2;
 67                         if ( sbi->inodes[ptynr] ) {
 68                                 genptsname(numbuf, ptynr);
 69                                 if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
 70                                         return 0;
 71                         }
 72                         filp->f_pos = ++nr;
 73                 }
 74                 break;
 75         }
 76 
 77         return 0;
 78 }
 79 
 80 /*
 81  * Revalidate is called on every cache lookup.  We use it to check that
 82  * the pty really does still exist.  Never revalidate negative dentries;
 83  * for simplicity (fix later?)
 84  */
 85 static int devpts_revalidate(struct dentry * dentry, int flags)
 86 {
 87         struct devpts_sb_info *sbi;
 88 
 89         if ( !dentry->d_inode )
 90                 return 0;
 91 
 92         sbi = SBI(dentry->d_inode->i_sb);
 93 
 94         return ( sbi->inodes[dentry->d_inode->i_ino - 2] == dentry->d_inode );
 95 }
 96 
 97 static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * dentry)
 98 {
 99         struct devpts_sb_info *sbi = SBI(dir->i_sb);
100         unsigned int entry;
101         int i;
102         const char *p;
103 
104         dentry->d_inode = NULL; /* Assume failure */
105         dentry->d_op    = &devpts_dentry_operations;
106 
107         if ( dentry->d_name.len == 1 && dentry->d_name.name[0] == '' ) {
108                 entry = 0;
109         } else if ( dentry->d_name.len < 1 ) {
110                 return NULL;
111         } else {
112                 p = dentry->d_name.name;
113                 if ( *p < '1' || *p > '9' )
114                         return NULL;
115                 entry = *p++ - '';
116 
117                 for ( i = dentry->d_name.len-1 ; i ; i-- ) {
118                         unsigned int nentry = *p++ - '';
119                         if ( nentry > 9 )
120                                 return NULL;
121                         if ( entry >= ~0U/10 )
122                                 return NULL;
123                         entry = nentry + entry * 10;
124                 }
125         }
126 
127         if ( entry >= sbi->max_ptys )
128                 return NULL;
129 
130         dentry->d_inode = sbi->inodes[entry];
131         if ( dentry->d_inode )
132                 atomic_inc(&dentry->d_inode->i_count);
133         
134         d_add(dentry, dentry->d_inode);
135 
136         return NULL;
137 }
138 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.