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

1.1       root        1: /*
                      2:  *  linux/fs/proc/fd.c
                      3:  *
                      4:  *  Copyright (C) 1991, 1992 Linus Torvalds
                      5:  *
                      6:  *  proc fd 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_readfd(struct inode *, struct file *, struct dirent *, int);
                     17: static int proc_lookupfd(struct inode *,const char *,int,struct inode **);
                     18: 
                     19: static struct file_operations proc_fd_operations = {
                     20:        NULL,                   /* lseek - default */
                     21:        NULL,                   /* read - bad */
                     22:        NULL,                   /* write - bad */
                     23:        proc_readfd,            /* 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_fd_inode_operations = {
                     34:        &proc_fd_operations,    /* default base directory file-ops */
                     35:        NULL,                   /* create */
                     36:        proc_lookupfd,          /* 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: static int proc_lookupfd(struct inode * dir,const char * name, int len,
                     51:        struct inode ** result)
                     52: {
                     53:        unsigned int ino, pid, fd, c;
                     54:        struct task_struct * p;
                     55:        int i, dev;
                     56: 
                     57:        *result = NULL;
                     58:        ino = dir->i_ino;
                     59:        pid = ino >> 16;
                     60:        ino &= 0x0000ffff;
                     61:        ino -= 7;
                     62:        if (!dir)
                     63:                return -ENOENT;
                     64:        if (!pid || ino > 1 || !S_ISDIR(dir->i_mode)) {
                     65:                iput(dir);
                     66:                return -ENOENT;
                     67:        }
                     68:        if (!len || (get_fs_byte(name) == '.' && (len == 1 ||
                     69:            (get_fs_byte(name+1) == '.' && len == 2)))) {
                     70:                if (len < 2) {
                     71:                        *result = dir;
                     72:                        return 0;
                     73:                }
                     74:                if (!(*result = iget(dir->i_dev,(pid << 16)+2))) {
                     75:                        iput(dir);
                     76:                        return -ENOENT;
                     77:                }
                     78:                iput(dir);
                     79:                return 0;
                     80:        }
                     81:        dev = dir->i_dev;
                     82:        iput(dir);
                     83:        fd = 0;
                     84:        while (len-- > 0) {
                     85:                c = get_fs_byte(name) - '0';
                     86:                name++;
                     87:                if (c > 9) {
                     88:                        fd = 0xfffff;
                     89:                        break;
                     90:                }
                     91:                fd *= 10;
                     92:                fd += c;
                     93:                if (fd & 0xffff0000) {
                     94:                        fd = 0xfffff;
                     95:                        break;
                     96:                }
                     97:        }
                     98:        for (i = 0 ; i < NR_TASKS ; i++)
                     99:                if ((p = task[i]) && p->pid == pid)
                    100:                        break;
                    101:        if (!pid || i >= NR_TASKS)
                    102:                return -ENOENT;
                    103:        if (!ino) {
                    104:                if (fd >= NR_OPEN || !p->filp[fd] || !p->filp[fd]->f_inode)
                    105:                        return -ENOENT;
                    106:                ino = (pid << 16) + 0x100 + fd;
                    107:        } else {
                    108:                if (fd >= p->numlibraries)
                    109:                        return -ENOENT;
                    110:                ino = (pid << 16) + 0x200 + fd;
                    111:        }
                    112:        if (!(*result = iget(dev,ino)))
                    113:                return -ENOENT;
                    114:        return 0;
                    115: }
                    116: 
                    117: static int proc_readfd(struct inode * inode, struct file * filp,
                    118:        struct dirent * dirent, int count)
                    119: {
                    120:        struct task_struct * p;
                    121:        unsigned int fd, pid, ino;
                    122:        int i,j;
                    123: 
                    124:        if (!inode || !S_ISDIR(inode->i_mode))
                    125:                return -EBADF;
                    126:        ino = inode->i_ino;
                    127:        pid = ino >> 16;
                    128:        ino &= 0x0000ffff;
                    129:        ino -= 7;
                    130:        if (ino > 1)
                    131:                return 0;
                    132:        while (1) {
                    133:                fd = filp->f_pos;
                    134:                filp->f_pos++;
                    135:                if (fd < 2) {
                    136:                        i = j = fd+1;
                    137:                        if (!fd)
                    138:                                fd = inode->i_ino;
                    139:                        else
                    140:                                fd = (inode->i_ino & 0xffff0000) | 2;
                    141:                        put_fs_long(fd, &dirent->d_ino);
                    142:                        put_fs_word(i, &dirent->d_reclen);
                    143:                        put_fs_byte(0, i+dirent->d_name);
                    144:                        while (i--)
                    145:                                put_fs_byte('.', i+dirent->d_name);
                    146:                        return j;
                    147:                }
                    148:                fd -= 2;
                    149:                for (i = 1 ; i < NR_TASKS ; i++)
                    150:                        if ((p = task[i]) && p->pid == pid)
                    151:                                break;
                    152:                if (i >= NR_TASKS)
                    153:                        return 0;
                    154:                if (!ino) {
                    155:                        if (fd >= NR_OPEN)
                    156:                                break;
                    157:                        if (!p->filp[fd] || !p->filp[fd]->f_inode)
                    158:                                continue;
                    159:                } else
                    160:                        if (fd >= p->numlibraries)
                    161:                                break;
                    162:                j = 10;
                    163:                i = 1;
                    164:                while (fd >= j) {
                    165:                        j *= 10;
                    166:                        i++;
                    167:                }
                    168:                j = i;
                    169:                if (!ino)
                    170:                        ino = (pid << 16) + 0x100 + fd;
                    171:                else
                    172:                        ino = (pid << 16) + 0x200 + fd;
                    173:                put_fs_long(ino, &dirent->d_ino);
                    174:                put_fs_word(i, &dirent->d_reclen);
                    175:                put_fs_byte(0, i+dirent->d_name);
                    176:                while (i--) {
                    177:                        put_fs_byte('0'+(fd % 10), i+dirent->d_name);
                    178:                        fd /= 10;
                    179:                }
                    180:                return j;
                    181:        }
                    182:        return 0;
                    183: }

unix.superglobalmegacorp.com

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