diff -u --recursive --new-file linux-2.0.35/CREDITS linux/CREDITS --- linux-2.0.35/CREDITS Wed Jul 22 16:55:37 1998 +++ linux/CREDITS Wed Jul 22 11:10:44 1998 @@ -16,6 +16,14 @@ D: and other hacks.. D: Documenting various parts of network subsystem (kernel side) +N: Dragos Acostachioaie +E: dragos@iname.com +W: http://www.arbornet.org/~dragos +D: /proc/sysvipc +S: C. Negri 6, bl. D3 +S: Iasi 6600 +S: Romania + N: Werner Almesberger E: werner.almesberger@lrc.di.epfl.ch D: dosfs, LILO, some fd features, various other hacks here and there diff -u --recursive --new-file linux-2.0.35/fs/proc/Makefile linux/fs/proc/Makefile --- linux-2.0.35/fs/proc/Makefile Thu Jan 18 07:06:17 1996 +++ linux/fs/proc/Makefile Wed Jul 22 13:01:16 1998 @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := proc.o -O_OBJS := inode.o root.o base.o mem.o link.o fd.o array.o kmsg.o net.o scsi.o +O_OBJS := inode.o root.o base.o mem.o link.o fd.o array.o kmsg.o net.o scsi.o sysvipc.o OX_OBJS := procfs_syms.o M_OBJS := $(O_TARGET) diff -u --recursive --new-file linux-2.0.35/fs/proc/root.c linux/fs/proc/root.c --- linux-2.0.35/fs/proc/root.c Tue Apr 30 13:09:45 1996 +++ linux/fs/proc/root.c Wed Jul 22 16:28:07 1998 @@ -148,6 +148,17 @@ NULL, NULL /* parent, subdir */ }; +#ifdef CONFIG_SYSVIPC +struct proc_dir_entry proc_sysvipc = { + PROC_SYSVIPC, 7, "sysvipc", + S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, + 0, &proc_dir_inode_operations, + NULL, NULL, + NULL, + NULL, NULL +}; +#endif + int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) { dp->next = dir->subdir; @@ -296,6 +307,9 @@ proc_register(&proc_root, &proc_net); proc_register(&proc_root, &proc_scsi); proc_register(&proc_root, &proc_sys_root); +#ifdef CONFIG_SYSVIPC + proc_register(&proc_root, &proc_sysvipc); +#endif #ifdef CONFIG_DEBUG_MALLOC proc_register(&proc_root, &(struct proc_dir_entry) { diff -u --recursive --new-file linux-2.0.35/fs/proc/sysvipc.c linux/fs/proc/sysvipc.c --- linux-2.0.35/fs/proc/sysvipc.c Thu Jan 1 02:00:00 1970 +++ linux/fs/proc/sysvipc.c Wed Jul 22 12:56:49 1998 @@ -0,0 +1,104 @@ +/* + * linux/fs/proc/sysvipc.c + * + * Copyright (c) 1998 Dragos Acostachioaie + * + * This code is derived from linux/fs/proc/net.c + * which is Copyright (C) 1991, 1992 Linus Torvalds. + * + * /proc/sysvipc directory handling functions + */ +#include +#include +#include +#include +#include +#include + +#include + +#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */ + +static int proc_readsysvipc(struct inode * inode, struct file * file, + char * buf, int count) +{ + char * page; + int bytes=count; + int copied=0; + char *start; + struct proc_dir_entry * dp; + + if (count < 0) + return -EINVAL; + dp = (struct proc_dir_entry *) inode->u.generic_ip; + if (!(page = (char*) __get_free_page(GFP_KERNEL))) + return -ENOMEM; + + while (bytes>0) + { + int length, thistime=bytes; + if (bytes > PROC_BLOCK_SIZE) + thistime=PROC_BLOCK_SIZE; + + length = dp->get_info(page, &start, + file->f_pos, + thistime, + (file->f_flags & O_ACCMODE) == O_RDWR); + + /* + * We have been given a non page aligned block of + * the data we asked for + a bit. We have been given + * the start pointer and we know the length.. + */ + + if (length <= 0) + break; + /* + * Copy the bytes + */ + memcpy_tofs(buf+copied, start, length); + file->f_pos += length; /* Move down the file */ + bytes -= length; + copied += length; + if (length in May 1995, and May 1996 * * See for the (optional) new kerneld protocol + * + * /proc/sysvipc/msg support (c) 1998 Dragos Acostachioaie */ #include @@ -15,6 +17,7 @@ #include #include #include +#include #include @@ -23,6 +26,9 @@ static void freeque (int id); static int newque (key_t key, int msgflg); static int findkey (key_t key); +#ifdef CONFIG_PROC_FS +static int sysvipc_msg_get_info(char *buffer, char **start, off_t offset, int length, int dummy); +#endif static struct msqid_ds *msgque[MSGMNI]; static int msgbytes = 0; @@ -45,6 +51,14 @@ msgque[id] = (struct msqid_ds *) IPC_UNUSED; msgbytes = msghdrs = msg_seq = max_msqid = used_queues = 0; msg_lock = NULL; +#ifdef CONFIG_PROC_FS + proc_register(&proc_sysvipc, &(struct proc_dir_entry) { + PROC_SYSVIPC_MSG, 3, "msg", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_sysvipc_inode_operations, + sysvipc_msg_get_info + }); +#endif return; } @@ -765,3 +779,46 @@ #endif /* CONFIG_KERNELD */ return status; } + +#ifdef CONFIG_PROC_FS +static int sysvipc_msg_get_info(char *buffer, char **start, off_t offset, int length, int dummy) +{ + off_t pos = 0; + off_t begin = 0; + int i, len = 0; + + len += sprintf(buffer, "msg: key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n"); + + for(i = 0; i < MSGMNI; i++) + if(msgque[i] != IPC_UNUSED) { + len += sprintf(buffer + len, "%10d %10d %4o %5u %5u %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", + msgque[i]->msg_perm.key, + msgque[i]->msg_perm.seq * MSGMNI + i, + msgque[i]->msg_perm.mode, + msgque[i]->msg_cbytes, + msgque[i]->msg_qnum, + msgque[i]->msg_lspid, + msgque[i]->msg_lrpid, + msgque[i]->msg_perm.uid, + msgque[i]->msg_perm.gid, + msgque[i]->msg_perm.cuid, + msgque[i]->msg_perm.cgid, + msgque[i]->msg_stime, + msgque[i]->msg_rtime, + msgque[i]->msg_ctime); + + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + if(pos > offset + length) + break; + } + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + return len; +} +#endif diff -u --recursive --new-file linux-2.0.35/ipc/sem.c linux/ipc/sem.c --- linux-2.0.35/ipc/sem.c Sun Sep 1 09:15:34 1996 +++ linux/ipc/sem.c Wed Jul 22 16:52:22 1998 @@ -29,6 +29,8 @@ * see a clean way to get the old behavior with the new design. * The POSIX standard and SVID should be consulted to determine * what behavior is mandated. + * + * /proc/sysvipc/sem support (c) 1998 Dragos Acostachioaie */ #include @@ -39,11 +41,15 @@ #include #include #include +#include extern int ipcperms (struct ipc_perm *ipcp, short semflg); static int newary (key_t, int, int); static int findkey (key_t key); static void freeary (int id); +#ifdef CONFIG_PROC_FS +static int sysvipc_sem_get_info(char *buffer, char **start, off_t offset, int length, int dummy); +#endif static struct semid_ds *semary[SEMMNI]; static int used_sems = 0, used_semids = 0; @@ -60,6 +66,14 @@ used_sems = used_semids = max_semid = sem_seq = 0; for (i = 0; i < SEMMNI; i++) semary[i] = (struct semid_ds *) IPC_UNUSED; +#ifdef CONFIG_PROC_FS + proc_register(&proc_sysvipc, &(struct proc_dir_entry) { + PROC_SYSVIPC_SEM, 3, "sem", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_sysvipc_inode_operations, + sysvipc_sem_get_info + }); +#endif return; } @@ -706,3 +720,42 @@ } current->semundo = NULL; } + +#ifdef CONFIG_PROC_FS +static int sysvipc_sem_get_info(char *buffer, char **start, off_t offset, int length, int dummy) +{ + off_t pos = 0; + off_t begin = 0; + int i, len = 0; + + len += sprintf(buffer, "sem: key semid perms nsems uid gid cuid cgid otime ctime\n"); + + for(i = 0; i < SEMMNI; i++) + if(semary[i] != IPC_UNUSED) { + len += sprintf(buffer + len, "%10d %10d %4o %5u %5u %5u %5u %5u %10lu %10lu\n", + semary[i]->sem_perm.key, + semary[i]->sem_perm.seq * SEMMNI + i, + semary[i]->sem_perm.mode, + semary[i]->sem_nsems, + semary[i]->sem_perm.uid, + semary[i]->sem_perm.gid, + semary[i]->sem_perm.cuid, + semary[i]->sem_perm.cgid, + semary[i]->sem_otime, + semary[i]->sem_ctime); + + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + if(pos > offset + length) + break; + } + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + return len; +} +#endif diff -u --recursive --new-file linux-2.0.35/ipc/shm.c linux/ipc/shm.c --- linux-2.0.35/ipc/shm.c Thu Jun 4 01:17:50 1998 +++ linux/ipc/shm.c Wed Jul 22 16:41:38 1998 @@ -3,11 +3,14 @@ * Copyright (C) 1992, 1993 Krishna Balasubramanian * Many improvements/fixes by Bruno Haible. * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994. + * + * /proc/sysvipc/shm support (c) 1998 Dragos Acostachioaie */ #include #include #include +#include #include #include #include @@ -27,6 +30,9 @@ static void shm_open (struct vm_area_struct *shmd); static void shm_close (struct vm_area_struct *shmd); static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long); +#ifdef CONFIG_PROC_FS +static int sysvipc_shm_get_info(char *buffer, char **start, off_t offset, int length, int dummy); +#endif static int shm_tot = 0; /* total number of shared memory pages */ static int shm_rss = 0; /* number of shared memory pages that are in memory */ @@ -50,6 +56,14 @@ shm_segs[id] = (struct shmid_ds *) IPC_UNUSED; shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0; shm_lock = NULL; +#ifdef CONFIG_PROC_FS + proc_register(&proc_sysvipc, &(struct proc_dir_entry) { + PROC_SYSVIPC_SHM, 3, "shm", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_sysvipc_inode_operations, + sysvipc_shm_get_info + }); +#endif return; } @@ -804,3 +818,46 @@ shm_rss--; return 1; } + +#ifdef CONFIG_PROC_FS +static int sysvipc_shm_get_info(char *buffer, char **start, off_t offset, int length, int dummy) +{ + off_t pos = 0; + off_t begin = 0; + int i, len = 0; + + len += sprintf(buffer, "shm: key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n"); + + for(i = 0; i < SHMMNI; i++) + if(shm_segs[i] != IPC_UNUSED) { + len += sprintf(buffer + len, "%10d %10d %4o %10d %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n", + shm_segs[i]->shm_perm.key, + shm_segs[i]->shm_perm.seq * SHMMNI + i, + shm_segs[i]->shm_perm.mode, + shm_segs[i]->shm_segsz, + shm_segs[i]->shm_cpid, + shm_segs[i]->shm_lpid, + shm_segs[i]->shm_nattch, + shm_segs[i]->shm_perm.uid, + shm_segs[i]->shm_perm.gid, + shm_segs[i]->shm_perm.cuid, + shm_segs[i]->shm_perm.cgid, + shm_segs[i]->shm_atime, + shm_segs[i]->shm_dtime, + shm_segs[i]->shm_ctime); + + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + if(pos > offset + length) + break; + } + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + return len; +} +#endif