home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / proc / link.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-11  |  2.5 KB  |  134 lines

  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,
  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->pwd;
  70.             break;
  71.         case 5:
  72.             inode = p->root;
  73.             break;
  74.         case 6:
  75.             inode = p->executable;
  76.             break;
  77.         default:
  78.             switch (ino >> 8) {
  79.                 case 1:
  80.                     ino &= 0xff;
  81.                     if (ino < NR_OPEN && p->filp[ino])
  82.                         inode = p->filp[ino]->f_inode;
  83.                     break;
  84.                 case 2:
  85.                     ino &= 0xff;
  86.                     { int j = ino;
  87.                       struct vm_area_struct * mpnt;
  88.                       for(mpnt = p->mmap; mpnt && j >= 0;
  89.                           mpnt = mpnt->vm_next){
  90.                         if(mpnt->vm_inode) {
  91.                           if(j == 0) {
  92.                         inode = mpnt->vm_inode;
  93.                         break;
  94.                           };
  95.                           j--;
  96.                         }
  97.                       }
  98.                     };
  99.             }
  100.     }
  101.     if (!inode)
  102.         return -ENOENT;
  103.     *res_inode = inode;
  104.     inode->i_count++;
  105.     return 0;
  106. }
  107.  
  108. static int proc_readlink(struct inode * inode, char * buffer, int buflen)
  109. {
  110.     int i;
  111.     unsigned int dev,ino;
  112.     char buf[64];
  113.  
  114.     if (!S_ISLNK(inode->i_mode)) {
  115.         iput(inode);
  116.         return -EINVAL;
  117.     }
  118.     i = proc_follow_link(NULL, inode, 0, 0, &inode);
  119.     if (i)
  120.         return i;
  121.     if (!inode)
  122.         return -EIO;
  123.     dev = inode->i_dev;
  124.     ino = inode->i_ino;
  125.     iput(inode);
  126.     i = sprintf(buf,"[%04x]:%u", dev, ino);
  127.     if (buflen > i)
  128.         buflen = i;
  129.     i = 0;
  130.     while (i < buflen)
  131.         put_fs_byte(buf[i++],buffer++);
  132.     return i;
  133. }
  134.