OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [proc/] [fd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
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 *, void *, filldir_t);
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,                   /* mmap */
27
        NULL,                   /* no special open code */
28
        NULL,                   /* no special release code */
29
        NULL                    /* can't fsync */
30
};
31
 
32
/*
33
 * proc directories can do almost nothing..
34
 */
35
struct inode_operations proc_fd_inode_operations = {
36
        &proc_fd_operations,    /* default base directory file-ops */
37
        NULL,                   /* create */
38
        proc_lookupfd,          /* lookup */
39
        NULL,                   /* link */
40
        NULL,                   /* unlink */
41
        NULL,                   /* symlink */
42
        NULL,                   /* mkdir */
43
        NULL,                   /* rmdir */
44
        NULL,                   /* mknod */
45
        NULL,                   /* rename */
46
        NULL,                   /* readlink */
47
        NULL,                   /* follow_link */
48
        NULL,                   /* readpage */
49
        NULL,                   /* writepage */
50
        NULL,                   /* bmap */
51
        NULL,                   /* truncate */
52
        NULL                    /* permission */
53
};
54
 
55
static int proc_lookupfd(struct inode * dir, const char * name, int len,
56
        struct inode ** result)
57
{
58
        unsigned int ino, pid, fd, c;
59
        struct task_struct * p;
60
        struct super_block * sb;
61
        int i;
62
 
63
        *result = NULL;
64
        ino = dir->i_ino;
65
        pid = ino >> 16;
66
        ino &= 0x0000ffff;
67
        if (!dir)
68
                return -ENOENT;
69
        sb = dir->i_sb;
70
        if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) {
71
                iput(dir);
72
                return -ENOENT;
73
        }
74
        if (!len || (name[0] == '.' && (len == 1 ||
75
            (name[1] == '.' && len == 2)))) {
76
                if (len < 2) {
77
                        *result = dir;
78
                        return 0;
79
                }
80
                if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) {
81
                        iput(dir);
82
                        return -ENOENT;
83
                }
84
                iput(dir);
85
                return 0;
86
        }
87
        iput(dir);
88
        fd = 0;
89
        while (len-- > 0) {
90
                c = *name - '0';
91
                name++;
92
                if (c > 9) {
93
                        fd = 0xfffff;
94
                        break;
95
                }
96
                fd *= 10;
97
                fd += c;
98
                if (fd & 0xffff0000) {
99
                        fd = 0xfffff;
100
                        break;
101
                }
102
        }
103
        for (i = 0 ; i < NR_TASKS ; i++)
104
                if ((p = task[i]) && p->pid == pid)
105
                        break;
106
        if (!pid || i >= NR_TASKS)
107
                return -ENOENT;
108
 
109
        if (fd >= NR_OPEN || !p->files || !p->files->fd[fd]
110
                || !p->files->fd[fd]->f_inode)
111
                return -ENOENT;
112
 
113
        ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
114
 
115
        if (!(*result = proc_get_inode(sb, ino, NULL)))
116
                return -ENOENT;
117
        return 0;
118
}
119
 
120
#define NUMBUF 10
121
 
122
static int proc_readfd(struct inode * inode, struct file * filp,
123
        void * dirent, filldir_t filldir)
124
{
125
        char buf[NUMBUF];
126
        int task_nr;
127
        struct task_struct * p;
128
        unsigned int fd, pid, ino;
129
        unsigned long i,j;
130
 
131
        if (!inode || !S_ISDIR(inode->i_mode))
132
                return -EBADF;
133
        ino = inode->i_ino;
134
        pid = ino >> 16;
135
        ino &= 0x0000ffff;
136
        if (ino != PROC_PID_FD)
137
                return 0;
138
 
139
        for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
140
                unsigned long ino = inode->i_ino;
141
                if (fd)
142
                        ino = (ino & 0xffff0000) | PROC_PID_INO;
143
                if (filldir(dirent, "..", fd+1, fd, ino) < 0)
144
                        return 0;
145
        }
146
 
147
        task_nr = 1;
148
        for (;;) {
149
                if ((p = task[task_nr]) && p->pid == pid)
150
                        break;
151
                if (++task_nr >= NR_TASKS)
152
                        return 0;
153
        }
154
 
155
        for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
156
                if (!p->files)
157
                        break;
158
                if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
159
                        continue;
160
 
161
                j = NUMBUF;
162
                i = fd;
163
                do {
164
                        j--;
165
                        buf[j] = '0' + (i % 10);
166
                        i /= 10;
167
                } while (i);
168
 
169
                ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
170
                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
171
                        break;
172
 
173
                /* filldir() might have slept, so we must re-validate "p" */
174
                if (p != task[task_nr] || p->pid != pid)
175
                        break;
176
        }
177
        return 0;
178
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.