The compat (32bit) version of sys_shmctl on 64bit kernel returns incorrect information. In this case is better to read data from /proc/sys/kernel/shm*. --- util-linux-2.13-pre7/sys-utils/ipcs.c.kzak 2007-06-25 10:25:31.000000000 +0200 +++ util-linux-2.13-pre7/sys-utils/ipcs.c 2007-06-25 10:14:06.000000000 +0200 @@ -253,6 +253,26 @@ printf(" %-10d\n", ipcp->gid); } +static unsigned long long +shminfo_from_proc(const char *name, unsigned long def) +{ + char path[256]; + char buf[64]; + FILE *f; + unsigned long long res = def; + + if (!name) + return res; + + snprintf(path, sizeof(path), "/proc/sys/kernel/%s", name); + + if (!(f = fopen(path, "r"))) + return res; + if (fgets(buf, sizeof(buf), f)) + res = atoll(buf); + fclose(f); + return res; +} void do_shm (char format) { @@ -268,7 +288,7 @@ printf (_("kernel not configured for shared memory\n")); return; } - + switch (format) { case LIMITS: printf (_("------ Shared Memory Limits --------\n")); @@ -276,18 +296,15 @@ 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 number of segments = %llu\n"), + shminfo_from_proc("shmmni", shminfo.shmmni)); + printf (_("max seg size (kbytes) = %llu\n"), + (shminfo_from_proc("shmmax", shminfo.shmmax) >> 10)); + /* max shmem = pagesize * shminfo.shmall / 1024 - * - * note: that "shminfo.shmall * getpagesize()" is greater than ULONG_MAX (32bit) - * it means that better is "/" before "*" or use "long long" */ - printf (_("max total shared memory (kbytes) = %lu\n"), - getpagesize()/1024 * (unsigned long) shminfo.shmall); + printf (_("max total shared memory (kbytes) = %llu\n"), + getpagesize()/1024 * shminfo_from_proc("shmall", shminfo.shmall)); printf (_("min seg size (bytes) = %lu\n"), (unsigned long) shminfo.shmmin); return;