|
|
1.1 ! root 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, /* no special open code */ ! 27: NULL /* no special release code */ ! 28: }; ! 29: ! 30: /* ! 31: * proc directories can do almost nothing.. ! 32: */ ! 33: struct inode_operations proc_base_inode_operations = { ! 34: &proc_base_operations, /* default base directory file-ops */ ! 35: NULL, /* create */ ! 36: proc_lookupbase, /* lookup */ ! 37: NULL, /* link */ ! 38: NULL, /* unlink */ ! 39: NULL, /* symlink */ ! 40: NULL, /* mkdir */ ! 41: NULL, /* rmdir */ ! 42: NULL, /* mknod */ ! 43: NULL, /* rename */ ! 44: NULL, /* readlink */ ! 45: NULL, /* follow_link */ ! 46: NULL, /* bmap */ ! 47: NULL /* truncate */ ! 48: }; ! 49: ! 50: struct proc_dir_entry { ! 51: unsigned short low_ino; ! 52: unsigned short namelen; ! 53: char * name; ! 54: }; ! 55: ! 56: static struct proc_dir_entry base_dir[] = { ! 57: { 1,2,".." }, ! 58: { 2,1,"." }, ! 59: { 3,3,"mem" }, ! 60: { 4,3,"cwd" }, ! 61: { 5,4,"root" }, ! 62: { 6,3,"exe" }, ! 63: { 7,2,"fd" }, ! 64: { 8,3,"lib" } ! 65: }; ! 66: ! 67: #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0]))) ! 68: ! 69: static int proc_match(int len,const char * name,struct proc_dir_entry * de) ! 70: { ! 71: register int same __asm__("ax"); ! 72: ! 73: if (!de || !de->low_ino) ! 74: return 0; ! 75: /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ ! 76: if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) ! 77: return 1; ! 78: if (de->namelen != len) ! 79: return 0; ! 80: __asm__("cld\n\t" ! 81: "fs ; repe ; cmpsb\n\t" ! 82: "setz %%al" ! 83: :"=a" (same) ! 84: :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len) ! 85: :"cx","di","si"); ! 86: return same; ! 87: } ! 88: ! 89: static int proc_lookupbase(struct inode * dir,const char * name, int len, ! 90: struct inode ** result) ! 91: { ! 92: unsigned int pid; ! 93: int i, ino; ! 94: ! 95: *result = NULL; ! 96: if (!dir) ! 97: return -ENOENT; ! 98: if (!S_ISDIR(dir->i_mode)) { ! 99: iput(dir); ! 100: return -ENOENT; ! 101: } ! 102: ino = dir->i_ino; ! 103: pid = ino >> 16; ! 104: i = NR_BASE_DIRENTRY; ! 105: while (i-- > 0 && !proc_match(len,name,base_dir+i)) ! 106: /* nothing */; ! 107: if (i < 0) { ! 108: iput(dir); ! 109: return -ENOENT; ! 110: } ! 111: if (base_dir[i].low_ino == 1) ! 112: ino = 1; ! 113: else ! 114: ino = (pid << 16) + base_dir[i].low_ino; ! 115: for (i = 0 ; i < NR_TASKS ; i++) ! 116: if (task[i] && task[i]->pid == pid) ! 117: break; ! 118: if (!pid || i >= NR_TASKS) { ! 119: iput(dir); ! 120: return -ENOENT; ! 121: } ! 122: if (!(*result = iget(dir->i_dev,ino))) { ! 123: iput(dir); ! 124: return -ENOENT; ! 125: } ! 126: iput(dir); ! 127: return 0; ! 128: } ! 129: ! 130: static int proc_readbase(struct inode * inode, struct file * filp, ! 131: struct dirent * dirent, int count) ! 132: { ! 133: struct proc_dir_entry * de; ! 134: unsigned int pid, ino; ! 135: int i,j; ! 136: ! 137: if (!inode || !S_ISDIR(inode->i_mode)) ! 138: return -EBADF; ! 139: ino = inode->i_ino; ! 140: pid = ino >> 16; ! 141: for (i = 0 ; i < NR_TASKS ; i++) ! 142: if (task[i] && task[i]->pid == pid) ! 143: break; ! 144: if (!pid || i >= NR_TASKS) ! 145: return 0; ! 146: if (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) { ! 147: de = base_dir + filp->f_pos; ! 148: filp->f_pos++; ! 149: i = de->namelen; ! 150: ino = de->low_ino; ! 151: if (ino != 1) ! 152: ino |= (pid << 16); ! 153: put_fs_long(ino, &dirent->d_ino); ! 154: put_fs_word(i,&dirent->d_reclen); ! 155: put_fs_byte(0,i+dirent->d_name); ! 156: j = i; ! 157: while (i--) ! 158: put_fs_byte(de->name[i], i+dirent->d_name); ! 159: return j; ! 160: } ! 161: return 0; ! 162: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.