]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/ipcutils.c
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 if (access(_PATH_PROC_IPC_MSGMNI
, F_OK
) == 0 &&
22 access(_PATH_PROC_IPC_MSGMNB
, F_OK
) == 0 &&
23 access(_PATH_PROC_IPC_MSGMAX
, F_OK
) == 0) {
25 ul_path_read_s32(NULL
, &lim
->msgmni
, _PATH_PROC_IPC_MSGMNI
);
26 ul_path_read_s32(NULL
, &lim
->msgmnb
, _PATH_PROC_IPC_MSGMNB
);
27 ul_path_read_u64(NULL
, &lim
->msgmax
, _PATH_PROC_IPC_MSGMAX
);
29 struct msginfo msginfo
;
31 if (msgctl(0, IPC_INFO
, (struct msqid_ds
*) &msginfo
) < 0)
33 lim
->msgmni
= msginfo
.msgmni
;
34 lim
->msgmnb
= msginfo
.msgmnb
;
35 lim
->msgmax
= msginfo
.msgmax
;
41 int ipc_sem_get_limits(struct ipc_limits
*lim
)
48 f
= fopen(_PATH_PROC_IPC_SEM
, "r");
50 rc
= fscanf(f
, "%d\t%d\t%d\t%d",
51 &lim
->semmsl
, &lim
->semmns
, &lim
->semopm
, &lim
->semmni
);
56 struct seminfo seminfo
= { .semmni
= 0 };
57 union semun arg
= { .array
= (ushort
*) &seminfo
};
59 if (semctl(0, 0, IPC_INFO
, arg
) < 0)
61 lim
->semmni
= seminfo
.semmni
;
62 lim
->semmsl
= seminfo
.semmsl
;
63 lim
->semmns
= seminfo
.semmns
;
64 lim
->semopm
= seminfo
.semopm
;
70 int ipc_shm_get_limits(struct ipc_limits
*lim
)
74 if (access(_PATH_PROC_IPC_SHMALL
, F_OK
) == 0 &&
75 access(_PATH_PROC_IPC_SHMMAX
, F_OK
) == 0 &&
76 access(_PATH_PROC_IPC_SHMMNI
, F_OK
) == 0) {
78 ul_path_read_u64(NULL
, &lim
->shmall
, _PATH_PROC_IPC_SHMALL
);
79 ul_path_read_u64(NULL
, &lim
->shmmax
, _PATH_PROC_IPC_SHMMAX
);
80 ul_path_read_u64(NULL
, &lim
->shmmni
, _PATH_PROC_IPC_SHMMNI
);
83 struct shminfo
*shminfo
;
84 struct shmid_ds shmbuf
;
86 if (shmctl(0, IPC_INFO
, &shmbuf
) < 0)
88 shminfo
= (struct shminfo
*) &shmbuf
;
89 lim
->shmmni
= shminfo
->shmmni
;
90 lim
->shmall
= shminfo
->shmall
;
91 lim
->shmmax
= shminfo
->shmmax
;
97 int ipc_shm_get_info(int id
, struct shm_data
**shmds
)
103 struct shmid_ds dummy
;
105 p
= *shmds
= xcalloc(1, sizeof(struct shm_data
));
108 f
= fopen(_PATH_PROC_SYSV_SHM
, "r");
112 while (fgetc(f
) != '\n'); /* skip header */
114 while (fgets(buf
, sizeof(buf
), f
) != NULL
) {
115 /* scan for the first 14-16 columns (e.g. Linux 2.6.32 has 14) */
119 "%d %d %o %"SCNu64
" %u %u "
120 "%"SCNu64
" %u %u %u %u %"SCNi64
" %"SCNi64
" %"SCNi64
121 " %"SCNu64
" %"SCNu64
"\n",
138 continue; /* invalid line, skipped */
142 if (id
== p
->shm_perm
.id
) {
149 p
->next
= xcalloc(1, sizeof(struct shm_data
));
160 /* Fallback; /proc or /sys file(s) missing. */
162 maxid
= shmctl(0, SHM_INFO
, &dummy
);
164 for (int j
= 0; j
<= maxid
; j
++) {
166 struct shmid_ds shmseg
;
167 struct ipc_perm
*ipcp
= &shmseg
.shm_perm
;
169 shmid
= shmctl(j
, SHM_STAT
, &shmseg
);
170 if (shmid
< 0 || (id
> -1 && shmid
!= id
)) {
175 p
->shm_perm
.key
= ipcp
->KEY
;
176 p
->shm_perm
.id
= shmid
;
177 p
->shm_perm
.mode
= ipcp
->mode
;
178 p
->shm_segsz
= shmseg
.shm_segsz
;
179 p
->shm_cprid
= shmseg
.shm_cpid
;
180 p
->shm_lprid
= shmseg
.shm_lpid
;
181 p
->shm_nattch
= shmseg
.shm_nattch
;
182 p
->shm_perm
.uid
= ipcp
->uid
;
183 p
->shm_perm
.gid
= ipcp
->gid
;
184 p
->shm_perm
.cuid
= ipcp
->cuid
;
185 p
->shm_perm
.cgid
= ipcp
->cuid
;
186 p
->shm_atim
= shmseg
.shm_atime
;
187 p
->shm_dtim
= shmseg
.shm_dtime
;
188 p
->shm_ctim
= shmseg
.shm_ctime
;
193 p
->next
= xcalloc(1, sizeof(struct shm_data
));
205 void ipc_shm_free_info(struct shm_data
*shmds
)
208 struct shm_data
*next
= shmds
->next
;
214 static void get_sem_elements(struct sem_data
*p
)
218 if (!p
|| !p
->sem_nsems
|| p
->sem_perm
.id
< 0)
221 p
->elements
= xcalloc(p
->sem_nsems
, sizeof(struct sem_elem
));
223 for (i
= 0; i
< p
->sem_nsems
; i
++) {
224 struct sem_elem
*e
= &p
->elements
[i
];
225 union semun arg
= { .val
= 0 };
227 e
->semval
= semctl(p
->sem_perm
.id
, i
, GETVAL
, arg
);
229 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETVAL)");
231 e
->ncount
= semctl(p
->sem_perm
.id
, i
, GETNCNT
, arg
);
233 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETNCNT)");
235 e
->zcount
= semctl(p
->sem_perm
.id
, i
, GETZCNT
, arg
);
237 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETZCNT)");
239 e
->pid
= semctl(p
->sem_perm
.id
, i
, GETPID
, arg
);
241 err(EXIT_FAILURE
, _("%s failed"), "semctl(GETPID)");
245 int ipc_sem_get_info(int id
, struct sem_data
**semds
)
250 struct seminfo dummy
;
253 p
= *semds
= xcalloc(1, sizeof(struct sem_data
));
256 f
= fopen(_PATH_PROC_SYSV_SEM
, "r");
260 while (fgetc(f
) != '\n') ; /* skip header */
262 while (feof(f
) == 0) {
264 "%d %d %o %" SCNu64
" %u %u %u %u %"
265 SCNi64
" %" SCNi64
"\n",
275 &p
->sem_ctime
) != 10)
280 if (id
== p
->sem_perm
.id
) {
288 p
->next
= xcalloc(1, sizeof(struct sem_data
));
299 /* Fallback; /proc or /sys file(s) missing. */
301 arg
.array
= (ushort
*) (void *)&dummy
;
302 maxid
= semctl(0, 0, SEM_INFO
, arg
);
304 for (int j
= 0; j
<= maxid
; j
++) {
306 struct semid_ds semseg
;
307 struct ipc_perm
*ipcp
= &semseg
.sem_perm
;
308 arg
.buf
= (struct semid_ds
*)&semseg
;
310 semid
= semctl(j
, 0, SEM_STAT
, arg
);
311 if (semid
< 0 || (id
> -1 && semid
!= id
)) {
316 p
->sem_perm
.key
= ipcp
->KEY
;
317 p
->sem_perm
.id
= semid
;
318 p
->sem_perm
.mode
= ipcp
->mode
;
319 p
->sem_nsems
= semseg
.sem_nsems
;
320 p
->sem_perm
.uid
= ipcp
->uid
;
321 p
->sem_perm
.gid
= ipcp
->gid
;
322 p
->sem_perm
.cuid
= ipcp
->cuid
;
323 p
->sem_perm
.cgid
= ipcp
->cuid
;
324 p
->sem_otime
= semseg
.sem_otime
;
325 p
->sem_ctime
= semseg
.sem_ctime
;
328 p
->next
= xcalloc(1, sizeof(struct sem_data
));
343 void ipc_sem_free_info(struct sem_data
*semds
)
346 struct sem_data
*next
= semds
->next
;
347 free(semds
->elements
);
353 int ipc_msg_get_info(int id
, struct msg_data
**msgds
)
358 struct msqid_ds dummy
;
359 struct msqid_ds msgseg
;
361 p
= *msgds
= xcalloc(1, sizeof(struct msg_data
));
364 f
= fopen(_PATH_PROC_SYSV_MSG
, "r");
368 while (fgetc(f
) != '\n') ; /* skip header */
370 while (feof(f
) == 0) {
372 "%d %d %o %" SCNu64
" %" SCNu64
373 " %u %u %u %u %u %u %" SCNi64
" %" SCNi64
" %" SCNi64
"\n",
392 if (id
== p
->msg_perm
.id
) {
393 if (msgctl(id
, IPC_STAT
, &msgseg
) != -1)
394 p
->q_qbytes
= msgseg
.msg_qbytes
;
401 p
->next
= xcalloc(1, sizeof(struct msg_data
));
412 /* Fallback; /proc or /sys file(s) missing. */
414 maxid
= msgctl(0, MSG_INFO
, &dummy
);
416 for (int j
= 0; j
<= maxid
; j
++) {
418 struct ipc_perm
*ipcp
= &msgseg
.msg_perm
;
420 msgid
= msgctl(j
, MSG_STAT
, &msgseg
);
421 if (msgid
< 0 || (id
> -1 && msgid
!= id
)) {
426 p
->msg_perm
.key
= ipcp
->KEY
;
427 p
->msg_perm
.id
= msgid
;
428 p
->msg_perm
.mode
= ipcp
->mode
;
429 p
->q_cbytes
= msgseg
.msg_cbytes
;
430 p
->q_qnum
= msgseg
.msg_qnum
;
431 p
->q_lspid
= msgseg
.msg_lspid
;
432 p
->q_lrpid
= msgseg
.msg_lrpid
;
433 p
->msg_perm
.uid
= ipcp
->uid
;
434 p
->msg_perm
.gid
= ipcp
->gid
;
435 p
->msg_perm
.cuid
= ipcp
->cuid
;
436 p
->msg_perm
.cgid
= ipcp
->cgid
;
437 p
->q_stime
= msgseg
.msg_stime
;
438 p
->q_rtime
= msgseg
.msg_rtime
;
439 p
->q_ctime
= msgseg
.msg_ctime
;
440 p
->q_qbytes
= msgseg
.msg_qbytes
;
443 p
->next
= xcalloc(1, sizeof(struct msg_data
));
455 void ipc_msg_free_info(struct msg_data
*msgds
)
458 struct msg_data
*next
= msgds
->next
;
464 void ipc_print_perms(FILE *f
, struct ipc_stat
*is
)
469 fprintf(f
, "%-10d %-10o", is
->id
, is
->mode
& 0777);
471 if ((pw
= getpwuid(is
->cuid
)))
472 fprintf(f
, " %-10s", pw
->pw_name
);
474 fprintf(f
, " %-10u", is
->cuid
);
476 if ((gr
= getgrgid(is
->cgid
)))
477 fprintf(f
, " %-10s", gr
->gr_name
);
479 fprintf(f
, " %-10u", is
->cgid
);
481 if ((pw
= getpwuid(is
->uid
)))
482 fprintf(f
, " %-10s", pw
->pw_name
);
484 fprintf(f
, " %-10u", is
->uid
);
486 if ((gr
= getgrgid(is
->gid
)))
487 fprintf(f
, " %-10s\n", gr
->gr_name
);
489 fprintf(f
, " %-10u\n", is
->gid
);
492 void ipc_print_size(int unit
, char *msg
, uint64_t size
, const char *end
,
499 else if (msg
[strlen(msg
) - 1] == '=')
501 else if (unit
== IPC_UNIT_BYTES
)
502 printf(_("%s (bytes) = "), msg
);
503 else if (unit
== IPC_UNIT_KB
)
504 printf(_("%s (kbytes) = "), msg
);
506 printf("%s = ", msg
);
509 case IPC_UNIT_DEFAULT
:
511 sprintf(format
, "%%%dju", width
);
512 printf(format
, size
);
515 sprintf(format
, "%%%dju", width
);
516 printf(format
, size
/ 1024);
521 sprintf(format
, "%%%ds", width
);
522 printf(format
, (tmp
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
)));
527 /* impossible occurred */