]>
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");