1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
/*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2012 Sami Kerola <kerolasa@iki.fi>
* Copyright (C) 2012-2023 Karel Zak <kzak@redhat.com>
*/
#ifndef UTIL_LINUX_IPCUTILS_H
#define UTIL_LINUX_IPCUTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
#include <stdint.h>
#ifdef HAVE_MQUEUE_H
#include <mqueue.h>
#endif
#ifdef HAVE_SEMAPHORE_H
#include <semaphore.h>
#endif
/*
* SHM_DEST and SHM_LOCKED are defined in kernel headers, but inside
* #ifdef __KERNEL__ ... #endif
*/
#ifndef SHM_DEST
/* shm_mode upper byte flags */
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
# define SHM_LOCKED 02000 /* segment will not be swapped */
#endif
/* For older kernels the same holds for the defines below */
#ifndef MSG_STAT
# define MSG_STAT 11
# define MSG_INFO 12
#endif
#ifndef SHM_STAT
# define SHM_STAT 13
# define SHM_INFO 14
struct shm_info {
int used_ids;
unsigned long shm_tot; /* total allocated shm */
unsigned long shm_rss; /* total resident shm */
unsigned long shm_swp; /* total swapped shm */
unsigned long swap_attempts;
unsigned long swap_successes;
};
#endif
#ifndef SEM_STAT
# define SEM_STAT 18
# define SEM_INFO 19
#endif
/* Some versions of libc only define IPC_INFO when __USE_GNU is defined. */
#ifndef IPC_INFO
# define IPC_INFO 3
#endif
/*
* * The last arg of semctl is a union semun, but where is it defined? X/OPEN
* * tells us to define it ourselves, but until recently Linux include files
* * would also define it.
* */
#ifndef HAVE_UNION_SEMUN
/* according to X/OPEN we have to define it ourselves */
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif
/*
* X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm;
* glibc-1.09 has no support for sysv ipc.
* glibc 2 uses __key, __seq
*/
#if defined (__GLIBC__) && __GLIBC__ >= 2
# define KEY __key
#else
# define KEY key
#endif
/* Size printing in ipcs is using these. */
enum {
IPC_UNIT_DEFAULT,
IPC_UNIT_BYTES,
IPC_UNIT_KB,
IPC_UNIT_HUMAN
};
struct ipc_limits {
/* System V IPC */
uint64_t shmmni; /* max number of segments */
uint64_t shmmax; /* max segment size */
uint64_t shmall; /* max total shared memory */
uint64_t shmmin; /* min segment size */
int semmni; /* max number of arrays */
int semmsl; /* max semaphores per array */
int semmns; /* max semaphores system wide */
int semopm; /* max ops per semop call */
unsigned int semvmx; /* semaphore max value (constant) */
int msgmni; /* max queues system wide */
uint64_t msgmax; /* max size of message */
int msgmnb; /* default max size of queue */
/* POSIX IPC */
uint64_t msgmax_posix; /* max size of message */
uint64_t msgmni_posix; /* max queues system wide */
uint64_t msgmnb_posix; /* default max number of messages in a queue */
};
extern int ipc_msg_get_limits(struct ipc_limits *lim);
extern int ipc_sem_get_limits(struct ipc_limits *lim);
extern int ipc_shm_get_limits(struct ipc_limits *lim);
struct ipc_stat {
int id;
key_t key;
uid_t uid; /* current uid */
gid_t gid; /* current gid */
uid_t cuid; /* creator uid */
gid_t cgid; /* creator gid */
unsigned int mode;
};
extern void ipc_print_perms(FILE *f, struct ipc_stat *is);
extern void ipc_print_size(int unit, char *msg, uint64_t size, const char *end, int width);
/* See 'struct shmid_kernel' in kernel sources
*/
struct shm_data {
struct ipc_stat shm_perm;
uint64_t shm_nattch;
uint64_t shm_segsz;
int64_t shm_atim; /* __kernel_time_t is signed long */
int64_t shm_dtim;
int64_t shm_ctim;
pid_t shm_cprid;
pid_t shm_lprid;
uint64_t shm_rss;
uint64_t shm_swp;
struct shm_data *next;
};
extern int ipc_shm_get_info(int id, struct shm_data **shmds);
extern void ipc_shm_free_info(struct shm_data *shmds);
struct posix_shm_data {
char *name;
int64_t mtime; /* last change time */
uid_t cuid;
gid_t cgid;
off_t size;
unsigned int mode;
struct posix_shm_data *next;
};
extern int posix_ipc_shm_get_info(const char *name, struct posix_shm_data **shmds);
extern void posix_ipc_shm_free_info(struct posix_shm_data *shmds);
/* See 'struct sem_array' in kernel sources
*/
struct sem_elem {
int semval;
int ncount; /* processes waiting on increase semval */
int zcount; /* processes waiting on semval set to zero */
pid_t pid; /* process last executed semop(2) call */
};
struct sem_data {
struct ipc_stat sem_perm;
int64_t sem_ctime;
int64_t sem_otime;
uint64_t sem_nsems;
struct sem_elem *elements;
struct sem_data *next;
};
extern int ipc_sem_get_info(int id, struct sem_data **semds);
extern void ipc_sem_free_info(struct sem_data *semds);
struct posix_sem_data {
char *sname;
int64_t mtime; /* last change time */
uid_t cuid;
gid_t cgid;
unsigned int mode;
int sval; /* semaphore value */
struct posix_sem_data *next;
};
extern int posix_ipc_sem_get_info(const char *name, struct posix_sem_data **semds);
extern void posix_ipc_sem_free_info(struct posix_sem_data *semds);
/* See 'struct msg_queue' in kernel sources
*/
struct msg_data {
struct ipc_stat msg_perm;
int64_t q_stime;
int64_t q_rtime;
int64_t q_ctime;
uint64_t q_cbytes;
uint64_t q_qnum;
uint64_t q_qbytes;
pid_t q_lspid;
pid_t q_lrpid;
struct msg_data *next;
};
extern int ipc_msg_get_info(int id, struct msg_data **msgds);
extern void ipc_msg_free_info(struct msg_data *msgds);
struct posix_msg_data {
char *mname;
int64_t mtime;
uid_t cuid;
gid_t cgid;
unsigned int mode;
uint64_t q_cbytes; /* current number of bytes on the queue */
long q_qnum; /* number of messages on the queue */
struct posix_msg_data *next;
};
extern int posix_ipc_msg_get_info(const char *name, struct posix_msg_data **msgds);
extern void posix_ipc_msg_free_info(struct posix_msg_data *msgds);
#endif /* UTIL_LINUX_IPCUTILS_H */
|