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         struct proc_dir_entry * de = NULL;
  86         unsigned int pid, ino;
  87         int i;
  88 
  89         *result = NULL;
  90         if (!dir)
  91                 return -ENOENT;
  92         if (!S_ISDIR(dir->i_mode)) {
  93                 iput(dir);
  94                 return -ENOENT;
  95         }
  96         ino = dir->i_ino;
  97         pid = ino >> 16;
  98         for (i = 0; i < NR_BASE_DIRENTRY; i++) {
  99                 if (!proc_match(len, name, base_dir+i))
 100                         continue;
 101                 de = base_dir+i;
 102                 break;
 103         }
 104         if (!de) {
 105                 iput(dir);
 106                 return -ENOENT;
 107         }
 108         if (de->low_ino == 1)
 109                 ino = 1;
 110         else
 111                 ino = (pid << 16) + de->low_ino;
 112         for (i = 0 ; i < NR_TASKS ; i++)
 113                 if (task[i] && task[i]->pid == pid)
 114                         break;
 115         if (!pid || i >= NR_TASKS) {
 116                 iput(dir);
 117                 return -ENOENT;
 118         }
 119         if (!(*result = iget(dir->i_sb,ino))) {
 120                 iput(dir);
 121                 return -ENOENT;
 122         }
 123         iput(dir);
 124         (*result)->u.generic_ip = de;
 125         return 0;
 126 }
 127 
 128 static int proc_readbase(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 129         void * dirent, filldir_t filldir)
 130 {
 131         struct proc_dir_entry * de;
 132         unsigned int pid, ino;
 133         int i;
 134 
 135         if (!inode || !S_ISDIR(inode->i_mode))
 136                 return -EBADF;
 137         ino = inode->i_ino;
 138         pid = ino >> 16;
 139         for (i = 0 ; i < NR_TASKS ; i++)
 140                 if (task[i] && task[i]->pid == pid)
 141                         break;
 142         if (!pid || i >= NR_TASKS)
 143                 return 0;
 144         while (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
 145                 de = base_dir + filp->f_pos;
 146                 ino = de->low_ino;
 147                 if (ino != 1)
 148                         ino |= (pid << 16);
 149                 if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino) < 0)
 150                         break;
 151                 filp->f_pos++;
 152         }
 153         return 0;
 154 }

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