xref: /minix3/minix/usr.bin/trace/service/ipc.c (revision 4d272e5a970c4e7d6700cabd52e337e37404b70e)
1521fa314SDavid van Moolenbroek /* This file is concerned with the IPC server, not with kernel-level IPC. */
2521fa314SDavid van Moolenbroek 
3521fa314SDavid van Moolenbroek #include "inc.h"
4521fa314SDavid van Moolenbroek 
5521fa314SDavid van Moolenbroek #include <sys/ipc.h>
6521fa314SDavid van Moolenbroek #include <sys/shm.h>
7521fa314SDavid van Moolenbroek #include <sys/sem.h>
8521fa314SDavid van Moolenbroek 
9521fa314SDavid van Moolenbroek static void
put_key(struct trace_proc * proc,const char * name,key_t key)10521fa314SDavid van Moolenbroek put_key(struct trace_proc * proc, const char * name, key_t key)
11521fa314SDavid van Moolenbroek {
12521fa314SDavid van Moolenbroek 
13521fa314SDavid van Moolenbroek 	if (!valuesonly && key == IPC_PRIVATE)
14521fa314SDavid van Moolenbroek 		put_field(proc, name, "IPC_PRIVATE");
15521fa314SDavid van Moolenbroek 	else
16521fa314SDavid van Moolenbroek 		put_value(proc, name, "%ld", key);
17521fa314SDavid van Moolenbroek }
18521fa314SDavid van Moolenbroek 
19521fa314SDavid van Moolenbroek static const struct flags ipcget_flags[] = {
20521fa314SDavid van Moolenbroek 	FLAG(IPC_CREAT),
21521fa314SDavid van Moolenbroek 	FLAG(IPC_EXCL),
22521fa314SDavid van Moolenbroek };
23521fa314SDavid van Moolenbroek 
24521fa314SDavid van Moolenbroek static int
ipc_shmget_out(struct trace_proc * proc,const message * m_out)25521fa314SDavid van Moolenbroek ipc_shmget_out(struct trace_proc * proc, const message * m_out)
26521fa314SDavid van Moolenbroek {
27521fa314SDavid van Moolenbroek 
28521fa314SDavid van Moolenbroek 	put_key(proc, "key", m_out->m_lc_ipc_shmget.key);
29521fa314SDavid van Moolenbroek 	put_value(proc, "size", "%zu", m_out->m_lc_ipc_shmget.size);
30521fa314SDavid van Moolenbroek 	put_flags(proc, "shmflg", ipcget_flags, COUNT(ipcget_flags), "0%o",
31521fa314SDavid van Moolenbroek 	    m_out->m_lc_ipc_shmget.flag);
32521fa314SDavid van Moolenbroek 
33521fa314SDavid van Moolenbroek 	return CT_DONE;
34521fa314SDavid van Moolenbroek }
35521fa314SDavid van Moolenbroek 
36521fa314SDavid van Moolenbroek static void
ipc_shmget_in(struct trace_proc * proc,const message * __unused m_out,const message * m_in,int failed)37521fa314SDavid van Moolenbroek ipc_shmget_in(struct trace_proc * proc, const message * __unused m_out,
38521fa314SDavid van Moolenbroek 	const message * m_in, int failed)
39521fa314SDavid van Moolenbroek {
40521fa314SDavid van Moolenbroek 
41521fa314SDavid van Moolenbroek 	if (!failed)
42521fa314SDavid van Moolenbroek 		put_value(proc, NULL, "%d", m_in->m_lc_ipc_shmget.retid);
43521fa314SDavid van Moolenbroek 	else
44521fa314SDavid van Moolenbroek 		put_result(proc);
45521fa314SDavid van Moolenbroek }
46521fa314SDavid van Moolenbroek 
47521fa314SDavid van Moolenbroek static const struct flags shmat_flags[] = {
48521fa314SDavid van Moolenbroek 	FLAG(SHM_RDONLY),
49521fa314SDavid van Moolenbroek 	FLAG(SHM_RND),
50521fa314SDavid van Moolenbroek };
51521fa314SDavid van Moolenbroek 
52521fa314SDavid van Moolenbroek static int
ipc_shmat_out(struct trace_proc * proc,const message * m_out)53521fa314SDavid van Moolenbroek ipc_shmat_out(struct trace_proc * proc, const message * m_out)
54521fa314SDavid van Moolenbroek {
55521fa314SDavid van Moolenbroek 
56521fa314SDavid van Moolenbroek 	put_value(proc, "shmid", "%d", m_out->m_lc_ipc_shmat.id);
57521fa314SDavid van Moolenbroek 	put_ptr(proc, "shmaddr", (vir_bytes)m_out->m_lc_ipc_shmat.addr);
58521fa314SDavid van Moolenbroek 	put_flags(proc, "shmflg", shmat_flags, COUNT(shmat_flags), "0x%x",
59521fa314SDavid van Moolenbroek 	    m_out->m_lc_ipc_shmat.flag);
60521fa314SDavid van Moolenbroek 
61521fa314SDavid van Moolenbroek 	return CT_DONE;
62521fa314SDavid van Moolenbroek }
63521fa314SDavid van Moolenbroek 
64521fa314SDavid van Moolenbroek static void
ipc_shmat_in(struct trace_proc * proc,const message * __unused m_out,const message * m_in,int failed)65521fa314SDavid van Moolenbroek ipc_shmat_in(struct trace_proc * proc, const message * __unused m_out,
66521fa314SDavid van Moolenbroek 	const message * m_in, int failed)
67521fa314SDavid van Moolenbroek {
68521fa314SDavid van Moolenbroek 
69521fa314SDavid van Moolenbroek 	if (!failed)
70521fa314SDavid van Moolenbroek 		put_ptr(proc, NULL, (vir_bytes)m_in->m_lc_ipc_shmat.retaddr);
71521fa314SDavid van Moolenbroek 	else
72521fa314SDavid van Moolenbroek 		put_result(proc);
73521fa314SDavid van Moolenbroek }
74521fa314SDavid van Moolenbroek 
75521fa314SDavid van Moolenbroek static int
ipc_shmdt_out(struct trace_proc * proc,const message * m_out)76521fa314SDavid van Moolenbroek ipc_shmdt_out(struct trace_proc * proc, const message * m_out)
77521fa314SDavid van Moolenbroek {
78521fa314SDavid van Moolenbroek 
79521fa314SDavid van Moolenbroek 	put_ptr(proc, "shmaddr", (vir_bytes)m_out->m_lc_ipc_shmdt.addr);
80521fa314SDavid van Moolenbroek 
81521fa314SDavid van Moolenbroek 	return CT_DONE;
82521fa314SDavid van Moolenbroek }
83521fa314SDavid van Moolenbroek 
84521fa314SDavid van Moolenbroek static void
put_shmctl_cmd(struct trace_proc * proc,const char * name,int cmd)85521fa314SDavid van Moolenbroek put_shmctl_cmd(struct trace_proc * proc, const char * name, int cmd)
86521fa314SDavid van Moolenbroek {
87521fa314SDavid van Moolenbroek 	const char *text = NULL;
88521fa314SDavid van Moolenbroek 
89521fa314SDavid van Moolenbroek 	if (!valuesonly) {
90521fa314SDavid van Moolenbroek 		switch (cmd) {
91521fa314SDavid van Moolenbroek 		TEXT(IPC_RMID);
92521fa314SDavid van Moolenbroek 		TEXT(IPC_SET);
93521fa314SDavid van Moolenbroek 		TEXT(IPC_STAT);
94521fa314SDavid van Moolenbroek 		TEXT(SHM_STAT);
95521fa314SDavid van Moolenbroek 		TEXT(SHM_INFO);
96521fa314SDavid van Moolenbroek 		TEXT(IPC_INFO);
97521fa314SDavid van Moolenbroek 		}
98521fa314SDavid van Moolenbroek 	}
99521fa314SDavid van Moolenbroek 
100521fa314SDavid van Moolenbroek 	if (text != NULL)
101521fa314SDavid van Moolenbroek 		put_field(proc, name, text);
102521fa314SDavid van Moolenbroek 	else
103521fa314SDavid van Moolenbroek 		put_value(proc, name, "%d", cmd);
104521fa314SDavid van Moolenbroek }
105521fa314SDavid van Moolenbroek 
106521fa314SDavid van Moolenbroek static const struct flags shm_mode_flags[] = {
107521fa314SDavid van Moolenbroek 	FLAG(SHM_DEST),
108521fa314SDavid van Moolenbroek 	FLAG(SHM_LOCKED),
109521fa314SDavid van Moolenbroek };
110521fa314SDavid van Moolenbroek 
111521fa314SDavid van Moolenbroek static void
put_struct_shmid_ds(struct trace_proc * proc,const char * name,int flags,vir_bytes addr)112521fa314SDavid van Moolenbroek put_struct_shmid_ds(struct trace_proc * proc, const char * name, int flags,
113521fa314SDavid van Moolenbroek 	vir_bytes addr)
114521fa314SDavid van Moolenbroek {
115521fa314SDavid van Moolenbroek 	struct shmid_ds buf;
116521fa314SDavid van Moolenbroek 	int set;
117521fa314SDavid van Moolenbroek 
118521fa314SDavid van Moolenbroek 	if (!put_open_struct(proc, name, flags, addr, &buf, sizeof(buf)))
119521fa314SDavid van Moolenbroek 		return;
120521fa314SDavid van Moolenbroek 
121521fa314SDavid van Moolenbroek 	/* Is this an IPC_SET call?  Then print a small subset of fields.. */
122521fa314SDavid van Moolenbroek 	set = (flags & PF_ALT);
123521fa314SDavid van Moolenbroek 
124521fa314SDavid van Moolenbroek 	put_open(proc, "shm_perm", 0, "{", ", ");
125521fa314SDavid van Moolenbroek 
126521fa314SDavid van Moolenbroek 	put_value(proc, "uid", "%u", buf.shm_perm.uid);
127521fa314SDavid van Moolenbroek 	put_value(proc, "gid", "%u", buf.shm_perm.gid);
128521fa314SDavid van Moolenbroek 	if (!set && verbose > 0) {
129521fa314SDavid van Moolenbroek 		put_value(proc, "cuid", "%u", buf.shm_perm.cuid);
130521fa314SDavid van Moolenbroek 		put_value(proc, "cgid", "%u", buf.shm_perm.cgid);
131521fa314SDavid van Moolenbroek 	}
132521fa314SDavid van Moolenbroek 	put_flags(proc, "mode", shm_mode_flags, COUNT(shm_mode_flags),
133521fa314SDavid van Moolenbroek 	    "0%03o", buf.shm_perm.mode);
134521fa314SDavid van Moolenbroek 
135521fa314SDavid van Moolenbroek 	put_close(proc, "}");
136521fa314SDavid van Moolenbroek 
137521fa314SDavid van Moolenbroek 	if (!set) {
138521fa314SDavid van Moolenbroek 		put_value(proc, "shm_segsz", "%zu", buf.shm_segsz);
139521fa314SDavid van Moolenbroek 		if (verbose > 0) {
140521fa314SDavid van Moolenbroek 			put_value(proc, "shm_lpid", "%d", buf.shm_lpid);
141521fa314SDavid van Moolenbroek 			put_value(proc, "shm_cpid", "%d", buf.shm_cpid);
142521fa314SDavid van Moolenbroek 			put_time(proc, "shm_atime", buf.shm_atime);
143521fa314SDavid van Moolenbroek 			put_time(proc, "shm_dtime", buf.shm_dtime);
144521fa314SDavid van Moolenbroek 			put_time(proc, "shm_ctime", buf.shm_ctime);
145521fa314SDavid van Moolenbroek 		}
146521fa314SDavid van Moolenbroek 		put_value(proc, "shm_nattch", "%u", buf.shm_nattch);
147521fa314SDavid van Moolenbroek 	}
148521fa314SDavid van Moolenbroek 
149521fa314SDavid van Moolenbroek 	put_close_struct(proc, set || verbose > 0);
150521fa314SDavid van Moolenbroek }
151521fa314SDavid van Moolenbroek 
152521fa314SDavid van Moolenbroek static int
ipc_shmctl_out(struct trace_proc * proc,const message * m_out)153521fa314SDavid van Moolenbroek ipc_shmctl_out(struct trace_proc * proc, const message * m_out)
154521fa314SDavid van Moolenbroek {
155521fa314SDavid van Moolenbroek 
156521fa314SDavid van Moolenbroek 	put_value(proc, "shmid", "%d", m_out->m_lc_ipc_shmctl.id);
157521fa314SDavid van Moolenbroek 	put_shmctl_cmd(proc, "cmd", m_out->m_lc_ipc_shmctl.cmd);
158521fa314SDavid van Moolenbroek 
159521fa314SDavid van Moolenbroek 	/* TODO: add support for the IPC_INFO and SHM_INFO structures.. */
160521fa314SDavid van Moolenbroek 	switch (m_out->m_lc_ipc_shmctl.cmd) {
161521fa314SDavid van Moolenbroek 	case IPC_STAT:
162521fa314SDavid van Moolenbroek 	case SHM_STAT:
163521fa314SDavid van Moolenbroek 		return CT_NOTDONE;
164521fa314SDavid van Moolenbroek 
165521fa314SDavid van Moolenbroek 	case IPC_SET:
166521fa314SDavid van Moolenbroek 		put_struct_shmid_ds(proc, "buf", PF_ALT,
167521fa314SDavid van Moolenbroek 		    (vir_bytes)m_out->m_lc_ipc_shmctl.buf);
168521fa314SDavid van Moolenbroek 
169521fa314SDavid van Moolenbroek 		return CT_DONE;
170521fa314SDavid van Moolenbroek 
171521fa314SDavid van Moolenbroek 	default:
172521fa314SDavid van Moolenbroek 		put_ptr(proc, "buf", (vir_bytes)m_out->m_lc_ipc_shmctl.buf);
173521fa314SDavid van Moolenbroek 
174521fa314SDavid van Moolenbroek 		return CT_DONE;
175521fa314SDavid van Moolenbroek 	}
176521fa314SDavid van Moolenbroek }
177521fa314SDavid van Moolenbroek 
178521fa314SDavid van Moolenbroek static void
ipc_shmctl_in(struct trace_proc * proc,const message * m_out,const message * m_in,int failed)179521fa314SDavid van Moolenbroek ipc_shmctl_in(struct trace_proc * proc, const message * m_out,
180521fa314SDavid van Moolenbroek 	const message * m_in, int failed)
181521fa314SDavid van Moolenbroek {
182521fa314SDavid van Moolenbroek 
183521fa314SDavid van Moolenbroek 	switch (m_out->m_lc_ipc_shmctl.cmd) {
184521fa314SDavid van Moolenbroek 	case IPC_STAT:
185521fa314SDavid van Moolenbroek 	case SHM_STAT:
186521fa314SDavid van Moolenbroek 		put_struct_shmid_ds(proc, "buf", failed,
187521fa314SDavid van Moolenbroek 		    (vir_bytes)m_out->m_lc_ipc_shmctl.buf);
188521fa314SDavid van Moolenbroek 		put_equals(proc);
189521fa314SDavid van Moolenbroek 
190521fa314SDavid van Moolenbroek 		break;
191521fa314SDavid van Moolenbroek 	}
192521fa314SDavid van Moolenbroek 
193521fa314SDavid van Moolenbroek 	if (!failed) {
194521fa314SDavid van Moolenbroek 		switch (m_out->m_lc_ipc_shmctl.cmd) {
195521fa314SDavid van Moolenbroek 		case SHM_INFO:
196521fa314SDavid van Moolenbroek 		case SHM_STAT:
197521fa314SDavid van Moolenbroek 		case IPC_INFO:
198521fa314SDavid van Moolenbroek 			put_value(proc, NULL, "%d", m_in->m_lc_ipc_shmctl.ret);
199521fa314SDavid van Moolenbroek 
200521fa314SDavid van Moolenbroek 			return;
201521fa314SDavid van Moolenbroek 		}
202521fa314SDavid van Moolenbroek 	}
203521fa314SDavid van Moolenbroek 
204521fa314SDavid van Moolenbroek 	put_result(proc);
205521fa314SDavid van Moolenbroek }
206521fa314SDavid van Moolenbroek 
207521fa314SDavid van Moolenbroek static int
ipc_semget_out(struct trace_proc * proc,const message * m_out)208521fa314SDavid van Moolenbroek ipc_semget_out(struct trace_proc * proc, const message * m_out)
209521fa314SDavid van Moolenbroek {
210521fa314SDavid van Moolenbroek 
211521fa314SDavid van Moolenbroek 	put_key(proc, "key", m_out->m_lc_ipc_semget.key);
212521fa314SDavid van Moolenbroek 	put_value(proc, "nsems", "%d", m_out->m_lc_ipc_semget.nr);
213521fa314SDavid van Moolenbroek 	put_flags(proc, "semflg", ipcget_flags, COUNT(ipcget_flags), "0%o",
214521fa314SDavid van Moolenbroek 	    m_out->m_lc_ipc_semget.flag);
215521fa314SDavid van Moolenbroek 
216521fa314SDavid van Moolenbroek 	return CT_DONE;
217521fa314SDavid van Moolenbroek }
218521fa314SDavid van Moolenbroek 
219521fa314SDavid van Moolenbroek static void
ipc_semget_in(struct trace_proc * proc,const message * __unused m_out,const message * m_in,int failed)220521fa314SDavid van Moolenbroek ipc_semget_in(struct trace_proc * proc, const message * __unused m_out,
221521fa314SDavid van Moolenbroek 	const message * m_in, int failed)
222521fa314SDavid van Moolenbroek {
223521fa314SDavid van Moolenbroek 
224521fa314SDavid van Moolenbroek 	if (!failed)
225521fa314SDavid van Moolenbroek 		put_value(proc, NULL, "%d", m_in->m_lc_ipc_semget.retid);
226521fa314SDavid van Moolenbroek 	else
227521fa314SDavid van Moolenbroek 		put_result(proc);
228521fa314SDavid van Moolenbroek }
229521fa314SDavid van Moolenbroek 
230521fa314SDavid van Moolenbroek static void
put_semctl_cmd(struct trace_proc * proc,const char * name,int cmd)231521fa314SDavid van Moolenbroek put_semctl_cmd(struct trace_proc * proc, const char * name, int cmd)
232521fa314SDavid van Moolenbroek {
233521fa314SDavid van Moolenbroek 	const char *text = NULL;
234521fa314SDavid van Moolenbroek 
235521fa314SDavid van Moolenbroek 	if (!valuesonly) {
236521fa314SDavid van Moolenbroek 		switch (cmd) {
237521fa314SDavid van Moolenbroek 		TEXT(IPC_RMID);
238521fa314SDavid van Moolenbroek 		TEXT(IPC_SET);
239521fa314SDavid van Moolenbroek 		TEXT(IPC_STAT);
240521fa314SDavid van Moolenbroek 		TEXT(GETNCNT);
241521fa314SDavid van Moolenbroek 		TEXT(GETPID);
242521fa314SDavid van Moolenbroek 		TEXT(GETVAL);
243521fa314SDavid van Moolenbroek 		TEXT(GETALL);
244521fa314SDavid van Moolenbroek 		TEXT(GETZCNT);
245521fa314SDavid van Moolenbroek 		TEXT(SETVAL);
246521fa314SDavid van Moolenbroek 		TEXT(SETALL);
247521fa314SDavid van Moolenbroek 		TEXT(SEM_STAT);
248521fa314SDavid van Moolenbroek 		TEXT(SEM_INFO);
249521fa314SDavid van Moolenbroek 		TEXT(IPC_INFO);
250521fa314SDavid van Moolenbroek 		}
251521fa314SDavid van Moolenbroek 	}
252521fa314SDavid van Moolenbroek 
253521fa314SDavid van Moolenbroek 	if (text != NULL)
254521fa314SDavid van Moolenbroek 		put_field(proc, name, text);
255521fa314SDavid van Moolenbroek 	else
256521fa314SDavid van Moolenbroek 		put_value(proc, name, "%d", cmd);
257521fa314SDavid van Moolenbroek }
258521fa314SDavid van Moolenbroek 
259521fa314SDavid van Moolenbroek static void
put_struct_semid_ds(struct trace_proc * proc,const char * name,int flags,vir_bytes addr)260521fa314SDavid van Moolenbroek put_struct_semid_ds(struct trace_proc * proc, const char * name, int flags,
261521fa314SDavid van Moolenbroek 	vir_bytes addr)
262521fa314SDavid van Moolenbroek {
263521fa314SDavid van Moolenbroek 	struct semid_ds buf;
264521fa314SDavid van Moolenbroek 	int set;
265521fa314SDavid van Moolenbroek 
266521fa314SDavid van Moolenbroek 	if (!put_open_struct(proc, name, flags, addr, &buf, sizeof(buf)))
267521fa314SDavid van Moolenbroek 		return;
268521fa314SDavid van Moolenbroek 
269521fa314SDavid van Moolenbroek 	/* Is this an IPC_SET call?  Then print a small subset of fields.. */
270521fa314SDavid van Moolenbroek 	set = (flags & PF_ALT);
271521fa314SDavid van Moolenbroek 
272521fa314SDavid van Moolenbroek 	put_open(proc, "sem_perm", 0, "{", ", ");
273521fa314SDavid van Moolenbroek 
274521fa314SDavid van Moolenbroek 	put_value(proc, "uid", "%u", buf.sem_perm.uid);
275521fa314SDavid van Moolenbroek 	put_value(proc, "gid", "%u", buf.sem_perm.gid);
276521fa314SDavid van Moolenbroek 	if (!set && verbose > 0) {
277521fa314SDavid van Moolenbroek 		put_value(proc, "cuid", "%u", buf.sem_perm.cuid);
278521fa314SDavid van Moolenbroek 		put_value(proc, "cgid", "%u", buf.sem_perm.cgid);
279521fa314SDavid van Moolenbroek 	}
280521fa314SDavid van Moolenbroek 	put_value(proc, "mode", "0%03o", buf.sem_perm.mode);
281521fa314SDavid van Moolenbroek 
282521fa314SDavid van Moolenbroek 	put_close(proc, "}");
283521fa314SDavid van Moolenbroek 
284521fa314SDavid van Moolenbroek 	if (!set) {
285521fa314SDavid van Moolenbroek 		if (verbose > 0) {
286521fa314SDavid van Moolenbroek 			put_time(proc, "sem_otime", buf.sem_otime);
287521fa314SDavid van Moolenbroek 			put_time(proc, "sem_ctime", buf.sem_ctime);
288521fa314SDavid van Moolenbroek 		}
289521fa314SDavid van Moolenbroek 		put_value(proc, "sem_nsems", "%u", buf.sem_nsems);
290521fa314SDavid van Moolenbroek 	}
291521fa314SDavid van Moolenbroek 
292521fa314SDavid van Moolenbroek 	put_close_struct(proc, set || verbose > 0);
293521fa314SDavid van Moolenbroek }
294521fa314SDavid van Moolenbroek 
295521fa314SDavid van Moolenbroek 
296521fa314SDavid van Moolenbroek static int
ipc_semctl_out(struct trace_proc * proc,const message * m_out)297521fa314SDavid van Moolenbroek ipc_semctl_out(struct trace_proc * proc, const message * m_out)
298521fa314SDavid van Moolenbroek {
299521fa314SDavid van Moolenbroek 
300521fa314SDavid van Moolenbroek 	put_value(proc, "semid", "%d", m_out->m_lc_ipc_semctl.id);
301521fa314SDavid van Moolenbroek 	put_value(proc, "semnum", "%d", m_out->m_lc_ipc_semctl.num);
302521fa314SDavid van Moolenbroek 	put_semctl_cmd(proc, "cmd", m_out->m_lc_ipc_semctl.cmd);
303521fa314SDavid van Moolenbroek 
304521fa314SDavid van Moolenbroek 	/* TODO: add support for the IPC_INFO and SEM_INFO structures.. */
305521fa314SDavid van Moolenbroek 	switch (m_out->m_lc_ipc_semctl.cmd) {
306521fa314SDavid van Moolenbroek 	case IPC_STAT:
307521fa314SDavid van Moolenbroek 	case SEM_STAT:
308521fa314SDavid van Moolenbroek 		return CT_NOTDONE;
309521fa314SDavid van Moolenbroek 
310521fa314SDavid van Moolenbroek 	case IPC_SET:
311521fa314SDavid van Moolenbroek 		put_struct_semid_ds(proc, "buf", PF_ALT,
312521fa314SDavid van Moolenbroek 		    (vir_bytes)m_out->m_lc_ipc_semctl.opt);
313521fa314SDavid van Moolenbroek 
314521fa314SDavid van Moolenbroek 		return CT_DONE;
315521fa314SDavid van Moolenbroek 
316521fa314SDavid van Moolenbroek 	case IPC_INFO:
317521fa314SDavid van Moolenbroek 	case SEM_INFO:
318521fa314SDavid van Moolenbroek 		put_ptr(proc, "buf", (vir_bytes)m_out->m_lc_ipc_semctl.opt);
319521fa314SDavid van Moolenbroek 
320521fa314SDavid van Moolenbroek 		return CT_DONE;
321521fa314SDavid van Moolenbroek 
322521fa314SDavid van Moolenbroek 	case GETALL:
323521fa314SDavid van Moolenbroek 	case SETALL:
324521fa314SDavid van Moolenbroek 		put_ptr(proc, "array", (vir_bytes)m_out->m_lc_ipc_semctl.opt);
325521fa314SDavid van Moolenbroek 
326521fa314SDavid van Moolenbroek 		return CT_DONE;
327521fa314SDavid van Moolenbroek 
328521fa314SDavid van Moolenbroek 	case SETVAL:
329*4d272e5aSDavid van Moolenbroek 		put_value(proc, "val", "%lu", m_out->m_lc_ipc_semctl.opt);
330521fa314SDavid van Moolenbroek 
331521fa314SDavid van Moolenbroek 		return CT_DONE;
332521fa314SDavid van Moolenbroek 
333521fa314SDavid van Moolenbroek 	default:
334521fa314SDavid van Moolenbroek 		return CT_DONE;
335521fa314SDavid van Moolenbroek 	}
336521fa314SDavid van Moolenbroek }
337521fa314SDavid van Moolenbroek 
338521fa314SDavid van Moolenbroek static void
ipc_semctl_in(struct trace_proc * proc,const message * m_out,const message * m_in,int failed)339521fa314SDavid van Moolenbroek ipc_semctl_in(struct trace_proc * proc, const message * m_out,
340521fa314SDavid van Moolenbroek 	const message * m_in, int failed)
341521fa314SDavid van Moolenbroek {
342521fa314SDavid van Moolenbroek 
343521fa314SDavid van Moolenbroek 	switch (m_out->m_lc_ipc_semctl.cmd) {
344521fa314SDavid van Moolenbroek 	case IPC_STAT:
345521fa314SDavid van Moolenbroek 	case SEM_STAT:
346521fa314SDavid van Moolenbroek 		put_struct_semid_ds(proc, "buf", failed,
347521fa314SDavid van Moolenbroek 		    (vir_bytes)m_out->m_lc_ipc_semctl.opt);
348521fa314SDavid van Moolenbroek 		put_equals(proc);
349521fa314SDavid van Moolenbroek 
350521fa314SDavid van Moolenbroek 		break;
351521fa314SDavid van Moolenbroek 	}
352521fa314SDavid van Moolenbroek 
353521fa314SDavid van Moolenbroek 	if (!failed) {
354521fa314SDavid van Moolenbroek 		switch (m_out->m_lc_ipc_semctl.cmd) {
355521fa314SDavid van Moolenbroek 		case GETNCNT:
356521fa314SDavid van Moolenbroek 		case GETPID:
357521fa314SDavid van Moolenbroek 		case GETVAL:
358521fa314SDavid van Moolenbroek 		case GETZCNT:
359521fa314SDavid van Moolenbroek 		case SEM_INFO:
360521fa314SDavid van Moolenbroek 		case SEM_STAT:
361521fa314SDavid van Moolenbroek 		case IPC_INFO:
362521fa314SDavid van Moolenbroek 			put_value(proc, NULL, "%d", m_in->m_lc_ipc_semctl.ret);
363521fa314SDavid van Moolenbroek 			return;
364521fa314SDavid van Moolenbroek 		}
365521fa314SDavid van Moolenbroek 	}
366521fa314SDavid van Moolenbroek 	put_result(proc);
367521fa314SDavid van Moolenbroek }
368521fa314SDavid van Moolenbroek 
369521fa314SDavid van Moolenbroek static const struct flags sem_flags[] = {
370521fa314SDavid van Moolenbroek 	FLAG(IPC_NOWAIT),
371521fa314SDavid van Moolenbroek 	FLAG(SEM_UNDO),
372521fa314SDavid van Moolenbroek };
373521fa314SDavid van Moolenbroek 
374521fa314SDavid van Moolenbroek static void
put_struct_sembuf(struct trace_proc * proc,const char * name,int flags,vir_bytes addr)375521fa314SDavid van Moolenbroek put_struct_sembuf(struct trace_proc * proc, const char * name, int flags,
376521fa314SDavid van Moolenbroek 	vir_bytes addr)
377521fa314SDavid van Moolenbroek {
378521fa314SDavid van Moolenbroek 	struct sembuf buf;
379521fa314SDavid van Moolenbroek 	int all;
380521fa314SDavid van Moolenbroek 
381521fa314SDavid van Moolenbroek 	if (!put_open_struct(proc, name, flags, addr, &buf, sizeof(buf)))
382521fa314SDavid van Moolenbroek 		return;
383521fa314SDavid van Moolenbroek 
384521fa314SDavid van Moolenbroek 	all = FALSE;
385521fa314SDavid van Moolenbroek 	put_value(proc, "sem_num", "%u", buf.sem_num);
386521fa314SDavid van Moolenbroek 	put_value(proc, "sem_op", "%d", buf.sem_op);
387521fa314SDavid van Moolenbroek 	if (verbose > 0 || (buf.sem_flg & ~SEM_UNDO) != 0) {
388521fa314SDavid van Moolenbroek 		put_flags(proc, "sem_flg", sem_flags, COUNT(sem_flags), "0x%x",
389521fa314SDavid van Moolenbroek 		   buf.sem_flg);
390521fa314SDavid van Moolenbroek 		all = TRUE;
391521fa314SDavid van Moolenbroek 	}
392521fa314SDavid van Moolenbroek 
393521fa314SDavid van Moolenbroek 	put_close_struct(proc, all);
394521fa314SDavid van Moolenbroek }
395521fa314SDavid van Moolenbroek 
396521fa314SDavid van Moolenbroek static void
put_sembuf_array(struct trace_proc * proc,const char * name,vir_bytes addr,size_t count)397521fa314SDavid van Moolenbroek put_sembuf_array(struct trace_proc * proc, const char * name, vir_bytes addr,
398521fa314SDavid van Moolenbroek 	size_t count)
399521fa314SDavid van Moolenbroek {
400521fa314SDavid van Moolenbroek 	struct sembuf buf[SEMOPM]; /* about 600 bytes, so OK for the stack */
401521fa314SDavid van Moolenbroek 	size_t i;
402521fa314SDavid van Moolenbroek 
403521fa314SDavid van Moolenbroek 	if (valuesonly > 1 || count > SEMOPM ||
404521fa314SDavid van Moolenbroek 	    mem_get_data(proc->pid, addr, &buf, count * sizeof(buf[0])) != 0) {
405521fa314SDavid van Moolenbroek 		put_ptr(proc, name, addr);
406521fa314SDavid van Moolenbroek 
407521fa314SDavid van Moolenbroek 		return;
408521fa314SDavid van Moolenbroek 	}
409521fa314SDavid van Moolenbroek 
410521fa314SDavid van Moolenbroek 	put_open(proc, name, PF_NONAME, "[", ", ");
411521fa314SDavid van Moolenbroek 	for (i = 0; i < count; i++)
412521fa314SDavid van Moolenbroek 		put_struct_sembuf(proc, NULL, PF_LOCADDR, (vir_bytes)&buf[i]);
413521fa314SDavid van Moolenbroek 	put_close(proc, "]");
414521fa314SDavid van Moolenbroek }
415521fa314SDavid van Moolenbroek 
416521fa314SDavid van Moolenbroek static int
ipc_semop_out(struct trace_proc * proc,const message * m_out)417521fa314SDavid van Moolenbroek ipc_semop_out(struct trace_proc * proc, const message * m_out)
418521fa314SDavid van Moolenbroek {
419521fa314SDavid van Moolenbroek 
420521fa314SDavid van Moolenbroek 	put_value(proc, "semid", "%d", m_out->m_lc_ipc_semop.id);
421521fa314SDavid van Moolenbroek 	put_sembuf_array(proc, "sops", (vir_bytes)m_out->m_lc_ipc_semop.ops,
422521fa314SDavid van Moolenbroek 	    m_out->m_lc_ipc_semop.size);
4233c8950ccSBen Gras 	put_value(proc, "nsops", "%u", m_out->m_lc_ipc_semop.size);
424521fa314SDavid van Moolenbroek 
425521fa314SDavid van Moolenbroek 	return CT_DONE;
426521fa314SDavid van Moolenbroek }
427521fa314SDavid van Moolenbroek 
428521fa314SDavid van Moolenbroek #define IPC_CALL(c) [((IPC_ ## c) - IPC_BASE)]
429521fa314SDavid van Moolenbroek 
430521fa314SDavid van Moolenbroek static const struct call_handler ipc_map[] = {
431521fa314SDavid van Moolenbroek 	IPC_CALL(SHMGET) = HANDLER("shmget", ipc_shmget_out, ipc_shmget_in),
432521fa314SDavid van Moolenbroek 	IPC_CALL(SHMAT) = HANDLER("shmat", ipc_shmat_out, ipc_shmat_in),
433521fa314SDavid van Moolenbroek 	IPC_CALL(SHMDT) = HANDLER("shmdt", ipc_shmdt_out, default_in),
434521fa314SDavid van Moolenbroek 	IPC_CALL(SHMCTL) = HANDLER("shmctl", ipc_shmctl_out, ipc_shmctl_in),
435521fa314SDavid van Moolenbroek 	IPC_CALL(SEMGET) = HANDLER("semget", ipc_semget_out, ipc_semget_in),
436521fa314SDavid van Moolenbroek 	IPC_CALL(SEMCTL) = HANDLER("semctl", ipc_semctl_out, ipc_semctl_in),
437521fa314SDavid van Moolenbroek 	IPC_CALL(SEMOP) = HANDLER("semop", ipc_semop_out, default_in),
438521fa314SDavid van Moolenbroek };
439521fa314SDavid van Moolenbroek 
440521fa314SDavid van Moolenbroek const struct calls ipc_calls = {
441521fa314SDavid van Moolenbroek 	.endpt = ANY,
442521fa314SDavid van Moolenbroek 	.base = IPC_BASE,
443521fa314SDavid van Moolenbroek 	.map = ipc_map,
444521fa314SDavid van Moolenbroek 	.count = COUNT(ipc_map)
445521fa314SDavid van Moolenbroek };
446