]>
git.saurik.com Git - apple/file_cmds.git/blob - ipcs/ipcs.c
2 * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
45 #include "sys/types.h"
46 #include <sys/ucred.h>
49 #include <sys/param.h>
50 #include <sys/sysctl.h>
53 #define KERNEL 1 /* To get new ipc_perm and __(sem|shm|msg)ds_new */
55 #include "sys/sem_internal.h"
56 #include "sys/shm_internal.h"
60 /* The following is a kludge, until the problem of multiple inclusions
61 of ipc.h is taken care of. */
62 #ifndef IXSEQ_TO_IPCID
63 #define IXSEQ_TO_IPCID(ix,perm) (((perm._seq) << 16L) | (ix & 0xffff))
67 fmt_perm(u_short mode
, char write_char
)
69 static char buffer
[100];
73 buffer
[2] = ((mode
& 0400) ? 'r' : '-');
74 buffer
[3] = ((mode
& 0200) ? write_char
: '-');
76 buffer
[5] = ((mode
& 0040) ? 'r' : '-');
77 buffer
[6] = ((mode
& 0020) ? write_char
: '-');
79 buffer
[8] = ((mode
& 0004) ? 'r' : '-');
80 buffer
[9] = ((mode
& 0002) ? write_char
: '-');
87 cvt_time(time_t t
, char *buf
)
92 strcpy(buf
, "no-entry");
96 sprintf(buf
, "%2d:%02d:%02d",
97 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
110 #define OUTSTANDING 4
117 errx(EX_USAGE
, "%s","usage: ipcs [-abcmopqstMQST]\n");
121 safe_sysctlbyname(const char *name
, void *oldp
, size_t *oldlenp
, void *newp
, size_t newlen
)
125 if (seteuid(0)) /* iterator needs root write access to sysctl */
126 err(1, "seteuid(0) failed");
128 rv
= sysctlbyname(name
, oldp
, oldlenp
, newp
, newlen
);
132 if (seteuid(getuid()))
133 err(1, "seteuid(%d) failed", getuid());
149 char datestring
[100];
152 if (seteuid(getuid())) /* run as user */
153 err(1, "seteuid(%d) failed", getuid());
155 while ((i
= getopt(argc
, argv
, "MmQqSsabcoptT")) != -1)
176 display
= SHMTOTAL
| MSGTOTAL
| SEMTOTAL
;
179 option
|= BIGGEST
| CREATOR
| OUTSTANDING
| PID
| TIME
;
188 option
|= OUTSTANDING
;
200 display
= SHMINFO
| MSGINFO
| SEMINFO
;
202 struct tm
* tm
= localtime(&now
);
205 tm
= localtime(&now
);
207 if (0 == strftime(datestring
, sizeof(datestring
), "%a %b %e %H:%M:%S %Z %Y", tm
))
208 errx(1, "strftime failed\n");
209 printf("IPC status from <running system> as of %s\n", datestring
);
210 if ((display
& (MSGINFO
| MSGTOTAL
))) {
211 if (display
& MSGTOTAL
) {
212 struct IPCS_command ic
;
213 struct msginfo msginfo
;
214 size_t ic_size
= sizeof(ic
);
216 ic
.ipcs_magic
= IPCS_MAGIC
;
217 ic
.ipcs_op
= IPCS_MSG_CONF
;
218 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
219 ic
.ipcs_data
= &msginfo
;
220 ic
.ipcs_datalen
= sizeof(msginfo
);
222 if (safe_sysctlbyname(IPCS_MSG_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
223 if (errno
!= EPERM
) {
225 snprintf(buffer
, 1024, "sysctlbyname(IPCS_MSG_SYSCTL, op=CONF, &ic, &%ld) datalen=%d",
226 sizeof(ic
), ic
.ipcs_datalen
);
229 perror("sysctlbyname IPCS_MSG_SYSCTL");
232 printf("msginfo:\n");
233 printf("\tmsgmax: %6d\t(max characters in a message)\n",
235 printf("\tmsgmni: %6d\t(# of message queues)\n",
237 printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
239 printf("\tmsgtql: %6d\t(max # of messages in system)\n",
241 printf("\tmsgssz: %6d\t(size of a message segment)\n",
243 printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
246 if (display
& MSGINFO
) {
247 struct IPCS_command ic
;
248 struct __msqid_ds_new ds
;
249 struct __msqid_ds_new
*msqptr
= &ds
;
250 size_t ic_size
= sizeof(ic
);
252 printf("T ID KEY MODE OWNER GROUP");
253 if (option
& CREATOR
)
254 printf(" CREATOR CGROUP");
255 if (option
& OUTSTANDING
)
256 printf(" CBYTES QNUM");
257 if (option
& BIGGEST
)
260 printf(" LSPID LRPID");
262 printf(" STIME RTIME CTIME");
263 printf("\nMessage Queues:\n");
265 ic
.ipcs_magic
= IPCS_MAGIC
;
266 ic
.ipcs_op
= IPCS_MSG_ITER
;
267 ic
.ipcs_cursor
= 0; /* start */
268 ic
.ipcs_datalen
= sizeof(*msqptr
);
269 ic
.ipcs_data
= msqptr
;
271 memset(msqptr
, 0, sizeof(*msqptr
));
273 while(!(safe_sysctlbyname(IPCS_MSG_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
274 ic
.ipcs_data
= msqptr
;
276 if (msqptr
->msg_qbytes
!= 0) {
277 char stime_buf
[100], rtime_buf
[100],
280 cvt_time(msqptr
->msg_stime
, stime_buf
);
281 cvt_time(msqptr
->msg_rtime
, rtime_buf
);
282 cvt_time(msqptr
->msg_ctime
, ctime_buf
);
284 printf("q %6d 0x%08x %s %8s %8s",
285 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), msqptr
->msg_perm
),
286 (int)msqptr
->msg_perm
._key
,
287 fmt_perm(msqptr
->msg_perm
.mode
, 'w'),
288 user_from_uid(msqptr
->msg_perm
.uid
, 0),
289 group_from_gid(msqptr
->msg_perm
.gid
, 0));
291 if (option
& CREATOR
)
293 user_from_uid(msqptr
->msg_perm
.cuid
, 0),
294 group_from_gid(msqptr
->msg_perm
.cgid
, 0));
296 if (option
& OUTSTANDING
)
301 if (option
& BIGGEST
)
318 memset(msqptr
, 0, sizeof(*msqptr
));
322 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
323 if (errno
!= EPERM
) {
324 errx(1, "sysctlbyname(IPCS_MSG_SYSCTL, op=ITER, &ic, &%ld) datalen=%d failed:%s\n",
325 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
327 errx(1, "sysctlbyname IPCS_MSG_SYSCTL: %s", strerror(errno
));
332 if (display
& (MSGINFO
| MSGTOTAL
)) {
333 errx(1, "%s", "SVID messages facility not configured in the system\n");
336 if ((display
& (SHMINFO
| SHMTOTAL
))) {
337 if (display
& SHMTOTAL
) {
338 struct IPCS_command ic
;
339 struct shminfo shminfo
;
340 size_t ic_size
= sizeof(ic
);
342 ic
.ipcs_magic
= IPCS_MAGIC
;
343 ic
.ipcs_op
= IPCS_SHM_CONF
;
344 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
345 ic
.ipcs_data
= &shminfo
;
346 ic
.ipcs_datalen
= sizeof(shminfo
);
348 if (safe_sysctlbyname(IPCS_SHM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
349 if (errno
!= EPERM
) {
350 errx(1, "sysctlbyname(IPCS_SHM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d failed: %s\n",
351 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
353 errx(1, "sysctlbyname: %s", strerror(errno
));
355 printf("shminfo:\n");
356 printf("\tshmmax: %7lld\t(max shared memory segment size)\n",
358 printf("\tshmmin: %7lld\t(min shared memory segment size)\n",
360 printf("\tshmmni: %7lld\t(max number of shared memory identifiers)\n",
362 printf("\tshmseg: %7lld\t(max shared memory segments per process)\n",
364 printf("\tshmall: %7lld\t(max amount of shared memory in pages)\n\n",
367 if (display
& SHMINFO
) {
368 struct IPCS_command ic
;
369 struct __shmid_ds_new ds
;
370 struct __shmid_ds_new
*shmptr
= &ds
;
371 size_t ic_size
= sizeof(ic
);
373 printf("T ID KEY MODE OWNER GROUP");
374 if (option
& CREATOR
)
375 printf(" CREATOR CGROUP");
376 if (option
& OUTSTANDING
)
378 if (option
& BIGGEST
)
381 printf(" CPID LPID");
383 printf(" ATIME DTIME CTIME");
384 printf("\nShared Memory:\n");
387 ic
.ipcs_magic
= IPCS_MAGIC
;
388 ic
.ipcs_op
= IPCS_SHM_ITER
;
389 ic
.ipcs_cursor
= 0; /* start */
390 ic
.ipcs_datalen
= sizeof(*shmptr
);
391 ic
.ipcs_data
= shmptr
;
392 memset(shmptr
, 0, sizeof(*shmptr
));
394 while(!(safe_sysctlbyname(IPCS_SHM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
395 ic
.ipcs_data
= shmptr
; /* xnu workaround */
397 if (shmptr
->shm_perm
.mode
& 0x0800) {
398 char atime_buf
[100], dtime_buf
[100],
401 cvt_time(shmptr
->shm_atime
, atime_buf
);
402 cvt_time(shmptr
->shm_dtime
, dtime_buf
);
403 cvt_time(shmptr
->shm_ctime
, ctime_buf
);
405 printf("m %6d 0x%08x %s %8s %8s",
406 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), shmptr
->shm_perm
),
407 (int)shmptr
->shm_perm
._key
,
408 fmt_perm(shmptr
->shm_perm
.mode
, 'w'),
409 user_from_uid(shmptr
->shm_perm
.uid
, 0),
410 group_from_gid(shmptr
->shm_perm
.gid
, 0));
412 if (option
& CREATOR
)
414 user_from_uid(shmptr
->shm_perm
.cuid
, 0),
415 group_from_gid(shmptr
->shm_perm
.cgid
, 0));
417 if (option
& OUTSTANDING
)
421 if (option
& BIGGEST
)
438 memset(shmptr
, 0, sizeof(*shmptr
));
442 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
443 if (errno
!= EPERM
) {
444 errx(1, "sysctlbyname(IPCS_SHM_SYSCTL, op=ITER, &ic, &%ld) datalen=%d failed:%s\n",
445 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
447 errx(1, "sysctlbyname: %s", strerror(errno
));
454 if (display
& (SHMINFO
| SHMTOTAL
)) {
455 errx(1, "%s", "SVID shared memory facility not configured in the system\n");
458 if ((display
& (SEMINFO
| SEMTOTAL
))) {
459 if (display
& SEMTOTAL
) {
460 struct IPCS_command ic
;
461 struct seminfo seminfo
;
462 size_t ic_size
= sizeof(ic
);
464 ic
.ipcs_magic
= IPCS_MAGIC
;
465 ic
.ipcs_op
= IPCS_SEM_CONF
;
466 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
467 ic
.ipcs_data
= &seminfo
;
468 ic
.ipcs_datalen
= sizeof(seminfo
);
470 if (safe_sysctlbyname(IPCS_SEM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
471 if (errno
!= EPERM
) {
473 snprintf(buffer
, 1024, "sysctlbyname(IPCS_SEM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d",
474 sizeof(ic
), ic
.ipcs_datalen
);
477 perror("sysctlbyname IPCS_SEM_SYSCTL/SEM_CONF");
480 printf("seminfo:\n");
481 printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
483 printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
485 printf("\tsemmns: %6d\t(# of semaphores in system)\n",
487 printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
489 printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
491 printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
493 printf("\tsemume: %6d\t(max # of undo entries per process)\n",
495 printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
497 printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
499 printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
502 if (display
& SEMINFO
) {
503 struct IPCS_command ic
;
504 struct __semid_ds_new ds
;
505 struct __semid_ds_new
*semaptr
= &ds
;
506 size_t ic_size
= sizeof(ic
);
508 printf("T ID KEY MODE OWNER GROUP");
509 if (option
& CREATOR
)
510 printf(" CREATOR CGROUP");
511 if (option
& BIGGEST
)
514 printf(" OTIME CTIME");
515 printf("\nSemaphores:\n");
517 ic
.ipcs_magic
= IPCS_MAGIC
;
518 ic
.ipcs_op
= IPCS_SEM_ITER
;
519 ic
.ipcs_cursor
= 0; /* start */
520 ic
.ipcs_datalen
= sizeof(*semaptr
);
521 ic
.ipcs_data
= semaptr
;
523 memset(semaptr
, 0, sizeof(*semaptr
));
525 while(!(safe_sysctlbyname(IPCS_SEM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
526 ic
.ipcs_data
= semaptr
; /* xnu workaround */
528 if ((semaptr
->sem_perm
.mode
& SEM_ALLOC
) != 0) {
529 char ctime_buf
[100], otime_buf
[100];
531 cvt_time(semaptr
->sem_otime
, otime_buf
);
532 cvt_time(semaptr
->sem_ctime
, ctime_buf
);
534 printf("s %6d 0x%08x %s %8s %8s",
535 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), semaptr
->sem_perm
),
536 (int)semaptr
->sem_perm
._key
,
537 fmt_perm(semaptr
->sem_perm
.mode
, 'a'),
538 user_from_uid(semaptr
->sem_perm
.uid
, 0),
539 group_from_gid(semaptr
->sem_perm
.gid
, 0));
541 if (option
& CREATOR
)
543 user_from_uid(semaptr
->sem_perm
.cuid
, 0),
544 group_from_gid(semaptr
->sem_perm
.cgid
, 0));
546 if (option
& BIGGEST
)
557 memset(semaptr
, 0, sizeof(*semaptr
));
561 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
562 if (errno
!= EPERM
) {
563 errx(1, "sysctlbyname(IPCS_SEM_SYSCTL/ITER, op=ITER, &ic, &%ld) datalen=%d failed: %s\n",
564 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
566 errx(1, "sysctlbyname: IPCS_SEM_SYSCTL %s", strerror(errno
));
571 if (display
& (SEMINFO
| SEMTOTAL
)) {
572 errx(1, "%s", "SVID semaphores facility not configured in the system\n");