]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/ipcutils.c
13 # define SEMVMX 32767 /* <= 32767 semaphore maximum value */
16 # define SHMMIN 1 /* min shared segment size in bytes */
20 int ipc_msg_get_limits(struct ipc_limits
*lim
)
22 if (path_exist(_PATH_PROC_IPC_MSGMNI
) &&
23 path_exist(_PATH_PROC_IPC_MSGMNB
) &&
24 path_exist(_PATH_PROC_IPC_MSGMAX
)) {
26 lim
->msgmni
= path_read_s32(_PATH_PROC_IPC_MSGMNI
);
27 lim
->msgmnb
= path_read_s32(_PATH_PROC_IPC_MSGMNB
);
28 lim
->msgmax
= path_read_s32(_PATH_PROC_IPC_MSGMAX
);
30 struct msginfo msginfo
;
32 if (msgctl(0, IPC_INFO
, (struct msqid_ds
*) &msginfo
) < 0)
34 lim
->msgmni
= msginfo
.msgmni
;
35 lim
->msgmnb
= msginfo
.msgmnb
;
36 lim
->msgmax
= msginfo
.msgmax
;
42 int ipc_sem_get_limits(struct ipc_limits
*lim
)
49 f
= path_fopen("r", 0, _PATH_PROC_IPC_SEM
);
51 rc
= fscanf(f
, "%d\t%d\t%d\t%d",
52 &lim
->semmsl
, &lim
->semmns
, &lim
->semopm
, &lim
->semmni
);
58 struct seminfo seminfo
;
59 union semun arg
= { .array
= (ushort
*) &seminfo
};
61 if (semctl(0, 0, IPC_INFO
, arg
) < 0)
63 lim
->semmni
= seminfo
.semmni
;
64 lim
->semmsl
= seminfo
.semmsl
;
65 lim
->semmns
= seminfo
.semmns
;
66 lim
->semopm
= seminfo
.semopm
;
72 int ipc_shm_get_limits(struct ipc_limits
*lim
)
76 if (path_exist(_PATH_PROC_IPC_SHMALL
) &&
77 path_exist(_PATH_PROC_IPC_SHMMAX
) &&
78 path_exist(_PATH_PROC_IPC_SHMMNI
)) {
80 lim
->shmall
= path_read_u64(_PATH_PROC_IPC_SHMALL
);
81 lim
->shmmax
= path_read_u64(_PATH_PROC_IPC_SHMMAX
);
82 lim
->shmmni
= path_read_u64(_PATH_PROC_IPC_SHMMNI
);
85 struct shminfo shminfo
;
87 if (shmctl(0, IPC_INFO
, (struct shmid_ds
*) &shminfo
) < 0)
89 lim
->shmmni
= shminfo
.shmmni
;
90 lim
->shmall
= shminfo
.shmall
;
96 int ipc_shm_get_info(int id
, struct shm_data
**shmds
)
101 struct shm_info dummy
;
103 p
= *shmds
= xcalloc(1, sizeof(struct shm_data
));
106 f
= path_fopen("r", 0, _PATH_PROC_SYSV_SHM
);
110 while (fgetc(f
) != '\n'); /* skip header */
112 while (feof(f
) == 0) {
114 "%d %d %o %"SCNu64
" %u %u "
115 "%"SCNu64
" %u %u %u %u %"SCNi64
" %"SCNi64
" %"SCNi64
116 " %"SCNu64
" %"SCNu64
"\n",
137 if (id
== p
->shm_perm
.id
) {
144 p
->next
= xcalloc(1, sizeof(struct shm_data
));
155 /* Fallback; /proc or /sys file(s) missing. */
159 maxid
= shmctl(0, SHM_INFO
, (struct shmid_ds
*) &dummy
);
165 struct shmid_ds shmseg
;
166 struct ipc_perm
*ipcp
= &shmseg
.shm_perm
;
168 shmid
= shmctl(i
, SHM_STAT
, &shmseg
);
178 p
->shm_perm
.key
= ipcp
->KEY
;
179 p
->shm_perm
.id
= shmid
;
180 p
->shm_perm
.mode
= ipcp
->mode
;
181 p
->shm_segsz
= shmseg
.shm_segsz
;
182 p
->shm_cprid
= shmseg
.shm_cpid
;
183 p
->shm_lprid
= shmseg
.shm_lpid
;
184 p
->shm_nattch
= shmseg
.shm_nattch
;
185 p
->shm_perm
.uid
= ipcp
->uid
;
186 p
->shm_perm
.gid
= ipcp
->gid
;
187 p
->shm_perm
.cuid
= ipcp
->cuid
;
188 p
->shm_perm
.cgid
= ipcp
->cuid
;
189 p
->shm_atim
= shmseg
.shm_atime
;
190 p
->shm_dtim
= shmseg
.shm_dtime
;
191 p
->shm_ctim
= shmseg
.shm_ctime
;
196 p
->next
= xcalloc(1, sizeof(struct shm_data
));
207 void ipc_shm_free_info(struct shm_data
*shmds
)
210 struct shm_data
*next
= shmds
->next
;
216 static void get_sem_elements(struct sem_data
*p
)
220 if (!p
|| !p
->sem_nsems
|| p
->sem_perm
.id
< 0)
223 p
->elements
= xcalloc(p
->sem_nsems
, sizeof(struct sem_elem
));
225 for (i
= 0; i
< p
->sem_nsems
; i
++) {
226 struct sem_elem
*e
= &p
->elements
[i
];
227 union semun arg
= { .val
= 0 };
229 e
->semval
= semctl(p
->sem_perm
.id
, i
, GETVAL
, arg
);
231 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETVAL)");
233 e
->ncount
= semctl(p
->sem_perm
.id
, i
, GETNCNT
, arg
);
235 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETNCNT)");
237 e
->zcount
= semctl(p
->sem_perm
.id
, i
, GETZCNT
, arg
);
239 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETZCNT)");
241 e
->pid
= semctl(p
->sem_perm
.id
, i
, GETPID
, arg
);
243 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETPID)");
247 int ipc_sem_get_info(int id
, struct sem_data
**semds
)
252 struct seminfo dummy
;
255 p
= *semds
= xcalloc(1, sizeof(struct sem_data
));
258 f
= path_fopen("r", 0, _PATH_PROC_SYSV_SEM
);
262 while (fgetc(f
) != '\n') ; /* skip header */
264 while (feof(f
) == 0) {
266 "%d %d %o %" SCNu64
" %u %u %u %u %"
267 SCNi64
" %" SCNi64
"\n",
277 &p
->sem_ctime
) != 10)
282 if (id
== p
->sem_perm
.id
) {
290 p
->next
= xcalloc(1, sizeof(struct sem_data
));
301 /* Fallback; /proc or /sys file(s) missing. */
305 arg
.array
= (ushort
*) (void *)&dummy
;
306 maxid
= semctl(0, 0, SEM_INFO
, arg
);
312 struct semid_ds semseg
;
313 struct ipc_perm
*ipcp
= &semseg
.sem_perm
;
314 arg
.buf
= (struct semid_ds
*)&semseg
;
316 semid
= semctl(i
, 0, SEM_STAT
, arg
);
326 p
->sem_perm
.key
= ipcp
->KEY
;
327 p
->sem_perm
.id
= semid
;
328 p
->sem_perm
.mode
= ipcp
->mode
;
329 p
->sem_nsems
= semseg
.sem_nsems
;
330 p
->sem_perm
.uid
= ipcp
->uid
;
331 p
->sem_perm
.gid
= ipcp
->gid
;
332 p
->sem_perm
.cuid
= ipcp
->cuid
;
333 p
->sem_perm
.cgid
= ipcp
->cuid
;
334 p
->sem_otime
= semseg
.sem_otime
;
335 p
->sem_ctime
= semseg
.sem_ctime
;
338 p
->next
= xcalloc(1, sizeof(struct sem_data
));
351 void ipc_sem_free_info(struct sem_data
*semds
)
354 struct sem_data
*next
= semds
->next
;
355 free(semds
->elements
);
361 int ipc_msg_get_info(int id
, struct msg_data
**msgds
)
366 struct msqid_ds dummy
;
367 struct msqid_ds msgseg
;
369 p
= *msgds
= xcalloc(1, sizeof(struct msg_data
));
372 f
= path_fopen("r", 0, _PATH_PROC_SYSV_MSG
);
376 while (fgetc(f
) != '\n') ; /* skip header */
378 while (feof(f
) == 0) {
380 "%d %d %o %" SCNu64
" %" SCNu64
381 " %u %u %u %u %u %u %" SCNi64
" %" SCNi64
" %" SCNi64
"\n",
400 if (id
== p
->msg_perm
.id
) {
402 * FIXME: q_qbytes are not in /proc
405 if (msgctl(id
, IPC_STAT
, &msgseg
) != -1)
406 p
->q_qbytes
= msgseg
.msg_qbytes
;
413 p
->next
= xcalloc(1, sizeof(struct msg_data
));
424 /* Fallback; /proc or /sys file(s) missing. */
428 maxid
= msgctl(id
, MSG_STAT
, &dummy
);
434 struct ipc_perm
*ipcp
= &msgseg
.msg_perm
;
436 msgid
= msgctl(i
, MSG_STAT
, &msgseg
);
446 p
->msg_perm
.key
= ipcp
->KEY
;
447 p
->msg_perm
.id
= msgid
;
448 p
->msg_perm
.mode
= ipcp
->mode
;
449 p
->q_cbytes
= msgseg
.msg_cbytes
;
450 p
->q_qnum
= msgseg
.msg_qnum
;
451 p
->q_lspid
= msgseg
.msg_lspid
;
452 p
->q_lrpid
= msgseg
.msg_lrpid
;
453 p
->msg_perm
.uid
= ipcp
->uid
;
454 p
->msg_perm
.gid
= ipcp
->gid
;
455 p
->msg_perm
.cuid
= ipcp
->cuid
;
456 p
->msg_perm
.cgid
= ipcp
->cgid
;
457 p
->q_stime
= msgseg
.msg_stime
;
458 p
->q_rtime
= msgseg
.msg_rtime
;
459 p
->q_ctime
= msgseg
.msg_ctime
;
460 p
->q_qbytes
= msgseg
.msg_qbytes
;
463 p
->next
= xcalloc(1, sizeof(struct msg_data
));
474 void ipc_msg_free_info(struct msg_data
*msgds
)
477 struct msg_data
*next
= msgds
->next
;
483 void ipc_print_perms(FILE *f
, struct ipc_stat
*is
)
488 fprintf(f
, "%-10d %-10o", is
->id
, is
->mode
& 0777);
490 if ((pw
= getpwuid(is
->cuid
)))
491 fprintf(f
, " %-10s", pw
->pw_name
);
493 fprintf(f
, " %-10u", is
->cuid
);
495 if ((gr
= getgrgid(is
->cgid
)))
496 fprintf(f
, " %-10s", gr
->gr_name
);
498 fprintf(f
, " %-10u", is
->cgid
);
500 if ((pw
= getpwuid(is
->uid
)))
501 fprintf(f
, " %-10s", pw
->pw_name
);
503 fprintf(f
, " %-10u", is
->uid
);
505 if ((gr
= getgrgid(is
->gid
)))
506 fprintf(f
, " %-10s\n", gr
->gr_name
);
508 fprintf(f
, " %-10u\n", is
->gid
);
511 void ipc_print_size(int unit
, char *msg
, uint64_t size
, const char *end
,
518 else if (msg
[strlen(msg
) - 1] == '=')
520 else if (unit
== IPC_UNIT_BYTES
)
521 printf(_("%s (bytes) = "), msg
);
522 else if (unit
== IPC_UNIT_KB
)
523 printf(_("%s (kbytes) = "), msg
);
525 printf("%s = ", msg
);
528 case IPC_UNIT_DEFAULT
:
530 sprintf(format
, "%%%dju", width
);
531 printf(format
, size
);
534 sprintf(format
, "%%%dju", width
);
535 printf(format
, size
/ 1024);
538 sprintf(format
, "%%%ds", width
);
539 printf(format
, size_to_human_string(SIZE_SUFFIX_1LETTER
, size
));
542 /* impossible occurred */