home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / proc / base.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-22  |  3.5 KB  |  156 lines

  1. /*
  2.  *  linux/fs/proc/base.c
  3.  *
  4.  *  Copyright (C) 1991, 1992 Linus Torvalds
  5.  *
  6.  *  proc base 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_readbase(struct inode *, struct file *, struct dirent *, int);
  17. static int proc_lookupbase(struct inode *,const char *,int,struct inode **);
  18.  
  19. static struct file_operations proc_base_operations = {
  20.     NULL,            /* lseek - default */
  21.     NULL,            /* read - bad */
  22.     NULL,            /* write - bad */
  23.     proc_readbase,        /* 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_base_inode_operations = {
  36.     &proc_base_operations,    /* default base directory file-ops */
  37.     NULL,            /* create */
  38.     proc_lookupbase,    /* 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,            /* bmap */
  49.     NULL,            /* truncate */
  50.     NULL            /* permission */
  51. };
  52.  
  53. static struct proc_dir_entry base_dir[] = {
  54.     { PROC_PID_INO,        1, "." },
  55.     { PROC_ROOT_INO,    2, ".." },
  56.     { PROC_PID_MEM,        3, "mem" },
  57.     { PROC_PID_CWD,        3, "cwd" },
  58.     { PROC_PID_ROOT,    4, "root" },
  59.     { PROC_PID_EXE,        3, "exe" },
  60.     { PROC_PID_FD,        2, "fd" },
  61.     { PROC_PID_ENVIRON,    7, "environ" },
  62.     { PROC_PID_CMDLINE,    7, "cmdline" },
  63.     { PROC_PID_STAT,    4, "stat" },
  64.     { PROC_PID_STATM,    5, "statm" },
  65.     { PROC_PID_MAPS,    4, "maps" }
  66. };
  67.  
  68. #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
  69.  
  70. int proc_match(int len,const char * name,struct proc_dir_entry * de)
  71. {
  72.     if (!de || !de->low_ino)
  73.         return 0;
  74.     /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
  75.     if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
  76.         return 1;
  77.     if (de->namelen != len)
  78.         return 0;
  79.     return !memcmp(name, de->name, len);
  80. }
  81.  
  82. static int proc_lookupbase(struct inode * dir,const char * name, int len,
  83.     struct inode ** result)
  84. {
  85.     unsigned int pid, ino;
  86.     int i;
  87.  
  88.     *result = NULL;
  89.     if (!dir)
  90.         return -ENOENT;
  91.     if (!S_ISDIR(dir->i_mode)) {
  92.         iput(dir);
  93.         return -ENOENT;
  94.     }
  95.     ino = dir->i_ino;
  96.     pid = ino >> 16;
  97.     i = NR_BASE_DIRENTRY;
  98.     while (i-- > 0 && !proc_match(len,name,base_dir+i))
  99.         /* nothing */;
  100.     if (i < 0) {
  101.         iput(dir);
  102.         return -ENOENT;
  103.     }
  104.     if (base_dir[i].low_ino == 1)
  105.         ino = 1;
  106.     else
  107.         ino = (pid << 16) + base_dir[i].low_ino;
  108.     for (i = 0 ; i < NR_TASKS ; i++)
  109.         if (task[i] && task[i]->pid == pid)
  110.             break;
  111.     if (!pid || i >= NR_TASKS) {
  112.         iput(dir);
  113.         return -ENOENT;
  114.     }
  115.     if (!(*result = iget(dir->i_sb,ino))) {
  116.         iput(dir);
  117.         return -ENOENT;
  118.     }
  119.     iput(dir);
  120.     return 0;
  121. }
  122.  
  123. static int proc_readbase(struct inode * inode, struct file * filp,
  124.     struct dirent * dirent, int count)
  125. {
  126.     struct proc_dir_entry * de;
  127.     unsigned int pid, ino;
  128.     int i,j;
  129.  
  130.     if (!inode || !S_ISDIR(inode->i_mode))
  131.         return -EBADF;
  132.     ino = inode->i_ino;
  133.     pid = ino >> 16;
  134.     for (i = 0 ; i < NR_TASKS ; i++)
  135.         if (task[i] && task[i]->pid == pid)
  136.             break;
  137.     if (!pid || i >= NR_TASKS)
  138.         return 0;
  139.     if (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
  140.         de = base_dir + filp->f_pos;
  141.         filp->f_pos++;
  142.         i = de->namelen;
  143.         ino = de->low_ino;
  144.         if (ino != 1)
  145.             ino |= (pid << 16);
  146.         put_fs_long(ino, &dirent->d_ino);
  147.         put_fs_word(i,&dirent->d_reclen);
  148.         put_fs_byte(0,i+dirent->d_name);
  149.         j = i;
  150.         while (i--)
  151.             put_fs_byte(de->name[i], i+dirent->d_name);
  152.         return j;
  153.     }
  154.     return 0;
  155. }
  156.