]>
Commit | Line | Data |
---|---|---|
c59d3020 A |
1 | /* |
2 | * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
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. | |
15 | * | |
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. | |
26 | */ | |
27 | ||
28 | #include <sys/cdefs.h> | |
29 | ||
30 | #include <assert.h> | |
31 | #include <err.h> | |
32 | #include <fcntl.h> | |
33 | #include <grp.h> | |
c59d3020 A |
34 | #include <nlist.h> |
35 | #include <limits.h> | |
36 | #include <paths.h> | |
37 | #include <pwd.h> | |
38 | #include <stddef.h> | |
39 | #include <stdio.h> | |
40 | #include <stdlib.h> | |
41 | #include <string.h> | |
42 | #include <unistd.h> | |
864a4b6e | 43 | #include <sysexits.h> |
c59d3020 | 44 | |
40bf83fe | 45 | #include "sys/types.h" |
c59d3020 | 46 | #include <sys/ucred.h> |
864a4b6e | 47 | #include <sys/time.h> |
c59d3020 A |
48 | #include <sys/proc.h> |
49 | #include <sys/param.h> | |
c59d3020 | 50 | #include <sys/sysctl.h> |
864a4b6e | 51 | #include <errno.h> |
c59d3020 | 52 | #include "sys/ipcs.h" |
864a4b6e A |
53 | #define KERNEL 1 /* To get new ipc_perm and __(sem|shm|msg)ds_new */ |
54 | #include "sys/ipc.h" | |
55 | #include "sys/sem_internal.h" | |
56 | #include "sys/shm_internal.h" | |
57 | #include "sys/msg.h" | |
58 | ||
c59d3020 A |
59 | |
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 | |
864a4b6e | 63 | #define IXSEQ_TO_IPCID(ix,perm) (((perm._seq) << 16L) | (ix & 0xffff)) |
c59d3020 A |
64 | #endif |
65 | ||
4d0bb651 | 66 | static char * |
864a4b6e | 67 | fmt_perm(u_short mode, char write_char) |
c59d3020 A |
68 | { |
69 | static char buffer[100]; | |
70 | ||
71 | buffer[0] = '-'; | |
72 | buffer[1] = '-'; | |
73 | buffer[2] = ((mode & 0400) ? 'r' : '-'); | |
864a4b6e A |
74 | buffer[3] = ((mode & 0200) ? write_char : '-'); |
75 | buffer[4] = '-'; | |
c59d3020 | 76 | buffer[5] = ((mode & 0040) ? 'r' : '-'); |
864a4b6e A |
77 | buffer[6] = ((mode & 0020) ? write_char : '-'); |
78 | buffer[7] = '-'; | |
c59d3020 | 79 | buffer[8] = ((mode & 0004) ? 'r' : '-'); |
864a4b6e A |
80 | buffer[9] = ((mode & 0002) ? write_char : '-'); |
81 | buffer[10] = '-'; | |
c59d3020 A |
82 | buffer[11] = '\0'; |
83 | return (&buffer[0]); | |
84 | } | |
85 | ||
4d0bb651 | 86 | static void |
864a4b6e | 87 | cvt_time(time_t t, char *buf) |
c59d3020 A |
88 | { |
89 | struct tm *tm; | |
90 | ||
91 | if (t == 0) { | |
92 | strcpy(buf, "no-entry"); | |
93 | } else { | |
94 | tm = localtime(&t); | |
4d0bb651 A |
95 | if (tm != NULL) { |
96 | sprintf(buf, "%2d:%02d:%02d", | |
97 | tm->tm_hour, tm->tm_min, tm->tm_sec); | |
98 | } | |
c59d3020 A |
99 | } |
100 | } | |
101 | #define SHMINFO 1 | |
102 | #define SHMTOTAL 2 | |
103 | #define MSGINFO 4 | |
104 | #define MSGTOTAL 8 | |
105 | #define SEMINFO 16 | |
106 | #define SEMTOTAL 32 | |
107 | ||
108 | #define BIGGEST 1 | |
109 | #define CREATOR 2 | |
110 | #define OUTSTANDING 4 | |
111 | #define PID 8 | |
112 | #define TIME 16 | |
113 | ||
4d0bb651 A |
114 | static void |
115 | usage(void) | |
864a4b6e A |
116 | { |
117 | errx(EX_USAGE, "%s","usage: ipcs [-abcmopqstMQST]\n"); | |
118 | } | |
119 | ||
c59d3020 A |
120 | int |
121 | main(argc, argv) | |
122 | int argc; | |
123 | char *argv[]; | |
124 | { | |
864a4b6e | 125 | int display = 0; |
c59d3020 | 126 | int option = 0; |
864a4b6e A |
127 | int exit_val = 0; |
128 | time_t now; | |
129 | char datestring[100]; | |
130 | int i; | |
131 | ||
c59d3020 A |
132 | while ((i = getopt(argc, argv, "MmQqSsabcoptT")) != -1) |
133 | switch (i) { | |
134 | case 'M': | |
135 | display = SHMTOTAL; | |
136 | break; | |
137 | case 'm': | |
864a4b6e | 138 | display |= SHMINFO; |
c59d3020 A |
139 | break; |
140 | case 'Q': | |
141 | display = MSGTOTAL; | |
142 | break; | |
143 | case 'q': | |
864a4b6e | 144 | display |= MSGINFO; |
c59d3020 A |
145 | break; |
146 | case 'S': | |
147 | display = SEMTOTAL; | |
148 | break; | |
149 | case 's': | |
864a4b6e | 150 | display |= SEMINFO; |
c59d3020 A |
151 | break; |
152 | case 'T': | |
153 | display = SHMTOTAL | MSGTOTAL | SEMTOTAL; | |
154 | break; | |
155 | case 'a': | |
156 | option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; | |
157 | break; | |
158 | case 'b': | |
159 | option |= BIGGEST; | |
160 | break; | |
161 | case 'c': | |
162 | option |= CREATOR; | |
163 | break; | |
164 | case 'o': | |
165 | option |= OUTSTANDING; | |
166 | break; | |
167 | case 'p': | |
168 | option |= PID; | |
169 | break; | |
170 | case 't': | |
171 | option |= TIME; | |
172 | break; | |
173 | default: | |
174 | usage(); | |
175 | } | |
864a4b6e A |
176 | if (display == 0) |
177 | display = SHMINFO | MSGINFO | SEMINFO; | |
178 | now = time(0); | |
4d0bb651 A |
179 | struct tm* tm = localtime(&now); |
180 | if (tm == NULL) { | |
181 | now = 0; | |
182 | tm = localtime(&now); | |
183 | } | |
184 | if (0 == strftime(datestring, sizeof(datestring), "%a %b %e %H:%M:%S %Z %Y", tm)) | |
864a4b6e A |
185 | errx(1, "strftime failed\n"); |
186 | printf("IPC status from <running system> as of %s\n", datestring); | |
c59d3020 A |
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); | |
192 | ||
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); | |
198 | ||
29341915 | 199 | if (sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size)) { |
864a4b6e A |
200 | if (errno != EPERM) { |
201 | char buffer[1024]; | |
202 | snprintf(buffer, 1024, "sysctlbyname(IPCS_MSG_SYSCTL, op=CONF, &ic, &%ld) datalen=%d", | |
203 | sizeof(ic), ic.ipcs_datalen); | |
204 | perror(buffer); | |
205 | } else | |
206 | perror("sysctlbyname IPCS_MSG_SYSCTL"); | |
207 | } | |
208 | ||
c59d3020 A |
209 | printf("msginfo:\n"); |
210 | printf("\tmsgmax: %6d\t(max characters in a message)\n", | |
211 | msginfo.msgmax); | |
212 | printf("\tmsgmni: %6d\t(# of message queues)\n", | |
213 | msginfo.msgmni); | |
214 | printf("\tmsgmnb: %6d\t(max characters in a message queue)\n", | |
215 | msginfo.msgmnb); | |
216 | printf("\tmsgtql: %6d\t(max # of messages in system)\n", | |
217 | msginfo.msgtql); | |
218 | printf("\tmsgssz: %6d\t(size of a message segment)\n", | |
219 | msginfo.msgssz); | |
220 | printf("\tmsgseg: %6d\t(# of message segments in system)\n\n", | |
221 | msginfo.msgseg); | |
222 | } | |
223 | if (display & MSGINFO) { | |
224 | struct IPCS_command ic; | |
864a4b6e A |
225 | struct __msqid_ds_new ds; |
226 | struct __msqid_ds_new *msqptr = &ds; | |
c59d3020 A |
227 | size_t ic_size = sizeof(ic); |
228 | ||
c59d3020 A |
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) | |
235 | printf(" QBYTES"); | |
236 | if (option & PID) | |
237 | printf(" LSPID LRPID"); | |
238 | if (option & TIME) | |
239 | printf(" STIME RTIME CTIME"); | |
864a4b6e | 240 | printf("\nMessage Queues:\n"); |
c59d3020 A |
241 | |
242 | ic.ipcs_magic = IPCS_MAGIC; | |
243 | ic.ipcs_op = IPCS_MSG_ITER; | |
244 | ic.ipcs_cursor = 0; /* start */ | |
c59d3020 | 245 | ic.ipcs_datalen = sizeof(*msqptr); |
864a4b6e A |
246 | ic.ipcs_data = msqptr; |
247 | ||
248 | memset(msqptr, 0, sizeof(*msqptr)); | |
249 | ||
29341915 | 250 | while(!(sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size))) { |
864a4b6e | 251 | ic.ipcs_data = msqptr; |
c59d3020 | 252 | |
c59d3020 A |
253 | if (msqptr->msg_qbytes != 0) { |
254 | char stime_buf[100], rtime_buf[100], | |
255 | ctime_buf[100]; | |
256 | ||
257 | cvt_time(msqptr->msg_stime, stime_buf); | |
258 | cvt_time(msqptr->msg_rtime, rtime_buf); | |
259 | cvt_time(msqptr->msg_ctime, ctime_buf); | |
260 | ||
864a4b6e | 261 | printf("q %6d 0x%08x %s %8s %8s", |
40bf83fe | 262 | IXSEQ_TO_IPCID((ic.ipcs_cursor-1), msqptr->msg_perm), |
864a4b6e A |
263 | (int)msqptr->msg_perm._key, |
264 | fmt_perm(msqptr->msg_perm.mode, 'w'), | |
c59d3020 A |
265 | user_from_uid(msqptr->msg_perm.uid, 0), |
266 | group_from_gid(msqptr->msg_perm.gid, 0)); | |
267 | ||
268 | if (option & CREATOR) | |
269 | printf(" %8s %8s", | |
270 | user_from_uid(msqptr->msg_perm.cuid, 0), | |
271 | group_from_gid(msqptr->msg_perm.cgid, 0)); | |
272 | ||
273 | if (option & OUTSTANDING) | |
274 | printf(" %6lu %6lu", | |
275 | msqptr->msg_cbytes, | |
276 | msqptr->msg_qnum); | |
277 | ||
278 | if (option & BIGGEST) | |
279 | printf(" %6lu", | |
280 | msqptr->msg_qbytes); | |
281 | ||
282 | if (option & PID) | |
283 | printf(" %6d %6d", | |
284 | msqptr->msg_lspid, | |
285 | msqptr->msg_lrpid); | |
286 | ||
287 | if (option & TIME) | |
288 | printf(" %s %s %s", | |
289 | stime_buf, | |
290 | rtime_buf, | |
291 | ctime_buf); | |
292 | ||
293 | printf("\n"); | |
294 | } | |
864a4b6e A |
295 | memset(msqptr, 0, sizeof(*msqptr)); |
296 | errno = 0; | |
297 | } | |
298 | ||
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)); | |
303 | } else | |
304 | errx(1, "sysctlbyname IPCS_MSG_SYSCTL: %s", strerror(errno)); | |
c59d3020 A |
305 | } |
306 | printf("\n"); | |
307 | } | |
308 | } else | |
309 | if (display & (MSGINFO | MSGTOTAL)) { | |
864a4b6e | 310 | errx(1, "%s", "SVID messages facility not configured in the system\n"); |
c59d3020 A |
311 | } |
312 | ||
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); | |
318 | ||
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); | |
324 | ||
29341915 | 325 | if (sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { |
864a4b6e A |
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)); | |
329 | } else | |
330 | errx(1, "sysctlbyname: %s", strerror(errno)); | |
331 | } | |
c59d3020 | 332 | printf("shminfo:\n"); |
864a4b6e | 333 | printf("\tshmmax: %7lld\t(max shared memory segment size)\n", |
c59d3020 | 334 | shminfo.shmmax); |
864a4b6e | 335 | printf("\tshmmin: %7lld\t(min shared memory segment size)\n", |
c59d3020 | 336 | shminfo.shmmin); |
864a4b6e | 337 | printf("\tshmmni: %7lld\t(max number of shared memory identifiers)\n", |
c59d3020 | 338 | shminfo.shmmni); |
864a4b6e | 339 | printf("\tshmseg: %7lld\t(max shared memory segments per process)\n", |
c59d3020 | 340 | shminfo.shmseg); |
864a4b6e | 341 | printf("\tshmall: %7lld\t(max amount of shared memory in pages)\n\n", |
c59d3020 A |
342 | shminfo.shmall); |
343 | } | |
344 | if (display & SHMINFO) { | |
345 | struct IPCS_command ic; | |
864a4b6e A |
346 | struct __shmid_ds_new ds; |
347 | struct __shmid_ds_new *shmptr = &ds; | |
c59d3020 A |
348 | size_t ic_size = sizeof(ic); |
349 | ||
c59d3020 A |
350 | printf("T ID KEY MODE OWNER GROUP"); |
351 | if (option & CREATOR) | |
352 | printf(" CREATOR CGROUP"); | |
353 | if (option & OUTSTANDING) | |
354 | printf(" NATTCH"); | |
355 | if (option & BIGGEST) | |
356 | printf(" SEGSZ"); | |
357 | if (option & PID) | |
358 | printf(" CPID LPID"); | |
359 | if (option & TIME) | |
360 | printf(" ATIME DTIME CTIME"); | |
864a4b6e | 361 | printf("\nShared Memory:\n"); |
c59d3020 A |
362 | { /* XXX */ |
363 | ||
364 | ic.ipcs_magic = IPCS_MAGIC; | |
365 | ic.ipcs_op = IPCS_SHM_ITER; | |
366 | ic.ipcs_cursor = 0; /* start */ | |
c59d3020 | 367 | ic.ipcs_datalen = sizeof(*shmptr); |
864a4b6e | 368 | ic.ipcs_data = shmptr; |
4d0bb651 | 369 | memset(shmptr, 0, sizeof(*shmptr)); |
864a4b6e | 370 | |
29341915 | 371 | while(!(sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { |
864a4b6e | 372 | ic.ipcs_data = shmptr; /* xnu workaround */ |
c59d3020 | 373 | |
c59d3020 A |
374 | if (shmptr->shm_perm.mode & 0x0800) { |
375 | char atime_buf[100], dtime_buf[100], | |
376 | ctime_buf[100]; | |
377 | ||
378 | cvt_time(shmptr->shm_atime, atime_buf); | |
379 | cvt_time(shmptr->shm_dtime, dtime_buf); | |
380 | cvt_time(shmptr->shm_ctime, ctime_buf); | |
381 | ||
864a4b6e | 382 | printf("m %6d 0x%08x %s %8s %8s", |
40bf83fe | 383 | IXSEQ_TO_IPCID((ic.ipcs_cursor-1), shmptr->shm_perm), |
864a4b6e A |
384 | (int)shmptr->shm_perm._key, |
385 | fmt_perm(shmptr->shm_perm.mode, 'w'), | |
c59d3020 A |
386 | user_from_uid(shmptr->shm_perm.uid, 0), |
387 | group_from_gid(shmptr->shm_perm.gid, 0)); | |
388 | ||
389 | if (option & CREATOR) | |
390 | printf(" %8s %8s", | |
391 | user_from_uid(shmptr->shm_perm.cuid, 0), | |
392 | group_from_gid(shmptr->shm_perm.cgid, 0)); | |
393 | ||
394 | if (option & OUTSTANDING) | |
395 | printf(" %6d", | |
396 | shmptr->shm_nattch); | |
397 | ||
398 | if (option & BIGGEST) | |
864a4b6e | 399 | printf(" %6ld", |
c59d3020 A |
400 | shmptr->shm_segsz); |
401 | ||
402 | if (option & PID) | |
403 | printf(" %6d %6d", | |
404 | shmptr->shm_cpid, | |
405 | shmptr->shm_lpid); | |
406 | ||
407 | if (option & TIME) | |
408 | printf(" %s %s %s", | |
409 | atime_buf, | |
410 | dtime_buf, | |
411 | ctime_buf); | |
412 | ||
413 | printf("\n"); | |
414 | } | |
864a4b6e A |
415 | memset(shmptr, 0, sizeof(*shmptr)); |
416 | errno = 0; | |
417 | } | |
418 | ||
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)); | |
423 | } else | |
424 | errx(1, "sysctlbyname: %s", strerror(errno)); | |
c59d3020 A |
425 | } |
426 | } /* XXX */ | |
427 | printf("\n"); | |
428 | } | |
429 | } | |
430 | else | |
431 | if (display & (SHMINFO | SHMTOTAL)) { | |
864a4b6e | 432 | errx(1, "%s", "SVID shared memory facility not configured in the system\n"); |
c59d3020 A |
433 | } |
434 | ||
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); | |
440 | ||
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); | |
446 | ||
29341915 | 447 | if (sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { |
864a4b6e A |
448 | if (errno != EPERM) { |
449 | char buffer[1024]; | |
450 | snprintf(buffer, 1024, "sysctlbyname(IPCS_SEM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d", | |
451 | sizeof(ic), ic.ipcs_datalen); | |
452 | perror(buffer); | |
453 | } else | |
454 | perror("sysctlbyname IPCS_SEM_SYSCTL/SEM_CONF"); | |
455 | } | |
456 | ||
c59d3020 A |
457 | printf("seminfo:\n"); |
458 | printf("\tsemmap: %6d\t(# of entries in semaphore map)\n", | |
459 | seminfo.semmap); | |
460 | printf("\tsemmni: %6d\t(# of semaphore identifiers)\n", | |
461 | seminfo.semmni); | |
462 | printf("\tsemmns: %6d\t(# of semaphores in system)\n", | |
463 | seminfo.semmns); | |
464 | printf("\tsemmnu: %6d\t(# of undo structures in system)\n", | |
465 | seminfo.semmnu); | |
466 | printf("\tsemmsl: %6d\t(max # of semaphores per id)\n", | |
467 | seminfo.semmsl); | |
468 | printf("\tsemopm: %6d\t(max # of operations per semop call)\n", | |
469 | seminfo.semopm); | |
470 | printf("\tsemume: %6d\t(max # of undo entries per process)\n", | |
471 | seminfo.semume); | |
472 | printf("\tsemusz: %6d\t(size in bytes of undo structure)\n", | |
473 | seminfo.semusz); | |
474 | printf("\tsemvmx: %6d\t(semaphore maximum value)\n", | |
475 | seminfo.semvmx); | |
476 | printf("\tsemaem: %6d\t(adjust on exit max value)\n\n", | |
477 | seminfo.semaem); | |
478 | } | |
479 | if (display & SEMINFO) { | |
480 | struct IPCS_command ic; | |
864a4b6e A |
481 | struct __semid_ds_new ds; |
482 | struct __semid_ds_new *semaptr = &ds; | |
c59d3020 A |
483 | size_t ic_size = sizeof(ic); |
484 | ||
c59d3020 A |
485 | printf("T ID KEY MODE OWNER GROUP"); |
486 | if (option & CREATOR) | |
487 | printf(" CREATOR CGROUP"); | |
488 | if (option & BIGGEST) | |
489 | printf(" NSEMS"); | |
490 | if (option & TIME) | |
491 | printf(" OTIME CTIME"); | |
864a4b6e | 492 | printf("\nSemaphores:\n"); |
c59d3020 A |
493 | |
494 | ic.ipcs_magic = IPCS_MAGIC; | |
495 | ic.ipcs_op = IPCS_SEM_ITER; | |
496 | ic.ipcs_cursor = 0; /* start */ | |
c59d3020 | 497 | ic.ipcs_datalen = sizeof(*semaptr); |
864a4b6e A |
498 | ic.ipcs_data = semaptr; |
499 | ||
500 | memset(semaptr, 0, sizeof(*semaptr)); | |
501 | ||
29341915 | 502 | while(!(sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { |
864a4b6e | 503 | ic.ipcs_data = semaptr; /* xnu workaround */ |
c59d3020 | 504 | |
c59d3020 A |
505 | if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) { |
506 | char ctime_buf[100], otime_buf[100]; | |
507 | ||
508 | cvt_time(semaptr->sem_otime, otime_buf); | |
509 | cvt_time(semaptr->sem_ctime, ctime_buf); | |
510 | ||
864a4b6e | 511 | printf("s %6d 0x%08x %s %8s %8s", |
40bf83fe | 512 | IXSEQ_TO_IPCID((ic.ipcs_cursor-1), semaptr->sem_perm), |
864a4b6e A |
513 | (int)semaptr->sem_perm._key, |
514 | fmt_perm(semaptr->sem_perm.mode, 'a'), | |
c59d3020 A |
515 | user_from_uid(semaptr->sem_perm.uid, 0), |
516 | group_from_gid(semaptr->sem_perm.gid, 0)); | |
517 | ||
518 | if (option & CREATOR) | |
519 | printf(" %8s %8s", | |
520 | user_from_uid(semaptr->sem_perm.cuid, 0), | |
521 | group_from_gid(semaptr->sem_perm.cgid, 0)); | |
522 | ||
523 | if (option & BIGGEST) | |
524 | printf(" %6d", | |
525 | semaptr->sem_nsems); | |
526 | ||
527 | if (option & TIME) | |
528 | printf(" %s %s", | |
529 | otime_buf, | |
530 | ctime_buf); | |
531 | ||
532 | printf("\n"); | |
533 | } | |
864a4b6e A |
534 | memset(semaptr, 0, sizeof(*semaptr)); |
535 | errno = 0; | |
c59d3020 A |
536 | } |
537 | ||
864a4b6e A |
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)); | |
542 | } else | |
543 | errx(1, "sysctlbyname: IPCS_SEM_SYSCTL %s", strerror(errno)); | |
544 | } | |
c59d3020 A |
545 | printf("\n"); |
546 | } | |
547 | } else | |
548 | if (display & (SEMINFO | SEMTOTAL)) { | |
864a4b6e | 549 | errx(1, "%s", "SVID semaphores facility not configured in the system\n"); |
c59d3020 A |
550 | } |
551 | ||
864a4b6e | 552 | exit(exit_val); |
c59d3020 | 553 | } |