root/fs/proc/link.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. proc_follow_link
  2. proc_readlink

   1 /*
   2  *  linux/fs/proc/link.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *
   6  *  /proc link-file handling code
   7  */
   8 
   9 #include <asm/segment.h>
  10 
  11 #include <linux/errno.h>
  12 #include <linux/sched.h>
  13 #include <linux/fs.h>
  14 #include <linux/minix_fs.h>
  15 #include <linux/stat.h>
  16 
  17 static int proc_readlink(struct inode *, char *, int);
  18 static int proc_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  19 
  20 /*
  21  * links can't do much...
  22  */
  23 struct inode_operations proc_link_inode_operations = {
  24         NULL,                   /* no file-operations */
  25         NULL,                   /* create */
  26         NULL,                   /* lookup */
  27         NULL,                   /* link */
  28         NULL,                   /* unlink */
  29         NULL,                   /* symlink */
  30         NULL,                   /* mkdir */
  31         NULL,                   /* rmdir */
  32         NULL,                   /* mknod */
  33         NULL,                   /* rename */
  34         proc_readlink,          /* readlink */
  35         proc_follow_link,       /* follow_link */
  36         NULL,                   /* bmap */
  37         NULL,                   /* truncate */
  38         NULL                    /* permission */
  39 };
  40 
  41 static int proc_follow_link(struct inode * dir, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  42         int flag, int mode, struct inode ** res_inode)
  43 {
  44         unsigned int pid, ino;
  45         struct task_struct * p;
  46         int i;
  47 
  48         *res_inode = NULL;
  49         if (dir)
  50                 iput(dir);
  51         if (!inode)
  52                 return -ENOENT;
  53         if (!permission(inode, MAY_EXEC)) {
  54                 iput(inode);
  55                 return -EACCES;
  56         }
  57         ino = inode->i_ino;
  58         pid = ino >> 16;
  59         ino &= 0x0000ffff;
  60         iput(inode);
  61         for (i = 0 ; i < NR_TASKS ; i++)
  62                 if ((p = task[i]) && p->pid == pid)
  63                         break;
  64         if (i >= NR_TASKS)
  65                 return -ENOENT;
  66         inode = NULL;
  67         switch (ino) {
  68                 case 4:
  69                         inode = p->fs->pwd;
  70                         break;
  71                 case 5:
  72                         inode = p->fs->root;
  73                         break;
  74                 case 6: {
  75                         struct vm_area_struct * vma = p->mm->mmap;
  76                         while (vma) {
  77                                 if (vma->vm_flags & VM_EXECUTABLE) {
  78                                         inode = vma->vm_inode;
  79                                         break;
  80                                 }
  81                                 vma = vma->vm_next;
  82                         }
  83                         break;
  84                 }
  85                 default:
  86                         switch (ino >> 8) {
  87                                 case 1:
  88                                         ino &= 0xff;
  89                                         if (ino < NR_OPEN && p->files->fd[ino])
  90                                                 inode = p->files->fd[ino]->f_inode;
  91                                         break;
  92                                 case 2:
  93                                         ino &= 0xff;
  94                                         { int j = ino;
  95                                           struct vm_area_struct * mpnt;
  96                                           for(mpnt = p->mm->mmap; mpnt && j >= 0;
  97                                               mpnt = mpnt->vm_next){
  98                                             if(mpnt->vm_inode) {
  99                                               if(j == 0) {
 100                                                 inode = mpnt->vm_inode;
 101                                                 break;
 102                                               };
 103                                               j--;
 104                                             }
 105                                           }
 106                                         };
 107                         }
 108         }
 109         if (!inode)
 110                 return -ENOENT;
 111         *res_inode = inode;
 112         inode->i_count++;
 113         return 0;
 114 }
 115 
 116 static int proc_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118         int i;
 119         unsigned int dev,ino;
 120         char buf[64];
 121 
 122         if (!S_ISLNK(inode->i_mode)) {
 123                 iput(inode);
 124                 return -EINVAL;
 125         }
 126         i = proc_follow_link(NULL, inode, 0, 0, &inode);
 127         if (i)
 128                 return i;
 129         if (!inode)
 130                 return -EIO;
 131         dev = inode->i_dev;
 132         ino = inode->i_ino;
 133         iput(inode);
 134         i = sprintf(buf,"[%04x]:%u", dev, ino);
 135         if (buflen > i)
 136                 buflen = i;
 137         i = 0;
 138         while (i < buflen)
 139                 put_fs_byte(buf[i++],buffer++);
 140         return i;
 141 }

/* [previous][next][first][last][top][bottom][index][help] */