• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1993 Ulrich Pegelow <pegelow@moorea.uni-muenster.de>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *	$Id: ipc.c,v 1.10 2005/06/01 19:02:37 roland Exp $
31  */
32 
33 #include "defs.h"
34 
35 #if defined(LINUX) || defined(SUNOS4) || defined(FREEBSD)
36 
37 # ifdef HAVE_MQUEUE_H
38 #  include <mqueue.h>
39 # endif
40 
41 #include <fcntl.h>
42 #include <sys/ipc.h>
43 #include <sys/sem.h>
44 #include <sys/msg.h>
45 #include <sys/shm.h>
46 
47 #ifndef MSG_STAT
48 #define MSG_STAT 11
49 #endif
50 #ifndef MSG_INFO
51 #define MSG_INFO 12
52 #endif
53 #ifndef SHM_STAT
54 #define SHM_STAT 13
55 #endif
56 #ifndef SHM_INFO
57 #define SHM_INFO 14
58 #endif
59 #ifndef SEM_STAT
60 #define SEM_STAT 18
61 #endif
62 #ifndef SEM_INFO
63 #define SEM_INFO 19
64 #endif
65 
66 #if defined LINUX && !defined IPC_64
67 # define IPC_64 0x100
68 #endif
69 
70 extern const struct xlat openmodes[];
71 extern void printsigevent(struct tcb *tcp, long arg);
72 
73 static const struct xlat msgctl_flags[] = {
74 	{ IPC_RMID,	"IPC_RMID"	},
75 	{ IPC_SET,	"IPC_SET"	},
76 	{ IPC_STAT,	"IPC_STAT"	},
77 #ifdef LINUX
78 	{ IPC_INFO,	"IPC_INFO"	},
79 	{ MSG_STAT,	"MSG_STAT"	},
80 	{ MSG_INFO,	"MSG_INFO"	},
81 #endif /* LINUX */
82 	{ 0,		NULL		},
83 };
84 
85 static const struct xlat semctl_flags[] = {
86 	{ IPC_RMID,	"IPC_RMID"	},
87 	{ IPC_SET,	"IPC_SET"	},
88 	{ IPC_STAT,	"IPC_STAT"	},
89 #ifdef LINUX
90 	{ IPC_INFO,	"IPC_INFO"	},
91 	{ SEM_STAT,	"SEM_STAT"	},
92 	{ SEM_INFO,	"SEM_INFO"	},
93 #endif /* LINUX */
94 	{ GETPID,	"GETPID"	},
95 	{ GETVAL,	"GETVAL"	},
96 	{ GETALL,	"GETALL"	},
97 	{ GETNCNT,	"GETNCNT"	},
98 	{ GETZCNT,	"GETZCNT"	},
99 	{ SETVAL,	"SETVAL"	},
100 	{ SETALL,	"SETALL"	},
101 	{ 0,		NULL		},
102 };
103 
104 static const struct xlat shmctl_flags[] = {
105 	{ IPC_RMID,	"IPC_RMID"	},
106 	{ IPC_SET,	"IPC_SET"	},
107 	{ IPC_STAT,	"IPC_STAT"	},
108 #ifdef LINUX
109 	{ IPC_INFO,	"IPC_INFO"	},
110 	{ SHM_STAT,	"SHM_STAT"	},
111 	{ SHM_INFO,	"SHM_INFO"	},
112 #endif /* LINUX */
113 #ifdef SHM_LOCK
114 	{ SHM_LOCK,	"SHM_LOCK"	},
115 #endif
116 #ifdef SHM_UNLOCK
117 	{ SHM_UNLOCK,	"SHM_UNLOCK"	},
118 #endif
119 	{ 0,		NULL		},
120 };
121 
122 static const struct xlat resource_flags[] = {
123 	{ IPC_CREAT,	"IPC_CREAT"	},
124 	{ IPC_EXCL,	"IPC_EXCL"	},
125 	{ IPC_NOWAIT,	"IPC_NOWAIT"	},
126 	{ 0,		NULL		},
127 };
128 
129 static const struct xlat shm_resource_flags[] = {
130 	{ IPC_CREAT,	"IPC_CREAT"	},
131 	{ IPC_EXCL,	"IPC_EXCL"	},
132 #ifdef SHM_HUGETLB
133 	{ SHM_HUGETLB,	"SHM_HUGETLB"	},
134 #endif
135 	{ 0,		NULL		},
136 };
137 
138 static const struct xlat shm_flags[] = {
139 #ifdef LINUX
140 	{ SHM_REMAP,	"SHM_REMAP"	},
141 #endif /* LINUX */
142 	{ SHM_RDONLY,	"SHM_RDONLY"	},
143 	{ SHM_RND,	"SHM_RND"	},
144 	{ 0,		NULL		},
145 };
146 
147 static const struct xlat msg_flags[] = {
148 	{ MSG_NOERROR,	"MSG_NOERROR"	},
149 #ifdef LINUX
150 	{ MSG_EXCEPT,	"MSG_EXCEPT"	},
151 #endif /* LINUX */
152 	{ IPC_NOWAIT,	"IPC_NOWAIT"	},
153 	{ 0,		NULL		},
154 };
155 
sys_msgget(tcp)156 int sys_msgget(tcp)
157 struct tcb *tcp;
158 {
159 	if (entering(tcp)) {
160 		if (tcp->u_arg[0])
161 			tprintf("%lu", tcp->u_arg[0]);
162 		else
163 			tprintf("IPC_PRIVATE");
164 		tprintf(", ");
165 		if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0)
166 			tprintf("|");
167 		tprintf("%#lo", tcp->u_arg[1] & 0777);
168 	}
169 	return 0;
170 }
171 
172 #ifdef IPC_64
173 # define PRINTCTL(flagset, arg, dflt) \
174 	if ((arg) & IPC_64) tprintf("IPC_64|"); \
175 	printxval((flagset), (arg) &~ IPC_64, dflt)
176 #else
177 # define PRINTCTL printxval
178 #endif
179 
sys_msgctl(tcp)180 int sys_msgctl(tcp)
181 struct tcb *tcp;
182 {
183 	if (entering(tcp)) {
184 		tprintf("%lu, ", tcp->u_arg[0]);
185 		PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???");
186 #ifdef LINUX
187 		tprintf(", %#lx", tcp->u_arg[3]);
188 #else /* !LINUX */
189 		tprintf(", %#lx", tcp->u_arg[2]);
190 #endif /* !LINUX */
191 	}
192 	return 0;
193 }
194 
sys_msgsnd(tcp)195 int sys_msgsnd(tcp)
196 struct tcb *tcp;
197 {
198 	long mtype;
199 
200 	if (entering(tcp)) {
201 		tprintf("%lu", tcp->u_arg[0]);
202 #ifdef LINUX
203 		umove(tcp, tcp->u_arg[3], &mtype);
204 		tprintf(", {%lu, ", mtype);
205 		printstr(tcp, tcp->u_arg[3] + sizeof(long),
206 			tcp->u_arg[1]);
207 		tprintf("}, %lu", tcp->u_arg[1]);
208 		tprintf(", ");
209 		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
210 #else /* !LINUX */
211 		umove(tcp, tcp->u_arg[1], &mtype);
212 		tprintf(", {%lu, ", mtype);
213 		printstr(tcp, tcp->u_arg[1] + sizeof(long),
214 			tcp->u_arg[2]);
215 		tprintf("}, %lu", tcp->u_arg[2]);
216 		tprintf(", ");
217 		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
218 #endif /* !LINUX */
219 	}
220 	return 0;
221 }
222 
sys_msgrcv(tcp)223 int sys_msgrcv(tcp)
224 struct tcb *tcp;
225 {
226 	long mtype;
227 #ifdef LINUX
228 	struct ipc_wrapper {
229 		struct msgbuf *msgp;
230 		long msgtyp;
231 	} tmp;
232 #endif
233 
234 
235 	if (exiting(tcp)) {
236 		tprintf("%lu", tcp->u_arg[0]);
237 #ifdef LINUX
238 		umove(tcp, tcp->u_arg[3], &tmp);
239 		umove(tcp, (long) tmp.msgp, &mtype);
240 		tprintf(", {%lu, ", mtype);
241 		printstr(tcp, (long) (tmp.msgp) + sizeof(long),
242 			tcp->u_arg[1]);
243 		tprintf("}, %lu", tcp->u_arg[1]);
244 		tprintf(", %ld", tmp.msgtyp);
245 		tprintf(", ");
246 		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
247 #else /* !LINUX */
248 		umove(tcp, tcp->u_arg[1], &mtype);
249 		tprintf(", {%lu, ", mtype);
250 		printstr(tcp, tcp->u_arg[1] + sizeof(long),
251 			tcp->u_arg[2]);
252 		tprintf("}, %lu", tcp->u_arg[2]);
253 		tprintf(", %ld", tcp->u_arg[3]);
254 		tprintf(", ");
255 		printflags(msg_flags, tcp->u_arg[4], "MSG_???");
256 #endif /* !LINUX */
257 	}
258 	return 0;
259 }
260 
sys_semop(tcp)261 int sys_semop(tcp)
262 struct tcb *tcp;
263 {
264 	if (entering(tcp)) {
265 		tprintf("%lu", tcp->u_arg[0]);
266 #ifdef LINUX
267 		tprintf(", %#lx", tcp->u_arg[3]);
268 		tprintf(", %lu", tcp->u_arg[1]);
269 #else /* !LINUX */
270 		tprintf(", %#lx", tcp->u_arg[1]);
271 		tprintf(", %lu", tcp->u_arg[2]);
272 #endif /* !LINUX */
273 	}
274 	return 0;
275 }
276 
277 #ifdef LINUX
sys_semtimedop(tcp)278 int sys_semtimedop(tcp)
279 struct tcb *tcp;
280 {
281 	if (entering(tcp)) {
282 		tprintf("%lu", tcp->u_arg[0]);
283 		tprintf(", %#lx", tcp->u_arg[3]);
284 		tprintf(", %lu, ", tcp->u_arg[1]);
285 		printtv(tcp, tcp->u_arg[5]);
286 	}
287 	return 0;
288 }
289 #endif
290 
sys_semget(tcp)291 int sys_semget(tcp)
292 struct tcb *tcp;
293 {
294 	if (entering(tcp)) {
295 		if (tcp->u_arg[0])
296 			tprintf("%lu", tcp->u_arg[0]);
297 		else
298 			tprintf("IPC_PRIVATE");
299 		tprintf(", %lu", tcp->u_arg[1]);
300 		tprintf(", ");
301 		if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
302 			tprintf("|");
303 		tprintf("%#lo", tcp->u_arg[2] & 0777);
304 	}
305 	return 0;
306 }
307 
sys_semctl(tcp)308 int sys_semctl(tcp)
309 struct tcb *tcp;
310 {
311 	if (entering(tcp)) {
312 		tprintf("%lu", tcp->u_arg[0]);
313 		tprintf(", %lu, ", tcp->u_arg[1]);
314 		PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???");
315 		tprintf(", %#lx", tcp->u_arg[3]);
316 	}
317 	return 0;
318 }
319 
sys_shmget(tcp)320 int sys_shmget(tcp)
321 struct tcb *tcp;
322 {
323 	if (entering(tcp)) {
324 		if (tcp->u_arg[0])
325 			tprintf("%lu", tcp->u_arg[0]);
326 		else
327 			tprintf("IPC_PRIVATE");
328 		tprintf(", %lu", tcp->u_arg[1]);
329 		tprintf(", ");
330 		if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
331 			tprintf("|");
332 		tprintf("%#lo", tcp->u_arg[2] & 0777);
333 	}
334 	return 0;
335 }
336 
sys_shmctl(tcp)337 int sys_shmctl(tcp)
338 struct tcb *tcp;
339 {
340 	if (entering(tcp)) {
341 		tprintf("%lu, ", tcp->u_arg[0]);
342 		PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???");
343 #ifdef LINUX
344 		tprintf(", %#lx", tcp->u_arg[3]);
345 #else /* !LINUX */
346 		tprintf(", %#lx", tcp->u_arg[2]);
347 #endif /* !LINUX */
348 	}
349 	return 0;
350 }
351 
sys_shmat(tcp)352 int sys_shmat(tcp)
353 struct tcb *tcp;
354 {
355 #ifdef LINUX
356 	unsigned long raddr;
357 #endif /* LINUX */
358 
359 	if (exiting(tcp)) {
360 		tprintf("%lu", tcp->u_arg[0]);
361 #ifdef LINUX
362 		tprintf(", %#lx", tcp->u_arg[3]);
363 		tprintf(", ");
364 		printflags(shm_flags, tcp->u_arg[1], "SHM_???");
365 #else /* !LINUX */
366 		tprintf(", %#lx", tcp->u_arg[1]);
367 		tprintf(", ");
368 		printflags(shm_flags, tcp->u_arg[2], "SHM_???");
369 #endif /* !LINUX */
370 		if (syserror(tcp))
371 			return 0;
372 #ifdef LINUX
373 		if (umove(tcp, tcp->u_arg[2], &raddr) < 0)
374 			return RVAL_NONE;
375 		tcp->u_rval = raddr;
376 #endif /* LINUX */
377 		return RVAL_HEX;
378 	}
379 	return 0;
380 }
381 
sys_shmdt(tcp)382 int sys_shmdt(tcp)
383 struct tcb *tcp;
384 {
385 	if (entering(tcp))
386 #ifdef LINUX
387 		tprintf("%#lx", tcp->u_arg[3]);
388 #else /* !LINUX */
389 		tprintf("%#lx", tcp->u_arg[0]);
390 #endif /* !LINUX */
391 	return 0;
392 }
393 
394 #endif /* defined(LINUX) || defined(SUNOS4) || defined(FREEBSD) */
395 
396 #ifdef LINUX
sys_mq_open(tcp)397 int sys_mq_open(tcp)
398 struct tcb *tcp;
399 {
400 	if (entering(tcp)) {
401 		printpath(tcp, tcp->u_arg[0]);
402 		tprintf(", ");
403 		/* flags */
404 		printflags(openmodes, tcp->u_arg[1] + 1, "O_???");
405 		if (tcp->u_arg[1] & O_CREAT) {
406 # ifndef HAVE_MQUEUE_H
407 			tprintf(", %lx", tcp->u_arg[2]);
408 # else
409 			struct mq_attr attr;
410 			/* mode */
411 			tprintf(", %#lo, ", tcp->u_arg[2]);
412 			if (umove(tcp, tcp->u_arg[3], &attr) < 0)
413 				tprintf("{ ??? }");
414 			else
415 				tprintf("{mq_maxmsg=%ld, mq_msgsize=%ld}",
416 					attr.mq_maxmsg, attr.mq_msgsize);
417 # endif
418 		}
419 	}
420 	return 0;
421 }
422 
sys_mq_timedsend(tcp)423 int sys_mq_timedsend(tcp)
424 struct tcb *tcp;
425 {
426 	if (entering(tcp)) {
427 		tprintf("%ld, ", tcp->u_arg[0]);
428 		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
429 		tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]);
430 		printtv(tcp, tcp->u_arg[4]);
431 	}
432 	return 0;
433 }
434 
sys_mq_timedreceive(tcp)435 int sys_mq_timedreceive(tcp)
436 struct tcb *tcp;
437 {
438 	if (entering(tcp))
439 		tprintf("%ld, ", tcp->u_arg[0]);
440 	else {
441 		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
442 		tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]);
443 		printtv(tcp, tcp->u_arg[4]);
444 	}
445 	return 0;
446 }
447 
sys_mq_notify(tcp)448 int sys_mq_notify(tcp)
449 struct tcb *tcp;
450 {
451 	if (entering(tcp)) {
452 		tprintf("%ld, ", tcp->u_arg[0]);
453 		printsigevent(tcp, tcp->u_arg[1]);
454 	}
455 	return 0;
456 }
457 
printmqattr(tcp,addr)458 static void printmqattr(tcp, addr)
459 struct tcb *tcp;
460 long addr;
461 {
462 	if (addr == 0)
463 		tprintf("NULL");
464 	else {
465 # ifndef HAVE_MQUEUE_H
466 		tprintf("%#lx", addr);
467 # else
468 		struct mq_attr attr;
469 		if (umove(tcp, addr, &attr) < 0) {
470 			tprintf("{...}");
471 			return;
472 		}
473 		tprintf("{mq_flags=");
474 		printflags(openmodes, attr.mq_flags + 1, "O_???");
475 		tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}",
476 			attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
477 # endif
478 	}
479 }
480 
sys_mq_getsetattr(tcp)481 int sys_mq_getsetattr(tcp)
482 struct tcb *tcp;
483 {
484 	if (entering(tcp)) {
485 		tprintf("%ld, ", tcp->u_arg[0]);
486 		printmqattr(tcp, tcp->u_arg[1]);
487 		tprintf(", ");
488 	} else
489 		printmqattr(tcp, tcp->u_arg[2]);
490 	return 0;
491 }
492 #endif
493