ipcs: read shared memory values from /proc
[kzak@redhat.com: - move to ipcutils.{c,h}, - fix datatypes to be arch independent] Signed-off-by: Sami Kerola <kerolasa@iki.fi> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
e5995acda2
commit
058e81540f
3 changed files with 205 additions and 39 deletions
|
@ -25,14 +25,14 @@
|
|||
|
||||
#include "ipcutils.h"
|
||||
|
||||
|
||||
#define LIMITS 1
|
||||
#define STATUS 2
|
||||
#define CREATOR 3
|
||||
#define TIME 4
|
||||
#define PID 5
|
||||
|
||||
void do_shm (char format);
|
||||
static void do_shm (char format);
|
||||
|
||||
void do_sem (char format);
|
||||
void do_msg (char format);
|
||||
void print_shm (int id);
|
||||
|
@ -190,14 +190,13 @@ static void print_perms (int id, struct ipc_perm *ipcp)
|
|||
printf(" %-10u\n", ipcp->gid);
|
||||
}
|
||||
|
||||
void do_shm (char format)
|
||||
static void do_shm (char format)
|
||||
{
|
||||
int maxid, shmid, id;
|
||||
struct shmid_ds shmseg;
|
||||
int maxid;
|
||||
struct shm_info shm_info;
|
||||
struct ipc_perm *ipcp = &shmseg.shm_perm;
|
||||
struct passwd *pw;
|
||||
struct ipc_limits lim;
|
||||
struct shm_data *shmds, *shmdsp;
|
||||
|
||||
maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
|
||||
if (maxid < 0) {
|
||||
|
@ -269,60 +268,56 @@ void do_shm (char format)
|
|||
break;
|
||||
}
|
||||
|
||||
for (id = 0; id <= maxid; id++) {
|
||||
shmid = shmctl (id, SHM_STAT, &shmseg);
|
||||
if (shmid < 0)
|
||||
continue;
|
||||
if (ipc_shm_get_info(maxid, -1, &shmds) < 1)
|
||||
return;
|
||||
shmdsp = shmds;
|
||||
|
||||
for (shmdsp = shmds; shmdsp->next != NULL; shmdsp = shmdsp->next) {
|
||||
if (format == CREATOR) {
|
||||
print_perms (shmid, ipcp);
|
||||
ipc_print_perms(stdout, &shmdsp->shm_perm);
|
||||
continue;
|
||||
}
|
||||
pw = getpwuid(ipcp->uid);
|
||||
pw = getpwuid(shmdsp->shm_perm.uid);
|
||||
switch (format) {
|
||||
case TIME:
|
||||
if (pw)
|
||||
printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
||||
printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
|
||||
else
|
||||
printf ("%-10d %-10u", shmid, ipcp->uid);
|
||||
printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.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"));
|
||||
printf(" %-20.16s", shmdsp->shm_atim
|
||||
? ctime(&shmdsp->shm_atim) + 4 : _("Not set"));
|
||||
printf(" %-20.16s", shmdsp->shm_dtim
|
||||
? ctime(&shmdsp->shm_dtim) + 4 : _("Not set"));
|
||||
printf(" %-20.16s\n", shmdsp->shm_ctim
|
||||
? ctime(&shmdsp->shm_ctim) + 4 : _("Not set"));
|
||||
break;
|
||||
case PID:
|
||||
if (pw)
|
||||
printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
||||
printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
|
||||
else
|
||||
printf ("%-10d %-10u", shmid, ipcp->uid);
|
||||
printf (" %-10d %-10d\n",
|
||||
shmseg.shm_cpid, shmseg.shm_lpid);
|
||||
printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid);
|
||||
printf (" %-10u %-10u\n",
|
||||
shmdsp->shm_cprid, shmdsp->shm_lprid);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("0x%08x ",ipcp->KEY );
|
||||
printf("0x%08x ", shmdsp->shm_perm.key);
|
||||
if (pw)
|
||||
printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
||||
printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
|
||||
else
|
||||
printf ("%-10d %-10u", shmid, ipcp->uid);
|
||||
printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid);
|
||||
printf (" %-10o %-10lu %-10ld %-6s %-6s\n",
|
||||
ipcp->mode & 0777,
|
||||
/*
|
||||
* earlier: int, Austin has size_t
|
||||
*/
|
||||
(unsigned long) shmseg.shm_segsz,
|
||||
/*
|
||||
* glibc-2.1.3 and earlier has unsigned short;
|
||||
* Austin has shmatt_t
|
||||
*/
|
||||
(long) shmseg.shm_nattch,
|
||||
ipcp->mode & SHM_DEST ? _("dest") : " ",
|
||||
ipcp->mode & SHM_LOCKED ? _("locked") : " ");
|
||||
shmdsp->shm_perm.mode & 0777,
|
||||
shmdsp->shm_segsz,
|
||||
shmdsp->shm_nattch,
|
||||
shmdsp->shm_perm.mode & SHM_DEST ? _("dest") : " ",
|
||||
shmdsp->shm_perm.mode & SHM_LOCKED ? _("locked") : " ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ipc_shm_free_info(shmds);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "xalloc.h"
|
||||
#include "path.h"
|
||||
#include "pathnames.h"
|
||||
#include "ipcutils.h"
|
||||
|
@ -87,3 +90,138 @@ int ipc_shm_get_limits(struct ipc_limits *lim)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_shm_get_info(int maxid, int id, struct shm_data **shmds)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
struct shm_data *p;
|
||||
|
||||
p = *shmds = xmalloc(sizeof(struct shm_data));
|
||||
p->next = NULL;
|
||||
|
||||
f = path_fopen("r", 0, _PATH_PROC_SYSV_SHM);
|
||||
if (!f)
|
||||
goto fallback;
|
||||
|
||||
while (fgetc(f) != '\n'); /* skip header */
|
||||
|
||||
for (i = 0; !feof(f); i++) {
|
||||
if (fscanf(f,
|
||||
"%d %d %o %"SCNu64 " %u %u "
|
||||
"%"SCNu64 " %u %u %u %u %"SCNu64 " %"SCNu64 " %"SCNu64
|
||||
" %"SCNu64 " %"SCNu64 "\n",
|
||||
&p->shm_perm.key,
|
||||
&p->shm_perm.id,
|
||||
&p->shm_perm.mode,
|
||||
&p->shm_segsz,
|
||||
&p->shm_cprid,
|
||||
&p->shm_lprid,
|
||||
&p->shm_nattch,
|
||||
&p->shm_perm.uid,
|
||||
&p->shm_perm.gid,
|
||||
&p->shm_perm.cuid,
|
||||
&p->shm_perm.cgid,
|
||||
&p->shm_atim,
|
||||
&p->shm_dtim,
|
||||
&p->shm_ctim,
|
||||
&p->shm_rss,
|
||||
&p->shm_swp) != 16)
|
||||
continue;
|
||||
|
||||
if (id < 0) {
|
||||
p->next = xmalloc(sizeof(struct shm_data));
|
||||
p = p->next;
|
||||
p->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
free(*shmds);
|
||||
fclose(f);
|
||||
return i;
|
||||
|
||||
/* Fallback; /proc or /sys file(s) missing. */
|
||||
fallback:
|
||||
i = id < 0 ? 0 : id;
|
||||
|
||||
while (i <= maxid) {
|
||||
int shmid;
|
||||
struct shmid_ds shmseg;
|
||||
struct ipc_perm *ipcp = &shmseg.shm_perm;
|
||||
|
||||
shmid = shmctl(i, SHM_STAT, &shmseg);
|
||||
if (shmid < 0) {
|
||||
if (-1 < id) {
|
||||
free(*shmds);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p->shm_perm.key = ipcp->KEY;
|
||||
p->shm_perm.id = shmid;
|
||||
p->shm_perm.mode = ipcp->mode;
|
||||
p->shm_segsz = shmseg.shm_segsz;
|
||||
p->shm_cprid = shmseg.shm_cpid;
|
||||
p->shm_lprid = shmseg.shm_lpid;
|
||||
p->shm_nattch = shmseg.shm_nattch;
|
||||
p->shm_perm.uid = ipcp->uid;
|
||||
p->shm_perm.gid = ipcp->gid;
|
||||
p->shm_perm.cuid = ipcp->cuid;
|
||||
p->shm_perm.cgid = ipcp->cuid;
|
||||
p->shm_atim = shmseg.shm_atime;
|
||||
p->shm_dtim = shmseg.shm_dtime;
|
||||
p->shm_ctim = shmseg.shm_ctime;
|
||||
p->shm_rss = 0xdead;
|
||||
p->shm_swp = 0xdead;
|
||||
|
||||
if (id < 0) {
|
||||
p->next = xmalloc(sizeof(struct shm_data));
|
||||
p = p->next;
|
||||
p->next = NULL;
|
||||
i++;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void ipc_shm_free_info(struct shm_data *shmds)
|
||||
{
|
||||
while (shmds) {
|
||||
struct shm_data *next = shmds->next;
|
||||
free(shmds);
|
||||
shmds = next;
|
||||
}
|
||||
}
|
||||
|
||||
void ipc_print_perms(FILE *f, struct ipc_stat *is)
|
||||
{
|
||||
struct passwd *pw;
|
||||
struct group *gr;
|
||||
|
||||
fprintf(f, "%-10d %-10o", is->id, is->mode & 0777);
|
||||
|
||||
if ((pw = getpwuid(is->cuid)))
|
||||
fprintf(f, " %-10s", pw->pw_name);
|
||||
else
|
||||
fprintf(f, " %-10u", is->cuid);
|
||||
|
||||
if ((gr = getgrgid(is->cgid)))
|
||||
fprintf(f, " %-10s", gr->gr_name);
|
||||
else
|
||||
fprintf(f, " %-10u", is->cgid);
|
||||
|
||||
if ((pw = getpwuid(is->uid)))
|
||||
fprintf(f, " %-10s", pw->pw_name);
|
||||
else
|
||||
fprintf(f, " %-10u", is->uid);
|
||||
|
||||
if ((gr = getgrgid(is->gid)))
|
||||
fprintf(f, " %-10s\n", gr->gr_name);
|
||||
else
|
||||
fprintf(f, " %-10u\n", is->gid);
|
||||
}
|
||||
|
|
|
@ -99,4 +99,37 @@ extern int ipc_msg_get_limits(struct ipc_limits *lim);
|
|||
extern int ipc_sem_get_limits(struct ipc_limits *lim);
|
||||
extern int ipc_shm_get_limits(struct ipc_limits *lim);
|
||||
|
||||
struct ipc_stat {
|
||||
int id;
|
||||
key_t key;
|
||||
uid_t uid; /* current uid */
|
||||
gid_t gid; /* current gid */
|
||||
uid_t cuid; /* creator uid */
|
||||
gid_t cgid; /* creator gid */
|
||||
unsigned int mode;
|
||||
};
|
||||
|
||||
extern void ipc_print_perms(FILE *f, struct ipc_stat *is);
|
||||
|
||||
/* See 'struct shmid_kernel' in kernel sources
|
||||
*/
|
||||
struct shm_data {
|
||||
struct ipc_stat shm_perm;
|
||||
|
||||
uint64_t shm_nattch;
|
||||
uint64_t shm_segsz;
|
||||
time_t shm_atim;
|
||||
time_t shm_dtim;
|
||||
time_t shm_ctim;
|
||||
pid_t shm_cprid;
|
||||
pid_t shm_lprid;
|
||||
uint64_t shm_rss;
|
||||
uint64_t shm_swp;
|
||||
|
||||
struct shm_data *next;
|
||||
};
|
||||
|
||||
extern int ipc_shm_get_info(int maxid, int id, struct shm_data **shmds);
|
||||
extern void ipc_shm_free_info(struct shm_data *shmds);
|
||||
|
||||
#endif /* UTIL_LINUX_IPCUTILS_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue