/*
|
/*
|
* linux/fs/proc/base.c
|
* linux/fs/proc/base.c
|
*
|
*
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
*
|
*
|
* proc base directory handling functions
|
* proc base directory handling functions
|
*/
|
*/
|
|
|
/*
|
/*
|
* uClinux revisions for NO_MM
|
* uClinux revisions for NO_MM
|
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
|
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
|
* The Silver Hammer Group, Ltd.
|
* The Silver Hammer Group, Ltd.
|
*/
|
*/
|
|
|
#include <asm/segment.h>
|
#include <asm/segment.h>
|
|
|
#include <linux/errno.h>
|
#include <linux/errno.h>
|
#include <linux/sched.h>
|
#include <linux/sched.h>
|
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
#include <linux/stat.h>
|
#include <linux/stat.h>
|
|
|
static struct file_operations proc_base_operations = {
|
static struct file_operations proc_base_operations = {
|
NULL, /* lseek - default */
|
NULL, /* lseek - default */
|
NULL, /* read - bad */
|
NULL, /* read - bad */
|
NULL, /* write - bad */
|
NULL, /* write - bad */
|
proc_readdir, /* readdir */
|
proc_readdir, /* readdir */
|
NULL, /* select - default */
|
NULL, /* select - default */
|
NULL, /* ioctl - default */
|
NULL, /* ioctl - default */
|
NULL, /* mmap */
|
NULL, /* mmap */
|
NULL, /* no special open code */
|
NULL, /* no special open code */
|
NULL, /* no special release code */
|
NULL, /* no special release code */
|
NULL /* can't fsync */
|
NULL /* can't fsync */
|
};
|
};
|
|
|
/*
|
/*
|
* proc directories can do almost nothing..
|
* proc directories can do almost nothing..
|
*/
|
*/
|
static struct inode_operations proc_base_inode_operations = {
|
static struct inode_operations proc_base_inode_operations = {
|
&proc_base_operations, /* default base directory file-ops */
|
&proc_base_operations, /* default base directory file-ops */
|
NULL, /* create */
|
NULL, /* create */
|
proc_lookup, /* lookup */
|
proc_lookup, /* lookup */
|
NULL, /* link */
|
NULL, /* link */
|
NULL, /* unlink */
|
NULL, /* unlink */
|
NULL, /* symlink */
|
NULL, /* symlink */
|
NULL, /* mkdir */
|
NULL, /* mkdir */
|
NULL, /* rmdir */
|
NULL, /* rmdir */
|
NULL, /* mknod */
|
NULL, /* mknod */
|
NULL, /* rename */
|
NULL, /* rename */
|
NULL, /* readlink */
|
NULL, /* readlink */
|
NULL, /* follow_link */
|
NULL, /* follow_link */
|
NULL, /* readpage */
|
NULL, /* readpage */
|
NULL, /* writepage */
|
NULL, /* writepage */
|
NULL, /* bmap */
|
NULL, /* bmap */
|
NULL, /* truncate */
|
NULL, /* truncate */
|
NULL /* permission */
|
NULL /* permission */
|
};
|
};
|
|
|
static void proc_pid_fill_inode(struct inode * inode)
|
static void proc_pid_fill_inode(struct inode * inode)
|
{
|
{
|
struct task_struct * p;
|
struct task_struct * p;
|
int pid = inode->i_ino >> 16;
|
int pid = inode->i_ino >> 16;
|
int ino = inode->i_ino & 0xffff;
|
int ino = inode->i_ino & 0xffff;
|
|
|
for_each_task(p) {
|
for_each_task(p) {
|
if (p->pid == pid) {
|
if (p->pid == pid) {
|
if (p->dumpable || ino == PROC_PID_INO) {
|
if (p->dumpable || ino == PROC_PID_INO) {
|
inode->i_uid = p->euid;
|
inode->i_uid = p->euid;
|
inode->i_gid = p->gid;
|
inode->i_gid = p->gid;
|
}
|
}
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* This is really a pseudo-entry, and only links
|
* This is really a pseudo-entry, and only links
|
* backwards to the parent with no link from the
|
* backwards to the parent with no link from the
|
* root directory to this. This way we can have just
|
* root directory to this. This way we can have just
|
* one entry for every /proc/<pid>/ directory.
|
* one entry for every /proc/<pid>/ directory.
|
*/
|
*/
|
struct proc_dir_entry proc_pid = {
|
struct proc_dir_entry proc_pid = {
|
PROC_PID_INO, 5, "<pid>",
|
PROC_PID_INO, 5, "<pid>",
|
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
|
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
|
0, &proc_base_inode_operations,
|
0, &proc_base_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
NULL, &proc_root, NULL
|
NULL, &proc_root, NULL
|
};
|
};
|
|
|
struct proc_dir_entry pde_status = {
|
struct proc_dir_entry pde_status = {
|
PROC_PID_STATUS, 6, "status",
|
PROC_PID_STATUS, 6, "status",
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
0, &proc_array_inode_operations,
|
0, &proc_array_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_mem = {
|
struct proc_dir_entry pde_mem = {
|
PROC_PID_MEM, 3, "mem",
|
PROC_PID_MEM, 3, "mem",
|
S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
|
S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
|
0, &proc_mem_inode_operations,
|
0, &proc_mem_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_cwd = {
|
struct proc_dir_entry pde_cwd = {
|
PROC_PID_CWD, 3, "cwd",
|
PROC_PID_CWD, 3, "cwd",
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
0, &proc_link_inode_operations,
|
0, &proc_link_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_root = {
|
struct proc_dir_entry pde_root = {
|
PROC_PID_ROOT, 4, "root",
|
PROC_PID_ROOT, 4, "root",
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
0, &proc_link_inode_operations,
|
0, &proc_link_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_exe = {
|
struct proc_dir_entry pde_exe = {
|
PROC_PID_EXE, 3, "exe",
|
PROC_PID_EXE, 3, "exe",
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
S_IFLNK | S_IRWXU, 1, 0, 0,
|
0, &proc_link_inode_operations,
|
0, &proc_link_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_fd = {
|
struct proc_dir_entry pde_fd = {
|
PROC_PID_FD, 2, "fd",
|
PROC_PID_FD, 2, "fd",
|
S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0,
|
S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0,
|
0, &proc_fd_inode_operations,
|
0, &proc_fd_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_environ = {
|
struct proc_dir_entry pde_environ = {
|
PROC_PID_ENVIRON, 7, "environ",
|
PROC_PID_ENVIRON, 7, "environ",
|
S_IFREG | S_IRUSR, 1, 0, 0,
|
S_IFREG | S_IRUSR, 1, 0, 0,
|
0, &proc_array_inode_operations,
|
0, &proc_array_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_pidcmdline = {
|
struct proc_dir_entry pde_pidcmdline = {
|
PROC_PID_CMDLINE, 7, "cmdline",
|
PROC_PID_CMDLINE, 7, "cmdline",
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
0, &proc_array_inode_operations,
|
0, &proc_array_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_pidstat = {
|
struct proc_dir_entry pde_pidstat = {
|
PROC_PID_STAT, 4, "stat",
|
PROC_PID_STAT, 4, "stat",
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
0, &proc_array_inode_operations,
|
0, &proc_array_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
#ifndef NO_MM
|
#ifndef NO_MM
|
struct proc_dir_entry pde_statm = {
|
struct proc_dir_entry pde_statm = {
|
PROC_PID_STATM, 5, "statm",
|
PROC_PID_STATM, 5, "statm",
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
S_IFREG | S_IRUGO, 1, 0, 0,
|
0, &proc_array_inode_operations,
|
0, &proc_array_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
struct proc_dir_entry pde_maps = {
|
struct proc_dir_entry pde_maps = {
|
PROC_PID_MAPS, 4, "maps",
|
PROC_PID_MAPS, 4, "maps",
|
S_IFIFO | S_IRUGO, 1, 0, 0,
|
S_IFIFO | S_IRUGO, 1, 0, 0,
|
0, &proc_arraylong_inode_operations,
|
0, &proc_arraylong_inode_operations,
|
NULL, proc_pid_fill_inode,
|
NULL, proc_pid_fill_inode,
|
};
|
};
|
#endif /* !NO_MM */
|
#endif /* !NO_MM */
|
|
|
|
|
void proc_base_init(void)
|
void proc_base_init(void)
|
{
|
{
|
proc_register(&proc_pid, &pde_status);
|
proc_register(&proc_pid, &pde_status);
|
proc_register(&proc_pid, &pde_mem);
|
proc_register(&proc_pid, &pde_mem);
|
proc_register(&proc_pid, &pde_cwd);
|
proc_register(&proc_pid, &pde_cwd);
|
proc_register(&proc_pid, &pde_root);
|
proc_register(&proc_pid, &pde_root);
|
proc_register(&proc_pid, &pde_exe);
|
proc_register(&proc_pid, &pde_exe);
|
proc_register(&proc_pid, &pde_fd);
|
proc_register(&proc_pid, &pde_fd);
|
proc_register(&proc_pid, &pde_environ);
|
proc_register(&proc_pid, &pde_environ);
|
proc_register(&proc_pid, &pde_pidcmdline);
|
proc_register(&proc_pid, &pde_pidcmdline);
|
proc_register(&proc_pid, &pde_pidstat);
|
proc_register(&proc_pid, &pde_pidstat);
|
#ifndef NO_MM
|
#ifndef NO_MM
|
proc_register(&proc_pid, &pde_statm);
|
proc_register(&proc_pid, &pde_statm);
|
proc_register(&proc_pid, &pde_maps);
|
proc_register(&proc_pid, &pde_maps);
|
#endif /* !NO_MM */
|
#endif /* !NO_MM */
|
};
|
};
|
|
|