#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);
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) {
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;
}
+#include <inttypes.h>
+
#include "c.h"
+#include "xalloc.h"
#include "path.h"
#include "pathnames.h"
#include "ipcutils.h"
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);
+}