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 / base.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  3.5 KB  |  165 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.     { 1,2,".." },
  55.     { 2,1,"." },
  56.     { 3,3,"mem" },
  57.     { 4,3,"cwd" },
  58.     { 5,4,"root" },
  59.     { 6,3,"exe" },
  60.     { 7,2,"fd" },
  61.     { 8,4,"mmap" },
  62.     { 9,7,"environ" },
  63.     { 10,7,"cmdline" },
  64.     { 11,4,"stat" },
  65.     { 12,5,"statm" },
  66.     { 15,4,"maps" }
  67. };
  68.  
  69. #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
  70.  
  71. int proc_match(int len,const char * name,struct proc_dir_entry * de)
  72. {
  73.     register int same __asm__("ax");
  74.  
  75.     if (!de || !de->low_ino)
  76.         return 0;
  77.     /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
  78.     if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
  79.         return 1;
  80.     if (de->namelen != len)
  81.         return 0;
  82.     __asm__("cld\n\t"
  83.         "repe ; cmpsb\n\t"
  84.         "setz %%al"
  85.         :"=a" (same)
  86.         :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)
  87.         :"cx","di","si");
  88.     return same;
  89. }
  90.  
  91. static int proc_lookupbase(struct inode * dir,const char * name, int len,
  92.     struct inode ** result)
  93. {
  94.     unsigned int pid, ino;
  95.     int i;
  96.  
  97.     *result = NULL;
  98.     if (!dir)
  99.         return -ENOENT;
  100.     if (!S_ISDIR(dir->i_mode)) {
  101.         iput(dir);
  102.         return -ENOENT;
  103.     }
  104.     ino = dir->i_ino;
  105.     pid = ino >> 16;
  106.     i = NR_BASE_DIRENTRY;
  107.     while (i-- > 0 && !proc_match(len,name,base_dir+i))
  108.         /* nothing */;
  109.     if (i < 0) {
  110.         iput(dir);
  111.         return -ENOENT;
  112.     }
  113.     if (base_dir[i].low_ino == 1)
  114.         ino = 1;
  115.     else
  116.         ino = (pid << 16) + base_dir[i].low_ino;
  117.     for (i = 0 ; i < NR_TASKS ; i++)
  118.         if (task[i] && task[i]->pid == pid)
  119.             break;
  120.     if (!pid || i >= NR_TASKS) {
  121.         iput(dir);
  122.         return -ENOENT;
  123.     }
  124.     if (!(*result = iget(dir->i_sb,ino))) {
  125.         iput(dir);
  126.         return -ENOENT;
  127.     }
  128.     iput(dir);
  129.     return 0;
  130. }
  131.  
  132. static int proc_readbase(struct inode * inode, struct file * filp,
  133.     struct dirent * dirent, int count)
  134. {
  135.     struct proc_dir_entry * de;
  136.     unsigned int pid, ino;
  137.     int i,j;
  138.  
  139.     if (!inode || !S_ISDIR(inode->i_mode))
  140.         return -EBADF;
  141.     ino = inode->i_ino;
  142.     pid = ino >> 16;
  143.     for (i = 0 ; i < NR_TASKS ; i++)
  144.         if (task[i] && task[i]->pid == pid)
  145.             break;
  146.     if (!pid || i >= NR_TASKS)
  147.         return 0;
  148.     if (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
  149.         de = base_dir + filp->f_pos;
  150.         filp->f_pos++;
  151.         i = de->namelen;
  152.         ino = de->low_ino;
  153.         if (ino != 1)
  154.             ino |= (pid << 16);
  155.         put_fs_long(ino, &dirent->d_ino);
  156.         put_fs_word(i,&dirent->d_reclen);
  157.         put_fs_byte(0,i+dirent->d_name);
  158.         j = i;
  159.         while (i--)
  160.             put_fs_byte(de->name[i], i+dirent->d_name);
  161.         return j;
  162.     }
  163.     return 0;
  164. }
  165.