Annotation of linux/fs/proc/base.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  linux/fs/proc/base.c
                      3:  *
                      4:  *  Copyright (C) 1991, 1992 Linus Torvalds
                      5:  *
                      6:  *  proc base directory handling functions
                      7:  */
                      8: 
                      9: #include <asm/segment.h>
                     10: 
                     11: #include <linux/errno.h>
                     12: #include <linux/sched.h>
                     13: #include <linux/proc_fs.h>
                     14: #include <linux/stat.h>
                     15: 
                     16: static int proc_readbase(struct inode *, struct file *, struct dirent *, int);
                     17: static int proc_lookupbase(struct inode *,const char *,int,struct inode **);
                     18: 
                     19: static struct file_operations proc_base_operations = {
                     20:        NULL,                   /* lseek - default */
                     21:        NULL,                   /* read - bad */
                     22:        NULL,                   /* write - bad */
                     23:        proc_readbase,          /* readdir */
                     24:        NULL,                   /* select - default */
                     25:        NULL,                   /* ioctl - default */
                     26:        NULL,                   /* no special open code */
                     27:        NULL                    /* no special release code */
                     28: };
                     29: 
                     30: /*
                     31:  * proc directories can do almost nothing..
                     32:  */
                     33: struct inode_operations proc_base_inode_operations = {
                     34:        &proc_base_operations,  /* default base directory file-ops */
                     35:        NULL,                   /* create */
                     36:        proc_lookupbase,        /* lookup */
                     37:        NULL,                   /* link */
                     38:        NULL,                   /* unlink */
                     39:        NULL,                   /* symlink */
                     40:        NULL,                   /* mkdir */
                     41:        NULL,                   /* rmdir */
                     42:        NULL,                   /* mknod */
                     43:        NULL,                   /* rename */
                     44:        NULL,                   /* readlink */
                     45:        NULL,                   /* follow_link */
                     46:        NULL,                   /* bmap */
                     47:        NULL                    /* truncate */
                     48: };
                     49: 
                     50: struct proc_dir_entry {
                     51:        unsigned short low_ino;
                     52:        unsigned short namelen;
                     53:        char * name;
                     54: };
                     55: 
                     56: static struct proc_dir_entry base_dir[] = {
                     57:        { 1,2,".." },
                     58:        { 2,1,"." },
                     59:        { 3,3,"mem" },
                     60:        { 4,3,"cwd" },
                     61:        { 5,4,"root" },
                     62:        { 6,3,"exe" },
                     63:        { 7,2,"fd" },
                     64:        { 8,3,"lib" }
                     65: };
                     66: 
                     67: #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
                     68: 
                     69: static int proc_match(int len,const char * name,struct proc_dir_entry * de)
                     70: {
                     71:        register int same __asm__("ax");
                     72: 
                     73:        if (!de || !de->low_ino)
                     74:                return 0;
                     75:        /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
                     76:        if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
                     77:                return 1;
                     78:        if (de->namelen != len)
                     79:                return 0;
                     80:        __asm__("cld\n\t"
                     81:                "fs ; repe ; cmpsb\n\t"
                     82:                "setz %%al"
                     83:                :"=a" (same)
                     84:                :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)
                     85:                :"cx","di","si");
                     86:        return same;
                     87: }
                     88: 
                     89: static int proc_lookupbase(struct inode * dir,const char * name, int len,
                     90:        struct inode ** result)
                     91: {
                     92:        unsigned int pid;
                     93:        int i, ino;
                     94: 
                     95:        *result = NULL;
                     96:        if (!dir)
                     97:                return -ENOENT;
                     98:        if (!S_ISDIR(dir->i_mode)) {
                     99:                iput(dir);
                    100:                return -ENOENT;
                    101:        }
                    102:        ino = dir->i_ino;
                    103:        pid = ino >> 16;
                    104:        i = NR_BASE_DIRENTRY;
                    105:        while (i-- > 0 && !proc_match(len,name,base_dir+i))
                    106:                /* nothing */;
                    107:        if (i < 0) {
                    108:                iput(dir);
                    109:                return -ENOENT;
                    110:        }
                    111:        if (base_dir[i].low_ino == 1)
                    112:                ino = 1;
                    113:        else
                    114:                ino = (pid << 16) + base_dir[i].low_ino;
                    115:        for (i = 0 ; i < NR_TASKS ; i++)
                    116:                if (task[i] && task[i]->pid == pid)
                    117:                        break;
                    118:        if (!pid || i >= NR_TASKS) {
                    119:                iput(dir);
                    120:                return -ENOENT;
                    121:        }
                    122:        if (!(*result = iget(dir->i_dev,ino))) {
                    123:                iput(dir);
                    124:                return -ENOENT;
                    125:        }
                    126:        iput(dir);
                    127:        return 0;
                    128: }
                    129: 
                    130: static int proc_readbase(struct inode * inode, struct file * filp,
                    131:        struct dirent * dirent, int count)
                    132: {
                    133:        struct proc_dir_entry * de;
                    134:        unsigned int pid, ino;
                    135:        int i,j;
                    136: 
                    137:        if (!inode || !S_ISDIR(inode->i_mode))
                    138:                return -EBADF;
                    139:        ino = inode->i_ino;
                    140:        pid = ino >> 16;
                    141:        for (i = 0 ; i < NR_TASKS ; i++)
                    142:                if (task[i] && task[i]->pid == pid)
                    143:                        break;
                    144:        if (!pid || i >= NR_TASKS)
                    145:                return 0;
                    146:        if (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
                    147:                de = base_dir + filp->f_pos;
                    148:                filp->f_pos++;
                    149:                i = de->namelen;
                    150:                ino = de->low_ino;
                    151:                if (ino != 1)
                    152:                        ino |= (pid << 16);
                    153:                put_fs_long(ino, &dirent->d_ino);
                    154:                put_fs_word(i,&dirent->d_reclen);
                    155:                put_fs_byte(0,i+dirent->d_name);
                    156:                j = i;
                    157:                while (i--)
                    158:                        put_fs_byte(de->name[i], i+dirent->d_name);
                    159:                return j;
                    160:        }
                    161:        return 0;
                    162: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.