1 #ifndef UTIL_LINUX_IPCUTILS_H
2 #define UTIL_LINUX_IPCUTILS_H
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #include <sys/sem.h>
9 #include <sys/shm.h>
10 #include <sys/types.h>
11 #include <time.h>
12 #include <unistd.h>
13 #include <grp.h>
14 #include <pwd.h>
15 #include <stdint.h>
16 
17 /*
18  * SHM_DEST and SHM_LOCKED are defined in kernel headers, but inside
19  * #ifdef __KERNEL__ ... #endif
20  */
21 #ifndef SHM_DEST
22   /* shm_mode upper byte flags */
23 # define SHM_DEST	01000	/* segment will be destroyed on last detach */
24 # define SHM_LOCKED	02000	/* segment will not be swapped */
25 #endif
26 
27 /* For older kernels the same holds for the defines below */
28 #ifndef MSG_STAT
29 # define MSG_STAT	11
30 # define MSG_INFO	12
31 #endif
32 
33 #ifndef SHM_STAT
34 # define SHM_STAT	13
35 # define SHM_INFO	14
36 struct shm_info {
37 	int used_ids;
38 	unsigned long shm_tot;		/* total allocated shm */
39 	unsigned long shm_rss;		/* total resident shm */
40 	unsigned long shm_swp;		/* total swapped shm */
41 	unsigned long swap_attempts;
42 	unsigned long swap_successes;
43 };
44 #endif
45 
46 #ifndef SEM_STAT
47 # define SEM_STAT	18
48 # define SEM_INFO	19
49 #endif
50 
51 /* Some versions of libc only define IPC_INFO when __USE_GNU is defined. */
52 #ifndef IPC_INFO
53 # define IPC_INFO	3
54 #endif
55 
56 /*
57  *  * The last arg of semctl is a union semun, but where is it defined? X/OPEN
58  *   * tells us to define it ourselves, but until recently Linux include files
59  *    * would also define it.
60  *     */
61 #ifndef HAVE_UNION_SEMUN
62 /* according to X/OPEN we have to define it ourselves */
63 union semun {
64 	int val;
65 	struct semid_ds *buf;
66 	unsigned short int *array;
67 	struct seminfo *__buf;
68 };
69 #endif
70 
71 /*
72  * X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm;
73  *	glibc-1.09 has no support for sysv ipc.
74  *	glibc 2 uses __key, __seq
75  */
76 #if defined (__GLIBC__) && __GLIBC__ >= 2
77 # define KEY __key
78 #else
79 # define KEY key
80 #endif
81 
82 /* Size printing in ipcs is using these. */
83 enum {
84 	IPC_UNIT_DEFAULT,
85 	IPC_UNIT_BYTES,
86 	IPC_UNIT_KB,
87 	IPC_UNIT_HUMAN
88 };
89 
90 struct ipc_limits {
91 	uint64_t	shmmni;		/* max number of segments */
92 	uint64_t	shmmax;		/* max segment size */
93 	uint64_t	shmall;		/* max total shared memory */
94 	uint64_t	shmmin;		/* min segment size */
95 
96 	int		semmni;		/* max number of arrays */
97 	int		semmsl;		/* max semaphores per array */
98 	int		semmns;		/* max semaphores system wide */
99 	int		semopm;		/* max ops per semop call */
100 	unsigned int	semvmx;		/* semaphore max value (constant) */
101 
102 	int		msgmni;		/* max queues system wide */
103 	uint64_t	msgmax;		/* max size of message */
104 	int		msgmnb;		/* default max size of queue */
105 };
106 
107 extern int ipc_msg_get_limits(struct ipc_limits *lim);
108 extern int ipc_sem_get_limits(struct ipc_limits *lim);
109 extern int ipc_shm_get_limits(struct ipc_limits *lim);
110 
111 struct ipc_stat {
112 	int		id;
113 	key_t		key;
114 	uid_t		uid;    /* current uid */
115 	gid_t		gid;    /* current gid */
116 	uid_t		cuid;    /* creator uid */
117 	gid_t		cgid;    /* creator gid */
118 	unsigned int	mode;
119 };
120 
121 extern void ipc_print_perms(FILE *f, struct ipc_stat *is);
122 extern void ipc_print_size(int unit, char *msg, uint64_t size, const char *end, int width);
123 
124 /* See 'struct shmid_kernel' in kernel sources
125  */
126 struct shm_data {
127 	struct ipc_stat	shm_perm;
128 
129 	uint64_t	shm_nattch;
130 	uint64_t	shm_segsz;
131 	int64_t		shm_atim;	/* __kernel_time_t is signed long */
132 	int64_t		shm_dtim;
133 	int64_t		shm_ctim;
134 	pid_t		shm_cprid;
135 	pid_t		shm_lprid;
136 	uint64_t	shm_rss;
137 	uint64_t	shm_swp;
138 
139 	struct shm_data  *next;
140 };
141 
142 extern int ipc_shm_get_info(int id, struct shm_data **shmds);
143 extern void ipc_shm_free_info(struct shm_data *shmds);
144 
145 /* See 'struct sem_array' in kernel sources
146  */
147 struct sem_elem {
148 	int	semval;
149 	int	ncount;		/* processes waiting on increase semval */
150 	int	zcount;		/* processes waiting on semval set to zero */
151 	pid_t	pid;		/* process last executed semop(2) call */
152 };
153 struct sem_data {
154 	struct ipc_stat sem_perm;
155 
156 	int64_t		sem_ctime;
157 	int64_t		sem_otime;
158 	uint64_t	sem_nsems;
159 
160 	struct sem_elem	*elements;
161 	struct sem_data *next;
162 };
163 
164 extern int ipc_sem_get_info(int id, struct sem_data **semds);
165 extern void ipc_sem_free_info(struct sem_data *semds);
166 
167 /* See 'struct msg_queue' in kernel sources
168  */
169 struct msg_data {
170 	struct ipc_stat msg_perm;
171 
172 	int64_t		q_stime;
173 	int64_t		q_rtime;
174 	int64_t		q_ctime;
175 	uint64_t	q_cbytes;
176 	uint64_t	q_qnum;
177 	uint64_t	q_qbytes;
178 	pid_t		q_lspid;
179 	pid_t		q_lrpid;
180 
181 	struct msg_data *next;
182 };
183 
184 extern int ipc_msg_get_info(int id, struct msg_data **msgds);
185 extern void ipc_msg_free_info(struct msg_data *msgds);
186 
187 #endif /* UTIL_LINUX_IPCUTILS_H */
188