]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/ipcutils.c
305ddd70010cf262a0d0c88d2c063a2fe6471796
12 # define SEMVMX 32767 /* <= 32767 semaphore maximum value */
15 # define SHMMIN 1 /* min shared segment size in bytes */
19 int ipc_msg_get_limits(struct ipc_limits
*lim
)
21 memset(lim
, 0, sizeof(*lim
));
23 if (access(_PATH_PROC_IPC_MSGMNI
, F_OK
) == 0 &&
24 access(_PATH_PROC_IPC_MSGMNB
, F_OK
) == 0 &&
25 access(_PATH_PROC_IPC_MSGMAX
, F_OK
) == 0) {
27 if (ul_path_read_s32(NULL
, &lim
->msgmni
, _PATH_PROC_IPC_MSGMNI
) != 0)
29 if (ul_path_read_s32(NULL
, &lim
->msgmnb
, _PATH_PROC_IPC_MSGMNB
) != 0)
31 if (ul_path_read_u64(NULL
, &lim
->msgmax
, _PATH_PROC_IPC_MSGMAX
) != 0)
34 struct msginfo msginfo
;
36 if (msgctl(0, IPC_INFO
, (struct msqid_ds
*) &msginfo
) < 0)
38 lim
->msgmni
= msginfo
.msgmni
;
39 lim
->msgmnb
= msginfo
.msgmnb
;
40 lim
->msgmax
= msginfo
.msgmax
;
46 int ipc_sem_get_limits(struct ipc_limits
*lim
)
53 f
= fopen(_PATH_PROC_IPC_SEM
, "r");
55 rc
= fscanf(f
, "%d\t%d\t%d\t%d",
56 &lim
->semmsl
, &lim
->semmns
, &lim
->semopm
, &lim
->semmni
);
61 struct seminfo seminfo
= { .semmni
= 0 };
62 union semun arg
= { .array
= (ushort
*) &seminfo
};
64 if (semctl(0, 0, IPC_INFO
, arg
) < 0)
66 lim
->semmni
= seminfo
.semmni
;
67 lim
->semmsl
= seminfo
.semmsl
;
68 lim
->semmns
= seminfo
.semmns
;
69 lim
->semopm
= seminfo
.semopm
;
75 int ipc_shm_get_limits(struct ipc_limits
*lim
)
79 if (access(_PATH_PROC_IPC_SHMALL
, F_OK
) == 0 &&
80 access(_PATH_PROC_IPC_SHMMAX
, F_OK
) == 0 &&
81 access(_PATH_PROC_IPC_SHMMNI
, F_OK
) == 0) {
83 ul_path_read_u64(NULL
, &lim
->shmall
, _PATH_PROC_IPC_SHMALL
);
84 ul_path_read_u64(NULL
, &lim
->shmmax
, _PATH_PROC_IPC_SHMMAX
);
85 ul_path_read_u64(NULL
, &lim
->shmmni
, _PATH_PROC_IPC_SHMMNI
);
88 struct shminfo
*shminfo
;
89 struct shmid_ds shmbuf
;
91 if (shmctl(0, IPC_INFO
, &shmbuf
) < 0)
93 shminfo
= (struct shminfo
*) &shmbuf
;
94 lim
->shmmni
= shminfo
->shmmni
;
95 lim
->shmall
= shminfo
->shmall
;
96 lim
->shmmax
= shminfo
->shmmax
;
102 int ipc_shm_get_info(int id
, struct shm_data
**shmds
)
108 struct shmid_ds dummy
;
110 p
= *shmds
= xcalloc(1, sizeof(struct shm_data
));
113 f
= fopen(_PATH_PROC_SYSV_SHM
, "r");
117 while (fgetc(f
) != '\n'); /* skip header */
119 while (fgets(buf
, sizeof(buf
), f
) != NULL
) {
120 /* scan for the first 14-16 columns (e.g. Linux 2.6.32 has 14) */
124 "%d %d %o %"SCNu64
" %u %u "
125 "%"SCNu64
" %u %u %u %u %"SCNi64
" %"SCNi64
" %"SCNi64
126 " %"SCNu64
" %"SCNu64
"\n",
143 continue; /* invalid line, skipped */
147 if (id
== p
->shm_perm
.id
) {
154 p
->next
= xcalloc(1, sizeof(struct shm_data
));
165 /* Fallback; /proc or /sys file(s) missing. */
167 maxid
= shmctl(0, SHM_INFO
, &dummy
);
169 for (j
= 0; j
<= maxid
; j
++) {
171 struct shmid_ds shmseg
;
172 struct ipc_perm
*ipcp
= &shmseg
.shm_perm
;
174 shmid
= shmctl(j
, SHM_STAT
, &shmseg
);
175 if (shmid
< 0 || (id
> -1 && shmid
!= id
)) {
180 p
->shm_perm
.key
= ipcp
->KEY
;
181 p
->shm_perm
.id
= shmid
;
182 p
->shm_perm
.mode
= ipcp
->mode
;
183 p
->shm_segsz
= shmseg
.shm_segsz
;
184 p
->shm_cprid
= shmseg
.shm_cpid
;
185 p
->shm_lprid
= shmseg
.shm_lpid
;
186 p
->shm_nattch
= shmseg
.shm_nattch
;
187 p
->shm_perm
.uid
= ipcp
->uid
;
188 p
->shm_perm
.gid
= ipcp
->gid
;
189 p
->shm_perm
.cuid
= ipcp
->cuid
;
190 p
->shm_perm
.cgid
= ipcp
->cuid
;
191 p
->shm_atim
= shmseg
.shm_atime
;
192 p
->shm_dtim
= shmseg
.shm_dtime
;
193 p
->shm_ctim
= shmseg
.shm_ctime
;
198 p
->next
= xcalloc(1, sizeof(struct shm_data
));
210 void ipc_shm_free_info(struct shm_data
*shmds
)
213 struct shm_data
*next
= shmds
->next
;
219 static void get_sem_elements(struct sem_data
*p
)
223 if (!p
|| !p
->sem_nsems
|| p
->sem_nsems
> SIZE_MAX
|| p
->sem_perm
.id
< 0)
226 p
->elements
= xcalloc(p
->sem_nsems
, sizeof(struct sem_elem
));
228 for (i
= 0; i
< p
->sem_nsems
; i
++) {
229 struct sem_elem
*e
= &p
->elements
[i
];
230 union semun arg
= { .val
= 0 };
232 e
->semval
= semctl(p
->sem_perm
.id
, i
, GETVAL
, arg
);
234 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETVAL)");
236 e
->ncount
= semctl(p
->sem_perm
.id
, i
, GETNCNT
, arg
);
238 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETNCNT)");
240 e
->zcount
= semctl(p
->sem_perm
.id
, i
, GETZCNT
, arg
);
242 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETZCNT)");
244 e
->pid
= semctl(p
->sem_perm
.id
, i
, GETPID
, arg
);
246 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETPID)");
250 int ipc_sem_get_info(int id
, struct sem_data
**semds
)
255 struct seminfo dummy
;
258 p
= *semds
= xcalloc(1, sizeof(struct sem_data
));
261 f
= fopen(_PATH_PROC_SYSV_SEM
, "r");
265 while (fgetc(f
) != '\n') ; /* skip header */
267 while (feof(f
) == 0) {
269 "%d %d %o %" SCNu64
" %u %u %u %u %"
270 SCNi64
" %" SCNi64
"\n",
280 &p
->sem_ctime
) != 10)
285 if (id
== p
->sem_perm
.id
) {
293 p
->next
= xcalloc(1, sizeof(struct sem_data
));
304 /* Fallback; /proc or /sys file(s) missing. */
306 arg
.array
= (ushort
*) (void *)&dummy
;
307 maxid
= semctl(0, 0, SEM_INFO
, arg
);
309 for (j
= 0; j
<= maxid
; j
++) {
311 struct semid_ds semseg
;
312 struct ipc_perm
*ipcp
= &semseg
.sem_perm
;
313 arg
.buf
= (struct semid_ds
*)&semseg
;
315 semid
= semctl(j
, 0, SEM_STAT
, arg
);
316 if (semid
< 0 || (id
> -1 && semid
!= id
)) {
321 p
->sem_perm
.key
= ipcp
->KEY
;
322 p
->sem_perm
.id
= semid
;
323 p
->sem_perm
.mode
= ipcp
->mode
;
324 p
->sem_nsems
= semseg
.sem_nsems
;
325 p
->sem_perm
.uid
= ipcp
->uid
;
326 p
->sem_perm
.gid
= ipcp
->gid
;
327 p
->sem_perm
.cuid
= ipcp
->cuid
;
328 p
->sem_perm
.cgid
= ipcp
->cuid
;
329 p
->sem_otime
= semseg
.sem_otime
;
330 p
->sem_ctime
= semseg
.sem_ctime
;
333 p
->next
= xcalloc(1, sizeof(struct sem_data
));
348 void ipc_sem_free_info(struct sem_data
*semds
)
351 struct sem_data
*next
= semds
->next
;
352 free(semds
->elements
);
358 int ipc_msg_get_info(int id
, struct msg_data
**msgds
)
363 struct msqid_ds dummy
;
364 struct msqid_ds msgseg
;
366 p
= *msgds
= xcalloc(1, sizeof(struct msg_data
));
369 f
= fopen(_PATH_PROC_SYSV_MSG
, "r");
373 while (fgetc(f
) != '\n') ; /* skip header */
375 while (feof(f
) == 0) {
377 "%d %d %o %" SCNu64
" %" SCNu64
378 " %u %u %u %u %u %u %" SCNi64
" %" SCNi64
" %" SCNi64
"\n",
397 if (id
== p
->msg_perm
.id
) {
398 if (msgctl(id
, IPC_STAT
, &msgseg
) != -1)
399 p
->q_qbytes
= msgseg
.msg_qbytes
;
406 p
->next
= xcalloc(1, sizeof(struct msg_data
));
417 /* Fallback; /proc or /sys file(s) missing. */
419 maxid
= msgctl(0, MSG_INFO
, &dummy
);
421 for (j
= 0; j
<= maxid
; j
++) {
423 struct ipc_perm
*ipcp
= &msgseg
.msg_perm
;
425 msgid
= msgctl(j
, MSG_STAT
, &msgseg
);
426 if (msgid
< 0 || (id
> -1 && msgid
!= id
)) {
431 p
->msg_perm
.key
= ipcp
->KEY
;
432 p
->msg_perm
.id
= msgid
;
433 p
->msg_perm
.mode
= ipcp
->mode
;
434 p
->q_cbytes
= msgseg
.msg_cbytes
;
435 p
->q_qnum
= msgseg
.msg_qnum
;
436 p
->q_lspid
= msgseg
.msg_lspid
;
437 p
->q_lrpid
= msgseg
.msg_lrpid
;
438 p
->msg_perm
.uid
= ipcp
->uid
;
439 p
->msg_perm
.gid
= ipcp
->gid
;
440 p
->msg_perm
.cuid
= ipcp
->cuid
;
441 p
->msg_perm
.cgid
= ipcp
->cgid
;
442 p
->q_stime
= msgseg
.msg_stime
;
443 p
->q_rtime
= msgseg
.msg_rtime
;
444 p
->q_ctime
= msgseg
.msg_ctime
;
445 p
->q_qbytes
= msgseg
.msg_qbytes
;
448 p
->next
= xcalloc(1, sizeof(struct msg_data
));
460 void ipc_msg_free_info(struct msg_data
*msgds
)
463 struct msg_data
*next
= msgds
->next
;
469 void ipc_print_perms(FILE *f
, struct ipc_stat
*is
)
474 fprintf(f
, "%-10d %-10o", is
->id
, is
->mode
& 0777);
476 if ((pw
= getpwuid(is
->cuid
)))
477 fprintf(f
, " %-10s", pw
->pw_name
);
479 fprintf(f
, " %-10u", is
->cuid
);
481 if ((gr
= getgrgid(is
->cgid
)))
482 fprintf(f
, " %-10s", gr
->gr_name
);
484 fprintf(f
, " %-10u", is
->cgid
);
486 if ((pw
= getpwuid(is
->uid
)))
487 fprintf(f
, " %-10s", pw
->pw_name
);
489 fprintf(f
, " %-10u", is
->uid
);
491 if ((gr
= getgrgid(is
->gid
)))
492 fprintf(f
, " %-10s\n", gr
->gr_name
);
494 fprintf(f
, " %-10u\n", is
->gid
);
497 void ipc_print_size(int unit
, char *msg
, uint64_t size
, const char *end
,
504 else if (msg
[strlen(msg
) - 1] == '=')
506 else if (unit
== IPC_UNIT_BYTES
)
507 printf(_("%s (bytes) = "), msg
);
508 else if (unit
== IPC_UNIT_KB
)
509 printf(_("%s (kbytes) = "), msg
);
511 printf("%s = ", msg
);
514 case IPC_UNIT_DEFAULT
:
516 snprintf(format
, sizeof(format
), "%%%dju", width
);
517 printf(format
, size
);
520 snprintf(format
, sizeof(format
), "%%%dju", width
);
521 printf(format
, size
/ 1024);
526 snprintf(format
, sizeof(format
), "%%%ds", width
);
527 printf(format
, (tmp
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
)));
532 /* impossible occurred */