root/fs/proc/base.c

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

DEFINITIONS

This source file includes following definitions.
  1. proc_match
  2. proc_lookupbase
  3. proc_readbase

   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 *, void *, filldir_t);
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
 124         void * dirent, filldir_t filldir)
 125 {
 126         struct proc_dir_entry * de;
 127         unsigned int pid, ino;
 128         int i;
 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         while (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
 140                 de = base_dir + filp->f_pos;
 141                 ino = de->low_ino;
 142                 if (ino != 1)
 143                         ino |= (pid << 16);
 144                 if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino) < 0)
 145                         break;
 146                 filp->f_pos++;
 147         }
 148         return 0;
 149 }

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