]>
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");
129 char datestring
[100];
132 while ((i
= getopt(argc
, argv
, "MmQqSsabcoptT")) != -1)
153 display
= SHMTOTAL
| MSGTOTAL
| SEMTOTAL
;
156 option
|= BIGGEST
| CREATOR
| OUTSTANDING
| PID
| TIME
;
165 option
|= OUTSTANDING
;
177 display
= SHMINFO
| MSGINFO
| SEMINFO
;
179 struct tm
* tm
= localtime(&now
);
182 tm
= localtime(&now
);
184 if (0 == strftime(datestring
, sizeof(datestring
), "%a %b %e %H:%M:%S %Z %Y", tm
))
185 errx(1, "strftime failed\n");
186 printf("IPC status from <running system> as of %s\n", datestring
);
187 if ((display
& (MSGINFO
| MSGTOTAL
))) {
188 if (display
& MSGTOTAL
) {
189 struct IPCS_command ic
;
190 struct msginfo msginfo
;
191 size_t ic_size
= sizeof(ic
);
193 ic
.ipcs_magic
= IPCS_MAGIC
;
194 ic
.ipcs_op
= IPCS_MSG_CONF
;
195 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
196 ic
.ipcs_data
= &msginfo
;
197 ic
.ipcs_datalen
= sizeof(msginfo
);
199 if (sysctlbyname(IPCS_MSG_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
200 if (errno
!= EPERM
) {
202 snprintf(buffer
, 1024, "sysctlbyname(IPCS_MSG_SYSCTL, op=CONF, &ic, &%ld) datalen=%d",
203 sizeof(ic
), ic
.ipcs_datalen
);
206 perror("sysctlbyname IPCS_MSG_SYSCTL");
209 printf("msginfo:\n");
210 printf("\tmsgmax: %6d\t(max characters in a message)\n",
212 printf("\tmsgmni: %6d\t(# of message queues)\n",
214 printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
216 printf("\tmsgtql: %6d\t(max # of messages in system)\n",
218 printf("\tmsgssz: %6d\t(size of a message segment)\n",
220 printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
223 if (display
& MSGINFO
) {
224 struct IPCS_command ic
;
225 struct __msqid_ds_new ds
;
226 struct __msqid_ds_new
*msqptr
= &ds
;
227 size_t ic_size
= sizeof(ic
);
229 printf("T ID KEY MODE OWNER GROUP");
230 if (option
& CREATOR
)
231 printf(" CREATOR CGROUP");
232 if (option
& OUTSTANDING
)
233 printf(" CBYTES QNUM");
234 if (option
& BIGGEST
)
237 printf(" LSPID LRPID");
239 printf(" STIME RTIME CTIME");
240 printf("\nMessage Queues:\n");
242 ic
.ipcs_magic
= IPCS_MAGIC
;
243 ic
.ipcs_op
= IPCS_MSG_ITER
;
244 ic
.ipcs_cursor
= 0; /* start */
245 ic
.ipcs_datalen
= sizeof(*msqptr
);
246 ic
.ipcs_data
= msqptr
;
248 memset(msqptr
, 0, sizeof(*msqptr
));
250 while(!(sysctlbyname(IPCS_MSG_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
251 ic
.ipcs_data
= msqptr
;
253 if (msqptr
->msg_qbytes
!= 0) {
254 char stime_buf
[100], rtime_buf
[100],
257 cvt_time(msqptr
->msg_stime
, stime_buf
);
258 cvt_time(msqptr
->msg_rtime
, rtime_buf
);
259 cvt_time(msqptr
->msg_ctime
, ctime_buf
);
261 printf("q %6d 0x%08x %s %8s %8s",
262 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), msqptr
->msg_perm
),
263 (int)msqptr
->msg_perm
._key
,
264 fmt_perm(msqptr
->msg_perm
.mode
, 'w'),
265 user_from_uid(msqptr
->msg_perm
.uid
, 0),
266 group_from_gid(msqptr
->msg_perm
.gid
, 0));
268 if (option
& CREATOR
)
270 user_from_uid(msqptr
->msg_perm
.cuid
, 0),
271 group_from_gid(msqptr
->msg_perm
.cgid
, 0));
273 if (option
& OUTSTANDING
)
278 if (option
& BIGGEST
)
295 memset(msqptr
, 0, sizeof(*msqptr
));
299 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
300 if (errno
!= EPERM
) {
301 errx(1, "sysctlbyname(IPCS_MSG_SYSCTL, op=ITER, &ic, &%ld) datalen=%d failed:%s\n",
302 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
304 errx(1, "sysctlbyname IPCS_MSG_SYSCTL: %s", strerror(errno
));
309 if (display
& (MSGINFO
| MSGTOTAL
)) {
310 errx(1, "%s", "SVID messages facility not configured in the system\n");
313 if ((display
& (SHMINFO
| SHMTOTAL
))) {
314 if (display
& SHMTOTAL
) {
315 struct IPCS_command ic
;
316 struct shminfo shminfo
;
317 size_t ic_size
= sizeof(ic
);
319 ic
.ipcs_magic
= IPCS_MAGIC
;
320 ic
.ipcs_op
= IPCS_SHM_CONF
;
321 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
322 ic
.ipcs_data
= &shminfo
;
323 ic
.ipcs_datalen
= sizeof(shminfo
);
325 if (sysctlbyname(IPCS_SHM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
326 if (errno
!= EPERM
) {
327 errx(1, "sysctlbyname(IPCS_SHM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d failed: %s\n",
328 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
330 errx(1, "sysctlbyname: %s", strerror(errno
));
332 printf("shminfo:\n");
333 printf("\tshmmax: %7lld\t(max shared memory segment size)\n",
335 printf("\tshmmin: %7lld\t(min shared memory segment size)\n",
337 printf("\tshmmni: %7lld\t(max number of shared memory identifiers)\n",
339 printf("\tshmseg: %7lld\t(max shared memory segments per process)\n",
341 printf("\tshmall: %7lld\t(max amount of shared memory in pages)\n\n",
344 if (display
& SHMINFO
) {
345 struct IPCS_command ic
;
346 struct __shmid_ds_new ds
;
347 struct __shmid_ds_new
*shmptr
= &ds
;
348 size_t ic_size
= sizeof(ic
);
350 printf("T ID KEY MODE OWNER GROUP");
351 if (option
& CREATOR
)
352 printf(" CREATOR CGROUP");
353 if (option
& OUTSTANDING
)
355 if (option
& BIGGEST
)
358 printf(" CPID LPID");
360 printf(" ATIME DTIME CTIME");
361 printf("\nShared Memory:\n");
364 ic
.ipcs_magic
= IPCS_MAGIC
;
365 ic
.ipcs_op
= IPCS_SHM_ITER
;
366 ic
.ipcs_cursor
= 0; /* start */
367 ic
.ipcs_datalen
= sizeof(*shmptr
);
368 ic
.ipcs_data
= shmptr
;
369 memset(shmptr
, 0, sizeof(*shmptr
));
371 while(!(sysctlbyname(IPCS_SHM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
372 ic
.ipcs_data
= shmptr
; /* xnu workaround */
374 if (shmptr
->shm_perm
.mode
& 0x0800) {
375 char atime_buf
[100], dtime_buf
[100],
378 cvt_time(shmptr
->shm_atime
, atime_buf
);
379 cvt_time(shmptr
->shm_dtime
, dtime_buf
);
380 cvt_time(shmptr
->shm_ctime
, ctime_buf
);
382 printf("m %6d 0x%08x %s %8s %8s",
383 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), shmptr
->shm_perm
),
384 (int)shmptr
->shm_perm
._key
,
385 fmt_perm(shmptr
->shm_perm
.mode
, 'w'),
386 user_from_uid(shmptr
->shm_perm
.uid
, 0),
387 group_from_gid(shmptr
->shm_perm
.gid
, 0));
389 if (option
& CREATOR
)
391 user_from_uid(shmptr
->shm_perm
.cuid
, 0),
392 group_from_gid(shmptr
->shm_perm
.cgid
, 0));
394 if (option
& OUTSTANDING
)
398 if (option
& BIGGEST
)
415 memset(shmptr
, 0, sizeof(*shmptr
));
419 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
420 if (errno
!= EPERM
) {
421 errx(1, "sysctlbyname(IPCS_SHM_SYSCTL, op=ITER, &ic, &%ld) datalen=%d failed:%s\n",
422 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
424 errx(1, "sysctlbyname: %s", strerror(errno
));
431 if (display
& (SHMINFO
| SHMTOTAL
)) {
432 errx(1, "%s", "SVID shared memory facility not configured in the system\n");
435 if ((display
& (SEMINFO
| SEMTOTAL
))) {
436 if (display
& SEMTOTAL
) {
437 struct IPCS_command ic
;
438 struct seminfo seminfo
;
439 size_t ic_size
= sizeof(ic
);
441 ic
.ipcs_magic
= IPCS_MAGIC
;
442 ic
.ipcs_op
= IPCS_SEM_CONF
;
443 ic
.ipcs_cursor
= 0; /* 0 for fw. compat. */
444 ic
.ipcs_data
= &seminfo
;
445 ic
.ipcs_datalen
= sizeof(seminfo
);
447 if (sysctlbyname(IPCS_SEM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
)) {
448 if (errno
!= EPERM
) {
450 snprintf(buffer
, 1024, "sysctlbyname(IPCS_SEM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d",
451 sizeof(ic
), ic
.ipcs_datalen
);
454 perror("sysctlbyname IPCS_SEM_SYSCTL/SEM_CONF");
457 printf("seminfo:\n");
458 printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
460 printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
462 printf("\tsemmns: %6d\t(# of semaphores in system)\n",
464 printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
466 printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
468 printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
470 printf("\tsemume: %6d\t(max # of undo entries per process)\n",
472 printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
474 printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
476 printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
479 if (display
& SEMINFO
) {
480 struct IPCS_command ic
;
481 struct __semid_ds_new ds
;
482 struct __semid_ds_new
*semaptr
= &ds
;
483 size_t ic_size
= sizeof(ic
);
485 printf("T ID KEY MODE OWNER GROUP");
486 if (option
& CREATOR
)
487 printf(" CREATOR CGROUP");
488 if (option
& BIGGEST
)
491 printf(" OTIME CTIME");
492 printf("\nSemaphores:\n");
494 ic
.ipcs_magic
= IPCS_MAGIC
;
495 ic
.ipcs_op
= IPCS_SEM_ITER
;
496 ic
.ipcs_cursor
= 0; /* start */
497 ic
.ipcs_datalen
= sizeof(*semaptr
);
498 ic
.ipcs_data
= semaptr
;
500 memset(semaptr
, 0, sizeof(*semaptr
));
502 while(!(sysctlbyname(IPCS_SEM_SYSCTL
, &ic
, &ic_size
, &ic
, ic_size
))) {
503 ic
.ipcs_data
= semaptr
; /* xnu workaround */
505 if ((semaptr
->sem_perm
.mode
& SEM_ALLOC
) != 0) {
506 char ctime_buf
[100], otime_buf
[100];
508 cvt_time(semaptr
->sem_otime
, otime_buf
);
509 cvt_time(semaptr
->sem_ctime
, ctime_buf
);
511 printf("s %6d 0x%08x %s %8s %8s",
512 IXSEQ_TO_IPCID((ic
.ipcs_cursor
-1), semaptr
->sem_perm
),
513 (int)semaptr
->sem_perm
._key
,
514 fmt_perm(semaptr
->sem_perm
.mode
, 'a'),
515 user_from_uid(semaptr
->sem_perm
.uid
, 0),
516 group_from_gid(semaptr
->sem_perm
.gid
, 0));
518 if (option
& CREATOR
)
520 user_from_uid(semaptr
->sem_perm
.cuid
, 0),
521 group_from_gid(semaptr
->sem_perm
.cgid
, 0));
523 if (option
& BIGGEST
)
534 memset(semaptr
, 0, sizeof(*semaptr
));
538 if (errno
!= ENOENT
&& errno
!= ERANGE
) {
539 if (errno
!= EPERM
) {
540 errx(1, "sysctlbyname(IPCS_SEM_SYSCTL/ITER, op=ITER, &ic, &%ld) datalen=%d failed: %s\n",
541 sizeof(ic
), ic
.ipcs_datalen
, strerror(errno
));
543 errx(1, "sysctlbyname: IPCS_SEM_SYSCTL %s", strerror(errno
));
548 if (display
& (SEMINFO
| SEMTOTAL
)) {
549 errx(1, "%s", "SVID semaphores facility not configured in the system\n");