📄 ipcs.c
字号:
/* Original author unknown, may be "krishna balasub@cis.ohio-state.edu" *//* Modified Sat Oct 9 10:55:28 1993 for 0.99.13 Patches from Mike Jagdis (jaggy@purplet.demon.co.uk) applied Wed Feb 8 12:12:21 1995 by faith@cs.unc.edu to print numeric uids if no passwd file entry. Patch from arnolds@ifns.de (Heinz-Ado Arnolds) applied Mon Jul 1 19:30:41 1996 by janl@math.uio.no to add code missing in case PID: clauses. Patched to display the key field -- hy@picksys.com 12/18/96 1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL> - added Native Language Support*/#include <stdio.h>#include <stdlib.h>#include <getopt.h>#include <errno.h>#include <time.h>#include <pwd.h>#include <grp.h>#include "nls.h"/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() *//* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() *//* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/msg.h>#include <sys/shm.h>/*-------------------------------------------------------------------*//* SHM_DEST and SHM_LOCKED are defined in kernel headers, but inside #ifdef __KERNEL__ ... #endif */#ifndef SHM_DEST/* shm_mode upper byte flags */#define SHM_DEST 01000 /* segment will be destroyed on last detach */#define SHM_LOCKED 02000 /* segment will not be swapped */#endif/* For older kernels the same holds for the defines below */#ifndef MSG_STAT#define MSG_STAT 11#define MSG_INFO 12#endif#ifndef SHM_STAT#define SHM_STAT 13#define SHM_INFO 14struct shm_info { int used_ids; ulong shm_tot; /* total allocated shm */ ulong shm_rss; /* total resident shm */ ulong shm_swp; /* total swapped shm */ ulong swap_attempts; ulong swap_successes;};#endif#ifndef SEM_STAT#define SEM_STAT 18#define SEM_INFO 19#endif/* Some versions of libc only define IPC_INFO when __USE_GNU is defined. */#ifndef IPC_INFO#define IPC_INFO 3#endif/*-------------------------------------------------------------------*//* The last arg of semctl is a union semun, but where is it defined? X/OPEN tells us to define it ourselves, but until recently Linux include files would also define it. */#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)/* union semun is defined by including <sys/sem.h> */#else/* according to X/OPEN we have to define it ourselves */union semun { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf;};#endif/* X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm; libc 4/5 does not mention struct ipc_term at all, but includes <linux/ipc.h>, which defines a struct ipc_perm with such fields. glibc-1.09 has no support for sysv ipc. glibc 2 uses __key, __seq */#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1#define KEY __key#else#define KEY key#endif#define LIMITS 1#define STATUS 2#define CREATOR 3#define TIME 4#define PID 5void do_shm (char format);void do_sem (char format);void do_msg (char format);void print_shm (int id);void print_msg (int id);void print_sem (int id);static char *progname;static voidusage(void) { printf (_("usage : %s -asmq -tclup \n"), progname); printf (_("\t%s [-s -m -q] -i id\n"), progname); printf (_("\t%s -h for help.\n"), progname); return;}static voidhelp (void) { printf (_("%s provides information on ipc facilities for" " which you have read access.\n"), progname); printf (_("Resource Specification:\n\t-m : shared_mem\n\t-q : messages\n")); printf (_("\t-s : semaphores\n\t-a : all (default)\n")); printf (_("Output Format:\n\t-t : time\n\t-p : pid\n\t-c : creator\n")); printf (_("\t-l : limits\n\t-u : summary\n")); printf (_("-i id [-s -q -m] : details on resource identified by id\n")); usage(); return;}intmain (int argc, char **argv) { int opt, msg = 0, sem = 0, shm = 0, id=0, print=0; char format = 0; char options[] = "atcluphsmqi:"; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); progname = argv[0]; while ((opt = getopt (argc, argv, options)) != -1) { switch (opt) { case 'i': id = atoi (optarg); print = 1; break; case 'a': msg = shm = sem = 1; break; case 'q': msg = 1; break; case 's': sem = 1; break; case 'm': shm = 1; break; case 't': format = TIME; break; case 'c': format = CREATOR; break; case 'p': format = PID; break; case 'l': format = LIMITS; break; case 'u': format = STATUS; break; case 'h': help(); exit (0); case '?': usage(); exit (0); } } if (print) { if (shm) { print_shm (id); exit (0); } if (sem) { print_sem (id); exit (0); } if (msg) { print_msg (id); exit (0); } usage(); } if ( !shm && !msg && !sem) msg = sem = shm = 1; printf ("\n"); if (shm) { do_shm (format); printf ("\n"); } if (sem) { do_sem (format); printf ("\n"); } if (msg) { do_msg (format); printf ("\n"); } return 0;}static voidprint_perms (int id, struct ipc_perm *ipcp) { struct passwd *pw; struct group *gr; printf ("%-10d %-10o", id, ipcp->mode & 0777); if ((pw = getpwuid(ipcp->cuid))) printf(" %-10s", pw->pw_name); else printf(" %-10d", ipcp->cuid); if ((gr = getgrgid(ipcp->cgid))) printf(" %-10s", gr->gr_name); else printf(" %-10d", ipcp->cgid); if ((pw = getpwuid(ipcp->uid))) printf(" %-10s", pw->pw_name); else printf(" %-10d", ipcp->uid); if ((gr = getgrgid(ipcp->gid))) printf(" %-10s\n", gr->gr_name); else printf(" %-10d\n", ipcp->gid);}void do_shm (char format){ int maxid, shmid, id; struct shmid_ds shmseg; struct shm_info shm_info; struct shminfo shminfo; struct ipc_perm *ipcp = &shmseg.shm_perm; struct passwd *pw; maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); if (maxid < 0) { printf (_("kernel not configured for shared memory\n")); return; } switch (format) { case LIMITS: printf (_("------ Shared Memory Limits --------\n")); if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 ) return; /* glibc 2.1.3 and all earlier libc's have ints as fields of struct shminfo; glibc 2.1.91 has unsigned long; ach */ printf (_("max number of segments = %lu\n"), (unsigned long) shminfo.shmmni); printf (_("max seg size (kbytes) = %lu\n"), (unsigned long) (shminfo.shmmax >> 10)); printf (_("max total shared memory (pages) = %lu\n"), (unsigned long) shminfo.shmall); printf (_("min seg size (bytes) = %lu\n"), (unsigned long) shminfo.shmmin); return; case STATUS: printf (_("------ Shared Memory Status --------\n")); printf (_("segments allocated %d\n"), shm_info.used_ids); printf (_("pages allocated %ld\n"), shm_info.shm_tot); printf (_("pages resident %ld\n"), shm_info.shm_rss); printf (_("pages swapped %ld\n"), shm_info.shm_swp); printf (_("Swap performance: %ld attempts\t %ld successes\n"), shm_info.swap_attempts, shm_info.swap_successes); return; case CREATOR: printf (_("------ Shared Memory Segment Creators/Owners --------\n")); printf (_("%-10s %-10s %-10s %-10s %-10s %-10s\n"), _("shmid"),_("perms"),_("cuid"),_("cgid"),_("uid"),_("gid")); break; case TIME: printf (_("------ Shared Memory Attach/Detach/Change Times --------\n")); printf (_("%-10s %-10s %-20s %-20s %-20s\n"), _("shmid"),_("owner"),_("attached"),_("detached"), _("changed")); break; case PID: printf (_("------ Shared Memory Creator/Last-op --------\n")); printf (_("%-10s %-10s %-10s %-10s\n"), _("shmid"),_("owner"),_("cpid"),_("lpid")); break; default: printf (_("------ Shared Memory Segments --------\n")); printf (_("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n"), _("key"),_("shmid"),_("owner"),_("perms"),_("bytes"), _("nattch"),_("status")); break; } for (id = 0; id <= maxid; id++) { shmid = shmctl (id, SHM_STAT, &shmseg); if (shmid < 0) continue; if (format == CREATOR) { print_perms (shmid, ipcp); continue; } pw = getpwuid(ipcp->uid); switch (format) { case TIME: if (pw) printf ("%-10d %-10.10s", shmid, pw->pw_name); else printf ("%-10d %-10d", shmid, ipcp->uid); /* ctime uses static buffer: use separate calls */ printf(" %-20.16s", shmseg.shm_atime ? ctime(&shmseg.shm_atime) + 4 : _("Not set")); printf(" %-20.16s", shmseg.shm_dtime ? ctime(&shmseg.shm_dtime) + 4 : _("Not set")); printf(" %-20.16s\n", shmseg.shm_ctime ? ctime(&shmseg.shm_ctime) + 4 : _("Not set")); break; case PID: if (pw)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -