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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [proc/] [link.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/proc/link.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 *
6
 *  /proc link-file handling code
7
 */
8
 
9
/*
10
 * uClinux revisions for NO_MM
11
 * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
12
 *                     The Silver Hammer Group, Ltd.
13
 */
14
 
15
#include <asm/segment.h>
16
 
17
#include <linux/errno.h>
18
#include <linux/sched.h>
19
#include <linux/fs.h>
20
#include <linux/mm.h>
21
#include <linux/proc_fs.h>
22
#include <linux/stat.h>
23
 
24
static int proc_readlink(struct inode *, char *, int);
25
static int proc_follow_link(struct inode *, struct inode *, int, int,
26
                            struct inode **);
27
 
28
/*
29
 * PLAN9_SEMANTICS won't work any more: it used an ugly hack that broke
30
 * when the files[] array was updated only after the open code
31
 */
32
#undef PLAN9_SEMANTICS
33
 
34
/*
35
 * links can't do much...
36
 */
37
static struct file_operations proc_fd_link_operations = {
38
        NULL,                   /* lseek - default */
39
        NULL,                   /* read - bad */
40
        NULL,                   /* write - bad */
41
        NULL,                   /* readdir - bad */
42
        NULL,                   /* select - default */
43
        NULL,                   /* ioctl - default */
44
        NULL,                   /* mmap */
45
        NULL,                   /* very special open code */
46
        NULL,                   /* no special release code */
47
        NULL                    /* can't fsync */
48
};
49
 
50
struct inode_operations proc_link_inode_operations = {
51
        &proc_fd_link_operations,/* file-operations */
52
        NULL,                   /* create */
53
        NULL,                   /* lookup */
54
        NULL,                   /* link */
55
        NULL,                   /* unlink */
56
        NULL,                   /* symlink */
57
        NULL,                   /* mkdir */
58
        NULL,                   /* rmdir */
59
        NULL,                   /* mknod */
60
        NULL,                   /* rename */
61
        proc_readlink,          /* readlink */
62
        proc_follow_link,       /* follow_link */
63
        NULL,                   /* readpage */
64
        NULL,                   /* writepage */
65
        NULL,                   /* bmap */
66
        NULL,                   /* truncate */
67
        NULL                    /* permission */
68
};
69
 
70
 
71
static int proc_follow_link(struct inode * dir, struct inode * inode,
72
        int flag, int mode, struct inode ** res_inode)
73
{
74
        unsigned int pid, ino;
75
        struct task_struct * p;
76
        struct inode * new_inode;
77
        int i, error;
78
 
79
        *res_inode = NULL;
80
        if (dir)
81
                iput(dir);
82
        if (!inode)
83
                return -ENOENT;
84
        if ((error = permission(inode, MAY_EXEC)) != 0){
85
                iput(inode);
86
                return error;
87
        }
88
        ino = inode->i_ino;
89
        pid = ino >> 16;
90
        ino &= 0x0000ffff;
91
        for (i = 0 ; i < NR_TASKS ; i++)
92
                if ((p = task[i]) && p->pid == pid)
93
                        break;
94
        if (i >= NR_TASKS) {
95
                iput(inode);
96
                return -ENOENT;
97
        }
98
        new_inode = NULL;
99
        switch (ino) {
100
                case PROC_PID_CWD:
101
                        if (!p->fs)
102
                                break;
103
                        new_inode = p->fs->pwd;
104
                        break;
105
                case PROC_PID_ROOT:
106
                        if (!p->fs)
107
                                break;
108
                        new_inode = p->fs->root;
109
                        break;
110
#ifndef NO_MM
111
                case PROC_PID_EXE: {
112
                        struct vm_area_struct * vma;
113
                        if (!p->mm)
114
                                break;
115
                        vma = p->mm->mmap;
116
                        while (vma) {
117
                                if (vma->vm_flags & VM_EXECUTABLE) {
118
                                        new_inode = vma->vm_inode;
119
                                        break;
120
                                }
121
                                vma = vma->vm_next;
122
                        }
123
                        break;
124
                }
125
#else /* NO_MM */
126
                case PROC_PID_EXE: {
127
                        new_inode = p->mm->executable;
128
                        break;
129
                }
130
#endif /* NO_MM */
131
                default:
132
                        switch (ino >> 8) {
133
                        case PROC_PID_FD_DIR:
134
                                if (!p->files)
135
                                        break;
136
                                ino &= 0xff;
137
                                if (ino < NR_OPEN && p->files && p->files->fd[ino]) {
138
                                        new_inode = p->files->fd[ino]->f_inode;
139
                                }
140
                                break;
141
                        }
142
        }
143
        iput(inode);
144
        if (!new_inode)
145
                return -ENOENT;
146
        *res_inode = new_inode;
147
        new_inode->i_count++;
148
        return 0;
149
}
150
 
151
static int proc_readlink(struct inode * inode, char * buffer, int buflen)
152
{
153
        int i;
154
        unsigned int dev,ino;
155
        char buf[64];
156
 
157
        if (!S_ISLNK(inode->i_mode)) {
158
                iput(inode);
159
                return -EINVAL;
160
        }
161
        i = proc_follow_link(NULL, inode, 0, 0, &inode);
162
        if (i)
163
                return i;
164
        if (!inode)
165
                return -EIO;
166
        dev = kdev_t_to_nr(inode->i_dev);
167
        ino = inode->i_ino;
168
        iput(inode);
169
        i = sprintf(buf,"[%04x]:%u", dev, ino);
170
        if (buflen > i)
171
                buflen = i;
172
        i = 0;
173
        while (i < buflen)
174
                put_user(buf[i++],buffer++);
175
        return i;
176
}

powered by: WebSVN 2.1.0

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