]> granicus.if.org Git - strace/blob - ipc.c
Bunch of stuff
[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)
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 static struct xlat msgctl_flags[] = {
62         { IPC_RMID,     "IPC_RMID"      },
63         { IPC_SET,      "IPC_SET"       },
64         { IPC_STAT,     "IPC_STAT"      },
65 #ifdef LINUX
66         { IPC_INFO,     "IPC_INFO"      },
67         { MSG_STAT,     "MSG_STAT"      },
68         { MSG_INFO,     "MSG_INFO"      },
69 #endif /* LINUX */
70         { 0,            NULL            },
71 };
72
73 static struct xlat semctl_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         { SEM_STAT,     "SEM_STAT"      },
80         { SEM_INFO,     "SEM_INFO"      },
81 #endif /* LINUX */
82         { GETPID,       "GETPID"        },
83         { GETVAL,       "GETVAL"        },
84         { GETALL,       "GETALL"        },
85         { GETNCNT,      "GETNCNT"       },
86         { GETZCNT,      "GETZCNT"       },
87         { SETVAL,       "SETVAL"        },
88         { SETALL,       "SETALL"        },
89         { 0,            NULL            },
90 };
91
92 static struct xlat shmctl_flags[] = {
93         { IPC_RMID,     "IPC_RMID"      },
94         { IPC_SET,      "IPC_SET"       },
95         { IPC_STAT,     "IPC_STAT"      },
96 #ifdef LINUX
97         { IPC_INFO,     "IPC_INFO"      },
98         { SHM_STAT,     "SHM_STAT"      },
99         { SHM_INFO,     "SHM_INFO"      },
100 #endif /* LINUX */
101         { SHM_LOCK,     "SHM_LOCK"      },
102         { SHM_UNLOCK,   "SHM_UNLOCK"    },
103         { 0,            NULL            },
104 };
105
106 static struct xlat resource_flags[] = {
107         { IPC_CREAT,    "IPC_CREAT"     },
108         { IPC_EXCL,     "IPC_EXCL"      },
109         { IPC_NOWAIT,   "IPC_NOWAIT"    },
110         { 0,            NULL            },
111 };
112
113 static struct xlat shm_flags[] = {
114 #ifdef LINUX
115         { SHM_REMAP,    "SHM_REMAP"     },
116 #endif /* LINUX */
117         { SHM_RDONLY,   "SHM_RDONLY"    },
118         { SHM_RND,      "SHM_RND"       },
119         { 0,            NULL            },
120 };
121
122 static struct xlat msg_flags[] = {
123         { MSG_NOERROR,  "MSG_NOERROR"   },
124 #ifdef LINUX
125         { MSG_EXCEPT,   "MSG_EXCEPT"    },
126 #endif /* LINUX */
127         { IPC_NOWAIT,   "IPC_NOWAIT"    },
128         { 0,            NULL            },
129 };
130
131 int sys_msgget(tcp)
132 struct tcb *tcp;
133 {
134         if (entering(tcp)) {
135                 if (tcp->u_arg[0])
136                         tprintf("%lu", tcp->u_arg[0]);
137                 else
138                         tprintf("IPC_PRIVATE");
139                 tprintf(", ");
140                 if (printflags(resource_flags, tcp->u_arg[1]) != 0)
141                         tprintf("|");
142                 tprintf("%#lo", tcp->u_arg[1] & 0666);
143         }
144         return 0;
145 }
146
147 int sys_msgctl(tcp)
148 struct tcb *tcp;
149 {
150         char *cmd = xlookup(msgctl_flags, tcp->u_arg[1]);
151
152         if (entering(tcp)) {
153                 tprintf("%lu", tcp->u_arg[0]);
154                 tprintf(", %s", cmd == NULL ? "MSG_???" : cmd);
155 #ifdef LINUX
156                 tprintf(", %#lx", tcp->u_arg[3]);
157 #else /* !LINUX */
158                 tprintf(", %#lx", tcp->u_arg[2]);
159 #endif /* !LINUX */
160         }
161         return 0;
162 }
163
164 int sys_msgsnd(tcp)
165 struct tcb *tcp;
166 {
167         long mtype;
168
169         if (entering(tcp)) {
170                 tprintf("%lu", tcp->u_arg[0]);
171 #ifdef LINUX
172                 umove(tcp, tcp->u_arg[3], &mtype);
173                 tprintf(", {%lu, ", mtype);
174                 printstr(tcp, tcp->u_arg[3] + sizeof(long),
175                         tcp->u_arg[1]);
176                 tprintf("}, %lu", tcp->u_arg[1]);
177                 tprintf(", ");
178                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
179                         tprintf("0");
180 #else /* !LINUX */
181                 umove(tcp, tcp->u_arg[1], &mtype);
182                 tprintf(", {%lu, ", mtype);
183                 printstr(tcp, tcp->u_arg[1] + sizeof(long),
184                         tcp->u_arg[2]);
185                 tprintf("}, %lu", tcp->u_arg[2]);
186                 tprintf(", ");
187                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
188                         tprintf("0");
189 #endif /* !LINUX */
190         }
191         return 0;
192 }
193
194 int sys_msgrcv(tcp)
195 struct tcb *tcp;
196 {
197         long mtype;
198 #ifdef LINUX
199         struct ipc_wrapper {
200                 struct msgbuf *msgp;
201                 long msgtyp;
202         } tmp;
203 #endif
204
205
206         if (exiting(tcp)) {
207                 tprintf("%lu", tcp->u_arg[0]);
208 #ifdef LINUX
209                 umove(tcp, tcp->u_arg[3], &tmp);
210                 umove(tcp, (long) tmp.msgp, &mtype);
211                 tprintf(", {%lu, ", mtype);
212                 printstr(tcp, (long) (tmp.msgp) + sizeof(long),
213                         tcp->u_arg[1]);
214                 tprintf("}, %lu", tcp->u_arg[1]);
215                 tprintf(", %ld", tmp.msgtyp);
216                 tprintf(", ");
217                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
218                         tprintf("0");
219 #else /* !LINUX */
220                 umove(tcp, tcp->u_arg[1], &mtype);
221                 tprintf(", {%lu, ", mtype);
222                 printstr(tcp, tcp->u_arg[1] + sizeof(long),
223                         tcp->u_arg[2]);
224                 tprintf("}, %lu", tcp->u_arg[2]);
225                 tprintf(", %ld", tcp->u_arg[3]);
226                 tprintf(", ");
227                 if (printflags(msg_flags, tcp->u_arg[4]) == 0)
228                         tprintf("0");
229 #endif /* !LINUX */
230         }
231         return 0;
232 }
233
234 int sys_semop(tcp)
235 struct tcb *tcp;
236 {
237         if (entering(tcp)) {
238                 tprintf("%lu", tcp->u_arg[0]);
239 #ifdef LINUX
240                 tprintf(", %#lx", tcp->u_arg[3]);
241                 tprintf(", %lu", tcp->u_arg[1]);
242 #else /* !LINUX */
243                 tprintf(", %#lx", tcp->u_arg[1]);
244                 tprintf(", %lu", tcp->u_arg[2]);
245 #endif /* !LINUX */
246         }
247         return 0;
248 }
249
250 int sys_semget(tcp)
251 struct tcb *tcp;
252 {
253         if (entering(tcp)) {
254                 if (tcp->u_arg[0])
255                         tprintf("%lu", tcp->u_arg[0]);
256                 else
257                         tprintf("IPC_PRIVATE");
258                 tprintf(", %lu", tcp->u_arg[1]);
259                 tprintf(", ");
260                 if (printflags(resource_flags, tcp->u_arg[2]) != 0)
261                         tprintf("|");
262                 tprintf("%#lo", tcp->u_arg[2] & 0666);
263         }
264         return 0;
265 }
266
267 int sys_semctl(tcp)
268 struct tcb *tcp;
269 {
270         if (entering(tcp)) {
271                 tprintf("%lu", tcp->u_arg[0]);
272                 tprintf(", %lu, ", tcp->u_arg[1]);
273                 printxval(semctl_flags, tcp->u_arg[2], "SEM_???");
274                 tprintf(", %#lx", tcp->u_arg[3]);
275         }
276         return 0;
277 }
278
279 int sys_shmget(tcp)
280 struct tcb *tcp;
281 {
282         if (entering(tcp)) {
283                 if (tcp->u_arg[0])
284                         tprintf("%lu", tcp->u_arg[0]);
285                 else
286                         tprintf("IPC_PRIVATE");
287                 tprintf(", %lu", tcp->u_arg[1]);
288                 tprintf(", ");
289                 if (printflags(resource_flags, tcp->u_arg[2]) != 0)
290                         tprintf("|");
291                 tprintf("%#lo", tcp->u_arg[2] & 0666);
292         }
293         return 0;
294 }
295
296 int sys_shmctl(tcp)
297 struct tcb *tcp;
298 {
299         if (entering(tcp)) {
300                 tprintf("%lu, ", tcp->u_arg[0]);
301                 printxval(shmctl_flags, tcp->u_arg[1], "SHM_???");
302 #ifdef LINUX
303                 tprintf(", %#lx", tcp->u_arg[3]);
304 #else /* !LINUX */
305                 tprintf(", %#lx", tcp->u_arg[2]);
306 #endif /* !LINUX */
307         }
308         return 0;
309 }
310
311 int sys_shmat(tcp)
312 struct tcb *tcp;
313 {
314 #ifdef LINUX
315         unsigned long raddr;
316 #endif /* LINUX */
317
318         if (exiting(tcp)) {
319                 tprintf("%lu", tcp->u_arg[0]);
320 #ifdef LINUX
321                 tprintf(", %#lx", tcp->u_arg[3]);
322                 tprintf(", ");
323                 if (printflags(shm_flags, tcp->u_arg[1]) == 0)
324                         tprintf("0");
325 #else /* !LINUX */
326                 tprintf(", %#lx", tcp->u_arg[1]);
327                 tprintf(", ");
328                 if (printflags(shm_flags, tcp->u_arg[2]) == 0)
329                         tprintf("0");
330 #endif /* !LINUX */
331                 if (syserror(tcp))
332                         return 0;
333 #ifdef LINUX
334                 if (umove(tcp, tcp->u_arg[2], &raddr) < 0)
335                         return RVAL_NONE;
336                 tcp->u_rval = raddr;
337 #endif /* LINUX */
338                 return RVAL_HEX;
339         }
340         return 0;
341 }
342
343 int sys_shmdt(tcp)
344 struct tcb *tcp;
345 {
346         if (entering(tcp))
347 #ifdef LINUX
348                 tprintf("%#lx", tcp->u_arg[3]);
349 #else /* !LINUX */
350                 tprintf("%#lx", tcp->u_arg[0]);
351 #endif /* !LINUX */
352         return 0;
353 }
354
355 #endif /* defined(LINUX) || defined(SUNOS4) */