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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [proc/] [base.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/fs/proc/base.c
3
 *
4
 *  Copyright (C) 1991, 1992 Linus Torvalds
5
 *
6
 *  proc base directory handling functions
7
 *
8
 *  1999, Al Viro. Rewritten. Now it covers the whole per-process part.
9
 *  Instead of using magical inumbers to determine the kind of object
10
 *  we allocate and fill in-core inodes upon lookup. They don't even
11
 *  go into icache. We cache the reference to task_struct upon lookup too.
12
 *  Eventually it should become a filesystem in its own. We don't use the
13
 *  rest of procfs anymore.
14
 */
15
 
16
#include <asm/uaccess.h>
17
 
18
#include <linux/config.h>
19
#include <linux/errno.h>
20
#include <linux/sched.h>
21
#include <linux/proc_fs.h>
22
#include <linux/stat.h>
23
#include <linux/init.h>
24
#include <linux/file.h>
25
#include <linux/string.h>
26
#include <linux/seq_file.h>
27
#include <linux/namespace.h>
28
 
29
/*
30
 * For hysterical raisins we keep the same inumbers as in the old procfs.
31
 * Feel free to change the macro below - just keep the range distinct from
32
 * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
33
 * As soon as we'll get a separate superblock we will be able to forget
34
 * about magical ranges too.
35
 */
36
 
37
#define fake_ino(pid,ino) (((pid)<<16)|(ino))
38
 
39
int proc_pid_stat(struct task_struct*,char*);
40
int proc_pid_status(struct task_struct*,char*);
41
int proc_pid_statm(struct task_struct*,char*);
42
int proc_pid_cpu(struct task_struct*,char*);
43
 
44
static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
45
{
46
        if (inode->u.proc_i.file) {
47
                *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
48
                *dentry = dget(inode->u.proc_i.file->f_dentry);
49
                return 0;
50
        }
51
        return -ENOENT;
52
}
53
 
54
static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
55
{
56
        struct mm_struct * mm;
57
        struct vm_area_struct * vma;
58
        int result = -ENOENT;
59
        struct task_struct *task = inode->u.proc_i.task;
60
 
61
        task_lock(task);
62
        mm = task->mm;
63
        if (mm)
64
                atomic_inc(&mm->mm_users);
65
        task_unlock(task);
66
        if (!mm)
67
                goto out;
68
        down_read(&mm->mmap_sem);
69
        vma = mm->mmap;
70
        while (vma) {
71
                if ((vma->vm_flags & VM_EXECUTABLE) &&
72
                    vma->vm_file) {
73
                        *mnt = mntget(vma->vm_file->f_vfsmnt);
74
                        *dentry = dget(vma->vm_file->f_dentry);
75
                        result = 0;
76
                        break;
77
                }
78
                vma = vma->vm_next;
79
        }
80
        up_read(&mm->mmap_sem);
81
        mmput(mm);
82
out:
83
        return result;
84
}
85
 
86
static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
87
{
88
        struct fs_struct *fs;
89
        int result = -ENOENT;
90
        task_lock(inode->u.proc_i.task);
91
        fs = inode->u.proc_i.task->fs;
92
        if(fs)
93
                atomic_inc(&fs->count);
94
        task_unlock(inode->u.proc_i.task);
95
        if (fs) {
96
                read_lock(&fs->lock);
97
                *mnt = mntget(fs->pwdmnt);
98
                *dentry = dget(fs->pwd);
99
                read_unlock(&fs->lock);
100
                result = 0;
101
                put_fs_struct(fs);
102
        }
103
        return result;
104
}
105
 
106
static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
107
{
108
        struct fs_struct *fs;
109
        int result = -ENOENT;
110
        task_lock(inode->u.proc_i.task);
111
        fs = inode->u.proc_i.task->fs;
112
        if(fs)
113
                atomic_inc(&fs->count);
114
        task_unlock(inode->u.proc_i.task);
115
        if (fs) {
116
                read_lock(&fs->lock);
117
                *mnt = mntget(fs->rootmnt);
118
                *dentry = dget(fs->root);
119
                read_unlock(&fs->lock);
120
                result = 0;
121
                put_fs_struct(fs);
122
        }
123
        return result;
124
}
125
 
126
#define MAY_PTRACE(task) \
127
        (task == current || \
128
        (task->p_pptr == current && \
129
        (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED))
130
 
131
static int may_ptrace_attach(struct task_struct *task)
132
{
133
        int retval = 0;
134
 
135
        task_lock(task);
136
 
137
        if (((current->uid != task->euid) ||
138
            (current->uid != task->suid) ||
139
            (current->uid != task->uid) ||
140
            (current->gid != task->egid) ||
141
            (current->gid != task->sgid) ||
142
            (!cap_issubset(task->cap_permitted, current->cap_permitted)) ||
143
            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
144
                goto out;
145
        rmb();
146
        if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE))
147
                goto out;
148
 
149
        retval = 1;
150
 
151
out:
152
        task_unlock(task);
153
        return retval;
154
}
155
 
156
static int proc_pid_environ(struct task_struct *task, char * buffer)
157
{
158
        struct mm_struct *mm;
159
        int res = 0;
160
 
161
        if (!may_ptrace_attach(task))
162
                return -ESRCH;
163
 
164
        task_lock(task);
165
        mm = task->mm;
166
        if (mm)
167
                atomic_inc(&mm->mm_users);
168
        task_unlock(task);
169
        if (mm) {
170
                unsigned int len = mm->env_end - mm->env_start;
171
                if (len > PAGE_SIZE)
172
                        len = PAGE_SIZE;
173
                res = access_process_vm(task, mm->env_start, buffer, len, 0);
174
                if (!may_ptrace_attach(task))
175
                        res = -ESRCH;
176
                mmput(mm);
177
        }
178
        return res;
179
}
180
 
181
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
182
{
183
        struct mm_struct *mm;
184
        int res = 0;
185
        task_lock(task);
186
        mm = task->mm;
187
        if (mm)
188
                atomic_inc(&mm->mm_users);
189
        task_unlock(task);
190
        if (mm) {
191
                int len = mm->arg_end - mm->arg_start;
192
                if (len > PAGE_SIZE)
193
                        len = PAGE_SIZE;
194
                res = access_process_vm(task, mm->arg_start, buffer, len, 0);
195
                // If the nul at the end of args has been overwritten, then
196
                // assume application is using setproctitle(3).
197
                if ( res > 0 && buffer[res-1] != '\0' )
198
                {
199
                        len = strnlen( buffer, res );
200
                        if ( len < res )
201
                        {
202
                            res = len;
203
                        }
204
                        else
205
                        {
206
                                len = mm->env_end - mm->env_start;
207
                                if (len > PAGE_SIZE - res)
208
                                        len = PAGE_SIZE - res;
209
                                res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
210
                                res = strnlen( buffer, res );
211
                        }
212
                }
213
                mmput(mm);
214
        }
215
        return res;
216
}
217
 
218
/************************************************************************/
219
/*                       Here the fs part begins                        */
220
/************************************************************************/
221
 
222
/* permission checks */
223
 
224
static int proc_check_root(struct inode *inode)
225
{
226
        struct dentry *de, *base, *root;
227
        struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
228
        int res = 0;
229
 
230
        if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
231
                return -ENOENT;
232
        read_lock(&current->fs->lock);
233
        our_vfsmnt = mntget(current->fs->rootmnt);
234
        base = dget(current->fs->root);
235
        read_unlock(&current->fs->lock);
236
 
237
        spin_lock(&dcache_lock);
238
        de = root;
239
        mnt = vfsmnt;
240
 
241
        while (vfsmnt != our_vfsmnt) {
242
                if (vfsmnt == vfsmnt->mnt_parent)
243
                        goto out;
244
                de = vfsmnt->mnt_mountpoint;
245
                vfsmnt = vfsmnt->mnt_parent;
246
        }
247
 
248
        if (!is_subdir(de, base))
249
                goto out;
250
        spin_unlock(&dcache_lock);
251
 
252
exit:
253
        dput(base);
254
        mntput(our_vfsmnt);
255
        dput(root);
256
        mntput(mnt);
257
        return res;
258
out:
259
        spin_unlock(&dcache_lock);
260
        res = -EACCES;
261
        goto exit;
262
}
263
 
264
static int proc_permission(struct inode *inode, int mask)
265
{
266
        if (vfs_permission(inode, mask) != 0)
267
                return -EACCES;
268
        return proc_check_root(inode);
269
}
270
 
271
extern struct seq_operations proc_pid_maps_op;
272
static int maps_open(struct inode *inode, struct file *file)
273
{
274
        struct task_struct *task = inode->u.proc_i.task;
275
        int ret = seq_open(file, &proc_pid_maps_op);
276
        if (!ret) {
277
                struct seq_file *m = file->private_data;
278
                m->private = task;
279
        }
280
        return ret;
281
}
282
 
283
static struct file_operations proc_maps_operations = {
284
        .open           = maps_open,
285
        .read           = seq_read,
286
        .llseek         = seq_lseek,
287
        .release        = seq_release,
288
};
289
 
290
extern struct seq_operations mounts_op;
291
static int mounts_open(struct inode *inode, struct file *file)
292
{
293
        struct task_struct *task = inode->u.proc_i.task;
294
        int ret = seq_open(file, &mounts_op);
295
 
296
        if (!ret) {
297
                struct seq_file *m = file->private_data;
298
                struct namespace *namespace;
299
                task_lock(task);
300
                namespace = task->namespace;
301
                if (namespace)
302
                        get_namespace(namespace);
303
                task_unlock(task);
304
 
305
                if (namespace)
306
                        m->private = namespace;
307
                else {
308
                        seq_release(inode, file);
309
                        ret = -EINVAL;
310
                }
311
        }
312
        return ret;
313
}
314
 
315
static int mounts_release(struct inode *inode, struct file *file)
316
{
317
        struct seq_file *m = file->private_data;
318
        struct namespace *namespace = m->private;
319
        put_namespace(namespace);
320
        return seq_release(inode, file);
321
}
322
 
323
static struct file_operations proc_mounts_operations = {
324
        open:           mounts_open,
325
        read:           seq_read,
326
        llseek:         seq_lseek,
327
        release:        mounts_release,
328
};
329
 
330
#define PROC_BLOCK_SIZE (3*1024)                /* 4K page size but our output routines use some slack for overruns */
331
 
332
static ssize_t proc_info_read(struct file * file, char * buf,
333
                          size_t count, loff_t *ppos)
334
{
335
        struct inode * inode = file->f_dentry->d_inode;
336
        unsigned long page;
337
        ssize_t length;
338
        ssize_t end;
339
        struct task_struct *task = inode->u.proc_i.task;
340
 
341
        if (count > PROC_BLOCK_SIZE)
342
                count = PROC_BLOCK_SIZE;
343
        if (!(page = __get_free_page(GFP_KERNEL)))
344
                return -ENOMEM;
345
 
346
        length = inode->u.proc_i.op.proc_read(task, (char*)page);
347
 
348
        if (length < 0) {
349
                free_page(page);
350
                return length;
351
        }
352
        /* Static 4kB (or whatever) block capacity */
353
        if (*ppos >= length) {
354
                free_page(page);
355
                return 0;
356
        }
357
        if (count + *ppos > length)
358
                count = length - *ppos;
359
        end = count + *ppos;
360
        copy_to_user(buf, (char *) page + *ppos, count);
361
        *ppos = end;
362
        free_page(page);
363
        return count;
364
}
365
 
366
static struct file_operations proc_info_file_operations = {
367
        read:           proc_info_read,
368
};
369
 
370
static int mem_open(struct inode* inode, struct file* file)
371
{
372
        file->private_data = (void*)((long)current->self_exec_id);
373
        return 0;
374
}
375
 
376
static ssize_t mem_read(struct file * file, char * buf,
377
                        size_t count, loff_t *ppos)
378
{
379
        struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
380
        char *page;
381
        unsigned long src = *ppos;
382
        int copied = 0;
383
        struct mm_struct *mm;
384
 
385
        if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
386
                return -ESRCH;
387
 
388
        page = (char *)__get_free_page(GFP_USER);
389
        if (!page)
390
                return -ENOMEM;
391
 
392
        task_lock(task);
393
        mm = task->mm;
394
        if (mm)
395
                atomic_inc(&mm->mm_users);
396
        task_unlock(task);
397
        if (!mm){
398
                copied = 0;
399
                goto out_free;
400
        }
401
 
402
        if (file->private_data != (void*)((long)current->self_exec_id) ) {
403
                mmput(mm);
404
                copied = -EIO;
405
                goto out_free;
406
        }
407
 
408
        while (count > 0) {
409
                int this_len, retval;
410
 
411
                this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
412
                retval = access_process_vm(task, src, page, this_len, 0);
413
                if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) {
414
                        if (!copied)
415
                                copied = -EIO;
416
                        break;
417
                }
418
                if (copy_to_user(buf, page, retval)) {
419
                        copied = -EFAULT;
420
                        break;
421
                }
422
                copied += retval;
423
                src += retval;
424
                buf += retval;
425
                count -= retval;
426
        }
427
        *ppos = src;
428
        mmput(mm);
429
 
430
out_free:
431
        free_page((unsigned long) page);
432
        return copied;
433
}
434
 
435
#define mem_write NULL
436
 
437
#ifndef mem_write
438
/* This is a security hazard */
439
static ssize_t mem_write(struct file * file, const char * buf,
440
                         size_t count, loff_t *ppos)
441
{
442
        int copied = 0;
443
        char *page;
444
        struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
445
        unsigned long dst = *ppos;
446
 
447
        if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
448
                return -ESRCH;
449
 
450
        page = (char *)__get_free_page(GFP_USER);
451
        if (!page)
452
                return -ENOMEM;
453
 
454
        while (count > 0) {
455
                int this_len, retval;
456
 
457
                this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
458
                if (copy_from_user(page, buf, this_len)) {
459
                        copied = -EFAULT;
460
                        break;
461
                }
462
                retval = access_process_vm(task, dst, page, this_len, 1);
463
                if (!retval) {
464
                        if (!copied)
465
                                copied = -EIO;
466
                        break;
467
                }
468
                copied += retval;
469
                buf += retval;
470
                dst += retval;
471
                count -= retval;
472
        }
473
        *ppos = dst;
474
        free_page((unsigned long) page);
475
        return copied;
476
}
477
#endif
478
 
479
static loff_t mem_lseek(struct file * file, loff_t offset, int orig)
480
{
481
        switch (orig) {
482
        case 0:
483
                file->f_pos = offset;
484
                break;
485
        case 1:
486
                file->f_pos += offset;
487
                break;
488
        default:
489
                return -EINVAL;
490
        }
491
        force_successful_syscall_return();
492
        return file->f_pos;
493
}
494
 
495
static struct file_operations proc_mem_operations = {
496
        llseek:         mem_lseek,
497
        read:           mem_read,
498
        write:          mem_write,
499
        open:           mem_open,
500
};
501
 
502
static struct inode_operations proc_mem_inode_operations = {
503
        permission:     proc_permission,
504
};
505
 
506
static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
507
{
508
        struct inode *inode = dentry->d_inode;
509
        int error = -EACCES;
510
 
511
        /* We don't need a base pointer in the /proc filesystem */
512
        path_release(nd);
513
 
514
        if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
515
                goto out;
516
        error = proc_check_root(inode);
517
        if (error)
518
                goto out;
519
 
520
        error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
521
        nd->last_type = LAST_BIND;
522
out:
523
        return error;
524
}
525
 
526
static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
527
                            char * buffer, int buflen)
528
{
529
        struct inode * inode;
530
        char * tmp = (char*)__get_free_page(GFP_KERNEL), *path;
531
        int len;
532
 
533
        if (!tmp)
534
                return -ENOMEM;
535
 
536
        inode = dentry->d_inode;
537
        path = d_path(dentry, mnt, tmp, PAGE_SIZE);
538
        if (IS_ERR(path)) {
539
                free_page((unsigned long)tmp);
540
                return PTR_ERR(path);
541
        }
542
        len = tmp + PAGE_SIZE - 1 - path;
543
 
544
        if (len < buflen)
545
                buflen = len;
546
        copy_to_user(buffer, path, buflen);
547
        free_page((unsigned long)tmp);
548
        return buflen;
549
}
550
 
551
static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
552
{
553
        int error = -EACCES;
554
        struct inode *inode = dentry->d_inode;
555
        struct dentry *de;
556
        struct vfsmount *mnt = NULL;
557
 
558
        if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
559
                goto out;
560
        error = proc_check_root(inode);
561
        if (error)
562
                goto out;
563
 
564
        error = inode->u.proc_i.op.proc_get_link(inode, &de, &mnt);
565
        if (error)
566
                goto out;
567
 
568
        error = do_proc_readlink(de, mnt, buffer, buflen);
569
        dput(de);
570
        mntput(mnt);
571
out:
572
        return error;
573
}
574
 
575
static struct inode_operations proc_pid_link_inode_operations = {
576
        readlink:       proc_pid_readlink,
577
        follow_link:    proc_pid_follow_link
578
};
579
 
580
struct pid_entry {
581
        int type;
582
        int len;
583
        char *name;
584
        mode_t mode;
585
};
586
 
587
enum pid_directory_inos {
588
        PROC_PID_INO = 2,
589
        PROC_PID_STATUS,
590
        PROC_PID_MEM,
591
        PROC_PID_CWD,
592
        PROC_PID_ROOT,
593
        PROC_PID_EXE,
594
        PROC_PID_FD,
595
        PROC_PID_ENVIRON,
596
        PROC_PID_CMDLINE,
597
        PROC_PID_STAT,
598
        PROC_PID_STATM,
599
        PROC_PID_MAPS,
600
        PROC_PID_CPU,
601
        PROC_PID_MOUNTS,
602
        PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
603
};
604
 
605
#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
606
static struct pid_entry base_stuff[] = {
607
  E(PROC_PID_FD,        "fd",           S_IFDIR|S_IRUSR|S_IXUSR),
608
  E(PROC_PID_ENVIRON,   "environ",      S_IFREG|S_IRUSR),
609
  E(PROC_PID_STATUS,    "status",       S_IFREG|S_IRUGO),
610
  E(PROC_PID_CMDLINE,   "cmdline",      S_IFREG|S_IRUGO),
611
  E(PROC_PID_STAT,      "stat",         S_IFREG|S_IRUGO),
612
  E(PROC_PID_STATM,     "statm",        S_IFREG|S_IRUGO),
613
#ifdef CONFIG_SMP
614
  E(PROC_PID_CPU,       "cpu",          S_IFREG|S_IRUGO),
615
#endif
616
  E(PROC_PID_MAPS,      "maps",         S_IFREG|S_IRUGO),
617
  E(PROC_PID_MEM,       "mem",          S_IFREG|S_IRUSR|S_IWUSR),
618
  E(PROC_PID_CWD,       "cwd",          S_IFLNK|S_IRWXUGO),
619
  E(PROC_PID_ROOT,      "root",         S_IFLNK|S_IRWXUGO),
620
  E(PROC_PID_EXE,       "exe",          S_IFLNK|S_IRWXUGO),
621
  E(PROC_PID_MOUNTS,    "mounts",       S_IFREG|S_IRUGO),
622
  {0,0,NULL,0}
623
};
624
#undef E
625
 
626
#define NUMBUF 10
627
 
628
static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
629
{
630
        struct inode *inode = filp->f_dentry->d_inode;
631
        struct task_struct *p = inode->u.proc_i.task;
632
        unsigned int fd, pid, ino;
633
        int retval;
634
        char buf[NUMBUF];
635
        struct files_struct * files;
636
 
637
        retval = 0;
638
        pid = p->pid;
639
 
640
        fd = filp->f_pos;
641
        switch (fd) {
642
                case 0:
643
                        if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
644
                                goto out;
645
                        filp->f_pos++;
646
                case 1:
647
                        ino = fake_ino(pid, PROC_PID_INO);
648
                        if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
649
                                goto out;
650
                        filp->f_pos++;
651
                default:
652
                        task_lock(p);
653
                        files = p->files;
654
                        if (files)
655
                                atomic_inc(&files->count);
656
                        task_unlock(p);
657
                        if (!files)
658
                                goto out;
659
                        read_lock(&files->file_lock);
660
                        for (fd = filp->f_pos-2;
661
                             fd < files->max_fds;
662
                             fd++, filp->f_pos++) {
663
                                unsigned int i,j;
664
 
665
                                if (!fcheck_files(files, fd))
666
                                        continue;
667
                                read_unlock(&files->file_lock);
668
 
669
                                j = NUMBUF;
670
                                i = fd;
671
                                do {
672
                                        j--;
673
                                        buf[j] = '0' + (i % 10);
674
                                        i /= 10;
675
                                } while (i);
676
 
677
                                ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
678
                                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
679
                                        read_lock(&files->file_lock);
680
                                        break;
681
                                }
682
                                read_lock(&files->file_lock);
683
                        }
684
                        read_unlock(&files->file_lock);
685
                        put_files_struct(files);
686
        }
687
out:
688
        return retval;
689
}
690
 
691
static int proc_base_readdir(struct file * filp,
692
        void * dirent, filldir_t filldir)
693
{
694
        int i;
695
        int pid;
696
        struct inode *inode = filp->f_dentry->d_inode;
697
        struct pid_entry *p;
698
 
699
        pid = inode->u.proc_i.task->pid;
700
        if (!pid)
701
                return -ENOENT;
702
        i = filp->f_pos;
703
        switch (i) {
704
                case 0:
705
                        if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
706
                                return 0;
707
                        i++;
708
                        filp->f_pos++;
709
                        /* fall through */
710
                case 1:
711
                        if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
712
                                return 0;
713
                        i++;
714
                        filp->f_pos++;
715
                        /* fall through */
716
                default:
717
                        i -= 2;
718
                        if (i>=sizeof(base_stuff)/sizeof(base_stuff[0]))
719
                                return 1;
720
                        p = base_stuff + i;
721
                        while (p->name) {
722
                                if (filldir(dirent, p->name, p->len, filp->f_pos,
723
                                            fake_ino(pid, p->type), p->mode >> 12) < 0)
724
                                        return 0;
725
                                filp->f_pos++;
726
                                p++;
727
                        }
728
        }
729
        return 1;
730
}
731
 
732
/* building an inode */
733
 
734
static int task_dumpable(struct task_struct *task)
735
{
736
        int dumpable = 0;
737
        struct mm_struct *mm;
738
 
739
        task_lock(task);
740
        mm = task->mm;
741
        if (mm)
742
                dumpable = mm->dumpable;
743
        task_unlock(task);
744
        return dumpable;
745
}
746
 
747
 
748
static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
749
{
750
        struct inode * inode;
751
 
752
        /* We need a new inode */
753
 
754
        inode = new_inode(sb);
755
        if (!inode)
756
                goto out;
757
 
758
        /* Common stuff */
759
 
760
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
761
        inode->i_ino = fake_ino(task->pid, ino);
762
 
763
        if (!task->pid)
764
                goto out_unlock;
765
 
766
        /*
767
         * grab the reference to task.
768
         */
769
        get_task_struct(task);
770
        inode->u.proc_i.task = task;
771
        inode->i_uid = 0;
772
        inode->i_gid = 0;
773
        if (ino == PROC_PID_INO || task_dumpable(task)) {
774
                inode->i_uid = task->euid;
775
                inode->i_gid = task->egid;
776
        }
777
 
778
out:
779
        return inode;
780
 
781
out_unlock:
782
        iput(inode);
783
        return NULL;
784
}
785
 
786
/* dentry stuff */
787
 
788
static int pid_fd_revalidate(struct dentry * dentry, int flags)
789
{
790
        return 0;
791
}
792
 
793
/*
794
 *      Exceptional case: normally we are not allowed to unhash a busy
795
 * directory. In this case, however, we can do it - no aliasing problems
796
 * due to the way we treat inodes.
797
 */
798
static int pid_base_revalidate(struct dentry * dentry, int flags)
799
{
800
        if (dentry->d_inode->u.proc_i.task->pid)
801
                return 1;
802
        d_drop(dentry);
803
        return 0;
804
}
805
 
806
static int pid_delete_dentry(struct dentry * dentry)
807
{
808
        return 1;
809
}
810
 
811
static struct dentry_operations pid_fd_dentry_operations =
812
{
813
        d_revalidate:   pid_fd_revalidate,
814
        d_delete:       pid_delete_dentry,
815
};
816
 
817
static struct dentry_operations pid_dentry_operations =
818
{
819
        d_delete:       pid_delete_dentry,
820
};
821
 
822
static struct dentry_operations pid_base_dentry_operations =
823
{
824
        d_revalidate:   pid_base_revalidate,
825
        d_delete:       pid_delete_dentry,
826
};
827
 
828
/* Lookups */
829
#define MAX_MULBY10     ((~0U-9)/10)
830
 
831
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
832
{
833
        unsigned int fd, c;
834
        struct task_struct *task = dir->u.proc_i.task;
835
        struct file * file;
836
        struct files_struct * files;
837
        struct inode *inode;
838
        const char *name;
839
        int len;
840
 
841
        fd = 0;
842
        len = dentry->d_name.len;
843
        name = dentry->d_name.name;
844
        if (len > 1 && *name == '0') goto out;
845
        while (len-- > 0) {
846
                c = *name - '0';
847
                name++;
848
                if (c > 9)
849
                        goto out;
850
                if (fd >= MAX_MULBY10)
851
                        goto out;
852
                fd *= 10;
853
                fd += c;
854
        }
855
 
856
        inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
857
        if (!inode)
858
                goto out;
859
        task_lock(task);
860
        files = task->files;
861
        if (files)
862
                atomic_inc(&files->count);
863
        task_unlock(task);
864
        if (!files)
865
                goto out_unlock;
866
        read_lock(&files->file_lock);
867
        file = inode->u.proc_i.file = fcheck_files(files, fd);
868
        if (!file)
869
                goto out_unlock2;
870
        get_file(file);
871
        read_unlock(&files->file_lock);
872
        put_files_struct(files);
873
        inode->i_op = &proc_pid_link_inode_operations;
874
        inode->i_size = 64;
875
        inode->i_mode = S_IFLNK;
876
        inode->u.proc_i.op.proc_get_link = proc_fd_link;
877
        if (file->f_mode & 1)
878
                inode->i_mode |= S_IRUSR | S_IXUSR;
879
        if (file->f_mode & 2)
880
                inode->i_mode |= S_IWUSR | S_IXUSR;
881
        dentry->d_op = &pid_fd_dentry_operations;
882
        d_add(dentry, inode);
883
        return NULL;
884
 
885
out_unlock2:
886
        put_files_struct(files);
887
        read_unlock(&files->file_lock);
888
out_unlock:
889
        iput(inode);
890
out:
891
        return ERR_PTR(-ENOENT);
892
}
893
 
894
static struct file_operations proc_fd_operations = {
895
        read:           generic_read_dir,
896
        readdir:        proc_readfd,
897
};
898
 
899
/*
900
 * proc directories can do almost nothing..
901
 */
902
static struct inode_operations proc_fd_inode_operations = {
903
        lookup:         proc_lookupfd,
904
        permission:     proc_permission,
905
};
906
 
907
static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
908
{
909
        struct inode *inode;
910
        int error;
911
        struct task_struct *task = dir->u.proc_i.task;
912
        struct pid_entry *p;
913
 
914
        error = -ENOENT;
915
        inode = NULL;
916
 
917
        for (p = base_stuff; p->name; p++) {
918
                if (p->len != dentry->d_name.len)
919
                        continue;
920
                if (!memcmp(dentry->d_name.name, p->name, p->len))
921
                        break;
922
        }
923
        if (!p->name)
924
                goto out;
925
 
926
        error = -EINVAL;
927
        inode = proc_pid_make_inode(dir->i_sb, task, p->type);
928
        if (!inode)
929
                goto out;
930
 
931
        inode->i_mode = p->mode;
932
        /*
933
         * Yes, it does not scale. And it should not. Don't add
934
         * new entries into /proc/<pid>/ without very good reasons.
935
         */
936
        switch(p->type) {
937
                case PROC_PID_FD:
938
                        inode->i_nlink = 2;
939
                        inode->i_op = &proc_fd_inode_operations;
940
                        inode->i_fop = &proc_fd_operations;
941
                        break;
942
                case PROC_PID_EXE:
943
                        inode->i_op = &proc_pid_link_inode_operations;
944
                        inode->u.proc_i.op.proc_get_link = proc_exe_link;
945
                        break;
946
                case PROC_PID_CWD:
947
                        inode->i_op = &proc_pid_link_inode_operations;
948
                        inode->u.proc_i.op.proc_get_link = proc_cwd_link;
949
                        break;
950
                case PROC_PID_ROOT:
951
                        inode->i_op = &proc_pid_link_inode_operations;
952
                        inode->u.proc_i.op.proc_get_link = proc_root_link;
953
                        break;
954
                case PROC_PID_ENVIRON:
955
                        inode->i_fop = &proc_info_file_operations;
956
                        inode->u.proc_i.op.proc_read = proc_pid_environ;
957
                        break;
958
                case PROC_PID_STATUS:
959
                        inode->i_fop = &proc_info_file_operations;
960
                        inode->u.proc_i.op.proc_read = proc_pid_status;
961
                        break;
962
                case PROC_PID_STAT:
963
                        inode->i_fop = &proc_info_file_operations;
964
                        inode->u.proc_i.op.proc_read = proc_pid_stat;
965
                        break;
966
                case PROC_PID_CMDLINE:
967
                        inode->i_fop = &proc_info_file_operations;
968
                        inode->u.proc_i.op.proc_read = proc_pid_cmdline;
969
                        break;
970
                case PROC_PID_STATM:
971
                        inode->i_fop = &proc_info_file_operations;
972
                        inode->u.proc_i.op.proc_read = proc_pid_statm;
973
                        break;
974
                case PROC_PID_MAPS:
975
                        inode->i_fop = &proc_maps_operations;
976
                        break;
977
#ifdef CONFIG_SMP
978
                case PROC_PID_CPU:
979
                        inode->i_fop = &proc_info_file_operations;
980
                        inode->u.proc_i.op.proc_read = proc_pid_cpu;
981
                        break;
982
#endif
983
                case PROC_PID_MEM:
984
                        inode->i_op = &proc_mem_inode_operations;
985
                        inode->i_fop = &proc_mem_operations;
986
                        break;
987
                case PROC_PID_MOUNTS:
988
                        inode->i_fop = &proc_mounts_operations;
989
                        break;
990
                default:
991
                        printk("procfs: impossible type (%d)",p->type);
992
                        iput(inode);
993
                        return ERR_PTR(-EINVAL);
994
        }
995
        dentry->d_op = &pid_dentry_operations;
996
        d_add(dentry, inode);
997
        return NULL;
998
 
999
out:
1000
        return ERR_PTR(error);
1001
}
1002
 
1003
static struct file_operations proc_base_operations = {
1004
        read:           generic_read_dir,
1005
        readdir:        proc_base_readdir,
1006
};
1007
 
1008
static struct inode_operations proc_base_inode_operations = {
1009
        lookup:         proc_base_lookup,
1010
};
1011
 
1012
/*
1013
 * /proc/self:
1014
 */
1015
static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
1016
{
1017
        char tmp[30];
1018
        sprintf(tmp, "%d", current->pid);
1019
        return vfs_readlink(dentry,buffer,buflen,tmp);
1020
}
1021
 
1022
static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
1023
{
1024
        char tmp[30];
1025
        sprintf(tmp, "%d", current->pid);
1026
        return vfs_follow_link(nd,tmp);
1027
}
1028
 
1029
static struct inode_operations proc_self_inode_operations = {
1030
        readlink:       proc_self_readlink,
1031
        follow_link:    proc_self_follow_link,
1032
};
1033
 
1034
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
1035
{
1036
        unsigned int pid, c;
1037
        struct task_struct *task;
1038
        const char *name;
1039
        struct inode *inode;
1040
        int len;
1041
 
1042
        pid = 0;
1043
        name = dentry->d_name.name;
1044
        len = dentry->d_name.len;
1045
        if (len == 4 && !memcmp(name, "self", 4)) {
1046
                inode = new_inode(dir->i_sb);
1047
                if (!inode)
1048
                        return ERR_PTR(-ENOMEM);
1049
                inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1050
                inode->i_ino = fake_ino(0, PROC_PID_INO);
1051
                inode->u.proc_i.file = NULL;
1052
                inode->u.proc_i.task = NULL;
1053
                inode->i_mode = S_IFLNK|S_IRWXUGO;
1054
                inode->i_uid = inode->i_gid = 0;
1055
                inode->i_size = 64;
1056
                inode->i_op = &proc_self_inode_operations;
1057
                d_add(dentry, inode);
1058
                return NULL;
1059
        }
1060
        while (len-- > 0) {
1061
                c = *name - '0';
1062
                name++;
1063
                if (c > 9)
1064
                        goto out;
1065
                if (pid >= MAX_MULBY10)
1066
                        goto out;
1067
                pid *= 10;
1068
                pid += c;
1069
                if (!pid)
1070
                        goto out;
1071
        }
1072
 
1073
        read_lock(&tasklist_lock);
1074
        task = find_task_by_pid(pid);
1075
        if (task)
1076
                get_task_struct(task);
1077
        read_unlock(&tasklist_lock);
1078
        if (!task)
1079
                goto out;
1080
 
1081
        inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
1082
 
1083
        free_task_struct(task);
1084
 
1085
        if (!inode)
1086
                goto out;
1087
        inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
1088
        inode->i_op = &proc_base_inode_operations;
1089
        inode->i_fop = &proc_base_operations;
1090
        inode->i_nlink = 3;
1091
        inode->i_flags|=S_IMMUTABLE;
1092
 
1093
        dentry->d_op = &pid_base_dentry_operations;
1094
        d_add(dentry, inode);
1095
        return NULL;
1096
out:
1097
        return ERR_PTR(-ENOENT);
1098
}
1099
 
1100
void proc_pid_delete_inode(struct inode *inode)
1101
{
1102
        if (inode->u.proc_i.file)
1103
                fput(inode->u.proc_i.file);
1104
        if (inode->u.proc_i.task)
1105
                free_task_struct(inode->u.proc_i.task);
1106
}
1107
 
1108
#define PROC_NUMBUF 10
1109
#define PROC_MAXPIDS 20
1110
 
1111
/*
1112
 * Get a few pid's to return for filldir - we need to hold the
1113
 * tasklist lock while doing this, and we must release it before
1114
 * we actually do the filldir itself, so we use a temp buffer..
1115
 */
1116
static int get_pid_list(int index, unsigned int *pids)
1117
{
1118
        struct task_struct *p;
1119
        int nr_pids = 0;
1120
 
1121
        index--;
1122
        read_lock(&tasklist_lock);
1123
        for_each_task(p) {
1124
                int pid = p->pid;
1125
                if (!pid)
1126
                        continue;
1127
                if (--index >= 0)
1128
                        continue;
1129
                pids[nr_pids] = pid;
1130
                nr_pids++;
1131
                if (nr_pids >= PROC_MAXPIDS)
1132
                        break;
1133
        }
1134
        read_unlock(&tasklist_lock);
1135
        return nr_pids;
1136
}
1137
 
1138
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
1139
{
1140
        unsigned int pid_array[PROC_MAXPIDS];
1141
        char buf[PROC_NUMBUF];
1142
        unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
1143
        unsigned int nr_pids, i;
1144
 
1145
        if (!nr) {
1146
                ino_t ino = fake_ino(0,PROC_PID_INO);
1147
                if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
1148
                        return 0;
1149
                filp->f_pos++;
1150
                nr++;
1151
        }
1152
 
1153
        nr_pids = get_pid_list(nr, pid_array);
1154
 
1155
        for (i = 0; i < nr_pids; i++) {
1156
                int pid = pid_array[i];
1157
                ino_t ino = fake_ino(pid,PROC_PID_INO);
1158
                unsigned long j = PROC_NUMBUF;
1159
 
1160
                do buf[--j] = '0' + (pid % 10); while (pid/=10);
1161
 
1162
                if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
1163
                        break;
1164
                filp->f_pos++;
1165
        }
1166
        return 0;
1167
}

powered by: WebSVN 2.1.0

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