]> granicus.if.org Git - strace/blob - ipc.c
2003-04-07 Roland McGrath <roland@redhat.com>
[strace] / ipc.c
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$
31  */
32
33 #include "defs.h"
34
35 #if defined(LINUX) || defined(SUNOS4) || defined(FREEBSD)
36
37 #include <sys/ipc.h>
38 #include <sys/sem.h>
39 #include <sys/msg.h>
40 #include <sys/shm.h>
41
42 #ifndef MSG_STAT
43 #define MSG_STAT 11
44 #endif
45 #ifndef MSG_INFO
46 #define MSG_INFO 12
47 #endif
48 #ifndef SHM_STAT
49 #define SHM_STAT 13
50 #endif
51 #ifndef SHM_INFO
52 #define SHM_INFO 14
53 #endif
54 #ifndef SEM_STAT
55 #define SEM_STAT 18
56 #endif
57 #ifndef SEM_INFO
58 #define SEM_INFO 19
59 #endif
60
61 #if defined LINUX && !defined IPC_64
62 # define IPC_64 0x100
63 #endif
64
65 static struct xlat msgctl_flags[] = {
66         { IPC_RMID,     "IPC_RMID"      },
67         { IPC_SET,      "IPC_SET"       },
68         { IPC_STAT,     "IPC_STAT"      },
69 #ifdef LINUX
70         { IPC_INFO,     "IPC_INFO"      },
71         { MSG_STAT,     "MSG_STAT"      },
72         { MSG_INFO,     "MSG_INFO"      },
73 #endif /* LINUX */
74         { 0,            NULL            },
75 };
76
77 static struct xlat semctl_flags[] = {
78         { IPC_RMID,     "IPC_RMID"      },
79         { IPC_SET,      "IPC_SET"       },
80         { IPC_STAT,     "IPC_STAT"      },
81 #ifdef LINUX
82         { IPC_INFO,     "IPC_INFO"      },
83         { SEM_STAT,     "SEM_STAT"      },
84         { SEM_INFO,     "SEM_INFO"      },
85 #endif /* LINUX */
86         { GETPID,       "GETPID"        },
87         { GETVAL,       "GETVAL"        },
88         { GETALL,       "GETALL"        },
89         { GETNCNT,      "GETNCNT"       },
90         { GETZCNT,      "GETZCNT"       },
91         { SETVAL,       "SETVAL"        },
92         { SETALL,       "SETALL"        },
93         { 0,            NULL            },
94 };
95
96 static struct xlat shmctl_flags[] = {
97         { IPC_RMID,     "IPC_RMID"      },
98         { IPC_SET,      "IPC_SET"       },
99         { IPC_STAT,     "IPC_STAT"      },
100 #ifdef LINUX
101         { IPC_INFO,     "IPC_INFO"      },
102         { SHM_STAT,     "SHM_STAT"      },
103         { SHM_INFO,     "SHM_INFO"      },
104 #endif /* LINUX */
105 #ifdef SHM_LOCK
106         { SHM_LOCK,     "SHM_LOCK"      },
107 #endif
108 #ifdef SHM_UNLOCK
109         { SHM_UNLOCK,   "SHM_UNLOCK"    },
110 #endif
111         { 0,            NULL            },
112 };
113
114 static struct xlat resource_flags[] = {
115         { IPC_CREAT,    "IPC_CREAT"     },
116         { IPC_EXCL,     "IPC_EXCL"      },
117         { IPC_NOWAIT,   "IPC_NOWAIT"    },
118         { 0,            NULL            },
119 };
120
121 static struct xlat shm_flags[] = {
122 #ifdef LINUX
123         { SHM_REMAP,    "SHM_REMAP"     },
124 #endif /* LINUX */
125         { SHM_RDONLY,   "SHM_RDONLY"    },
126         { SHM_RND,      "SHM_RND"       },
127         { 0,            NULL            },
128 };
129
130 static struct xlat msg_flags[] = {
131         { MSG_NOERROR,  "MSG_NOERROR"   },
132 #ifdef LINUX
133         { MSG_EXCEPT,   "MSG_EXCEPT"    },
134 #endif /* LINUX */
135         { IPC_NOWAIT,   "IPC_NOWAIT"    },
136         { 0,            NULL            },
137 };
138
139 int sys_msgget(tcp)
140 struct tcb *tcp;
141 {
142         if (entering(tcp)) {
143                 if (tcp->u_arg[0])
144                         tprintf("%lu", tcp->u_arg[0]);
145                 else
146                         tprintf("IPC_PRIVATE");
147                 tprintf(", ");
148                 if (printflags(resource_flags, tcp->u_arg[1]) != 0)
149                         tprintf("|");
150                 tprintf("%#lo", tcp->u_arg[1] & 0666);
151         }
152         return 0;
153 }
154
155 #ifdef IPC_64
156 # define PRINTCTL(flagset, arg, dflt) \
157         if ((arg) & IPC_64) tprintf("IPC_64|"); \
158         printxval((flagset), (arg) &~ IPC_64, dflt)
159 #else
160 # define PRINTCTL printxval
161 #endif
162
163 int sys_msgctl(tcp)
164 struct tcb *tcp;
165 {
166         if (entering(tcp)) {
167                 tprintf("%lu, ", tcp->u_arg[0]);
168                 PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???");
169 #ifdef LINUX
170                 tprintf(", %#lx", tcp->u_arg[3]);
171 #else /* !LINUX */
172                 tprintf(", %#lx", tcp->u_arg[2]);
173 #endif /* !LINUX */
174         }
175         return 0;
176 }
177
178 int sys_msgsnd(tcp)
179 struct tcb *tcp;
180 {
181         long mtype;
182
183         if (entering(tcp)) {
184                 tprintf("%lu", tcp->u_arg[0]);
185 #ifdef LINUX
186                 umove(tcp, tcp->u_arg[3], &mtype);
187                 tprintf(", {%lu, ", mtype);
188                 printstr(tcp, tcp->u_arg[3] + sizeof(long),
189                         tcp->u_arg[1]);
190                 tprintf("}, %lu", tcp->u_arg[1]);
191                 tprintf(", ");
192                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
193                         tprintf("0");
194 #else /* !LINUX */
195                 umove(tcp, tcp->u_arg[1], &mtype);
196                 tprintf(", {%lu, ", mtype);
197                 printstr(tcp, tcp->u_arg[1] + sizeof(long),
198                         tcp->u_arg[2]);
199                 tprintf("}, %lu", tcp->u_arg[2]);
200                 tprintf(", ");
201                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
202                         tprintf("0");
203 #endif /* !LINUX */
204         }
205         return 0;
206 }
207
208 int sys_msgrcv(tcp)
209 struct tcb *tcp;
210 {
211         long mtype;
212 #ifdef LINUX
213         struct ipc_wrapper {
214                 struct msgbuf *msgp;
215                 long msgtyp;
216         } tmp;
217 #endif
218
219
220         if (exiting(tcp)) {
221                 tprintf("%lu", tcp->u_arg[0]);
222 #ifdef LINUX
223                 umove(tcp, tcp->u_arg[3], &tmp);
224                 umove(tcp, (long) tmp.msgp, &mtype);
225                 tprintf(", {%lu, ", mtype);
226                 printstr(tcp, (long) (tmp.msgp) + sizeof(long),
227                         tcp->u_arg[1]);
228                 tprintf("}, %lu", tcp->u_arg[1]);
229                 tprintf(", %ld", tmp.msgtyp);
230                 tprintf(", ");
231                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
232                         tprintf("0");
233 #else /* !LINUX */
234                 umove(tcp, tcp->u_arg[1], &mtype);
235                 tprintf(", {%lu, ", mtype);
236                 printstr(tcp, tcp->u_arg[1] + sizeof(long),
237                         tcp->u_arg[2]);
238                 tprintf("}, %lu", tcp->u_arg[2]);
239                 tprintf(", %ld", tcp->u_arg[3]);
240                 tprintf(", ");
241                 if (printflags(msg_flags, tcp->u_arg[4]) == 0)
242                         tprintf("0");
243 #endif /* !LINUX */
244         }
245         return 0;
246 }
247
248 int sys_semop(tcp)
249 struct tcb *tcp;
250 {
251         if (entering(tcp)) {
252                 tprintf("%lu", tcp->u_arg[0]);
253 #ifdef LINUX
254                 tprintf(", %#lx", tcp->u_arg[3]);
255                 tprintf(", %lu", tcp->u_arg[1]);
256 #else /* !LINUX */
257                 tprintf(", %#lx", tcp->u_arg[1]);
258                 tprintf(", %lu", tcp->u_arg[2]);
259 #endif /* !LINUX */
260         }
261         return 0;
262 }
263
264 #ifdef LINUX
265 int sys_semtimedop(tcp)
266 struct tcb *tcp;
267 {
268         if (entering(tcp)) {
269                 tprintf("%lu", tcp->u_arg[0]);
270                 tprintf(", %#lx", tcp->u_arg[3]);
271                 tprintf(", %lu, ", tcp->u_arg[1]);
272                 printtv(tcp, tcp->u_arg[5]);
273         }
274         return 0;
275 }
276 #endif
277
278 int sys_semget(tcp)
279 struct tcb *tcp;
280 {
281         if (entering(tcp)) {
282                 if (tcp->u_arg[0])
283                         tprintf("%lu", tcp->u_arg[0]);
284                 else
285                         tprintf("IPC_PRIVATE");
286                 tprintf(", %lu", tcp->u_arg[1]);
287                 tprintf(", ");
288                 if (printflags(resource_flags, tcp->u_arg[2] & ~0666) != 0)
289                         tprintf("|");
290                 tprintf("%#lo", tcp->u_arg[2] & 0666);
291         }
292         return 0;
293 }
294
295 int sys_semctl(tcp)
296 struct tcb *tcp;
297 {
298         if (entering(tcp)) {
299                 tprintf("%lu", tcp->u_arg[0]);
300                 tprintf(", %lu, ", tcp->u_arg[1]);
301                 PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???");
302                 tprintf(", %#lx", tcp->u_arg[3]);
303         }
304         return 0;
305 }
306
307 int sys_shmget(tcp)
308 struct tcb *tcp;
309 {
310         if (entering(tcp)) {
311                 if (tcp->u_arg[0])
312                         tprintf("%lu", tcp->u_arg[0]);
313                 else
314                         tprintf("IPC_PRIVATE");
315                 tprintf(", %lu", tcp->u_arg[1]);
316                 tprintf(", ");
317                 if (printflags(resource_flags, tcp->u_arg[2]) != 0)
318                         tprintf("|");
319                 tprintf("%#lo", tcp->u_arg[2] & 0666);
320         }
321         return 0;
322 }
323
324 int sys_shmctl(tcp)
325 struct tcb *tcp;
326 {
327         if (entering(tcp)) {
328                 tprintf("%lu, ", tcp->u_arg[0]);
329                 PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???");
330 #ifdef LINUX
331                 tprintf(", %#lx", tcp->u_arg[3]);
332 #else /* !LINUX */
333                 tprintf(", %#lx", tcp->u_arg[2]);
334 #endif /* !LINUX */
335         }
336         return 0;
337 }
338
339 int sys_shmat(tcp)
340 struct tcb *tcp;
341 {
342 #ifdef LINUX
343         unsigned long raddr;
344 #endif /* LINUX */
345
346         if (exiting(tcp)) {
347                 tprintf("%lu", tcp->u_arg[0]);
348 #ifdef LINUX
349                 tprintf(", %#lx", tcp->u_arg[3]);
350                 tprintf(", ");
351                 if (printflags(shm_flags, tcp->u_arg[1]) == 0)
352                         tprintf("0");
353 #else /* !LINUX */
354                 tprintf(", %#lx", tcp->u_arg[1]);
355                 tprintf(", ");
356                 if (printflags(shm_flags, tcp->u_arg[2]) == 0)
357                         tprintf("0");
358 #endif /* !LINUX */
359                 if (syserror(tcp))
360                         return 0;
361 #ifdef LINUX
362                 if (umove(tcp, tcp->u_arg[2], &raddr) < 0)
363                         return RVAL_NONE;
364                 tcp->u_rval = raddr;
365 #endif /* LINUX */
366                 return RVAL_HEX;
367         }
368         return 0;
369 }
370
371 int sys_shmdt(tcp)
372 struct tcb *tcp;
373 {
374         if (entering(tcp))
375 #ifdef LINUX
376                 tprintf("%#lx", tcp->u_arg[3]);
377 #else /* !LINUX */
378                 tprintf("%#lx", tcp->u_arg[0]);
379 #endif /* !LINUX */
380         return 0;
381 }
382
383 #endif /* defined(LINUX) || defined(SUNOS4) || defined(FREEBSD) */