blob: f1e0334dc1e8b6ec383d4aa6dbb964d457183fcf [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32#include "defs.h"
33
34#include <fcntl.h>
35#include <sys/file.h>
36
37static struct xlat fcntlcmds[] = {
38 { F_DUPFD, "F_DUPFD" },
39 { F_GETFD, "F_GETFD" },
40 { F_SETFD, "F_SETFD" },
41 { F_GETFL, "F_GETFL" },
42 { F_SETFL, "F_SETFL" },
43 { F_GETLK, "F_GETLK" },
44 { F_SETLK, "F_SETLK" },
45 { F_SETLKW, "F_SETLKW" },
46 { F_GETOWN, "F_GETOWN" },
47 { F_SETOWN, "F_SETOWN" },
48#ifdef F_RSETLK
49 { F_RSETLK, "F_RSETLK" },
50#endif
51#ifdef F_RSETLKW
52 { F_RSETLKW, "F_RSETLKW" },
53#endif
54#ifdef F_RGETLK
55 { F_RGETLK, "F_RGETLK" },
56#endif
57#ifdef F_CNVT
58 { F_CNVT, "F_CNVT" },
59#endif
60 { 0, NULL },
61};
62
63static struct xlat fdflags[] = {
64#ifdef FD_CLOEXEC
65 { FD_CLOEXEC, "FD_CLOEXEC" },
66#endif
67 { 0, NULL },
68};
69
70#ifdef LOCK_SH
71
72static struct xlat flockcmds[] = {
73 { LOCK_SH, "LOCK_SH" },
74 { LOCK_EX, "LOCK_EX" },
75 { LOCK_NB, "LOCK_NB" },
76 { LOCK_UN, "LOCK_UN" },
77 { 0, NULL },
78};
79
80#endif /* LOCK_SH */
81
82static struct xlat lockfcmds[] = {
83 { F_RDLCK, "F_RDLCK" },
84 { F_WRLCK, "F_WRLCK" },
85 { F_UNLCK, "F_UNLCK" },
86#ifdef F_EXLCK
87 { F_EXLCK, "F_EXLCK" },
88#endif
89#ifdef F_SHLCK
90 { F_SHLCK, "F_SHLCK" },
91#endif
92 { 0, NULL },
93};
94
95static struct xlat whence[] = {
96 { SEEK_SET, "SEEK_SET" },
97 { SEEK_CUR, "SEEK_CUR" },
98 { SEEK_END, "SEEK_END" },
99 { 0, NULL },
100};
101
102/* fcntl/lockf */
103static void
104printflock(tcp, addr, getlk)
105struct tcb *tcp;
106int addr;
107int getlk;
108{
109 struct flock fl;
110
111 if (umove(tcp, addr, &fl) < 0) {
112 tprintf("{...}");
113 return;
114 }
115 tprintf("{type=");
116 printxval(lockfcmds, fl.l_type, "F_???");
117 tprintf(", whence=");
118 printxval(whence, fl.l_whence, "SEEK_???");
119 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
120 if (getlk)
121 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
122 else
123 tprintf("}");
124}
125
126static char *
127sprintflags(xlat, flags)
128struct xlat *xlat;
129int flags;
130{
131 static char outstr[1024];
132 char *sep;
133
134 strcpy(outstr, "flags ");
135 sep = "";
136 for (; xlat->str; xlat++) {
137 if ((flags & xlat->val) == xlat->val) {
138 sprintf(outstr + strlen(outstr),
139 "%s%s", sep, xlat->str);
140 sep = "|";
141 flags &= ~xlat->val;
142 }
143 }
144 if (flags)
145 sprintf(outstr + strlen(outstr),
146 "%s%#x", sep, flags);
147 return outstr;
148}
149
150int
151sys_fcntl(tcp)
152struct tcb *tcp;
153{
154 extern struct xlat openmodes[];
155
156 if (entering(tcp)) {
157 tprintf("%ld, ", tcp->u_arg[0]);
158 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
159 switch (tcp->u_arg[1]) {
160 case F_SETFD:
161 tprintf(", ");
162 if (printflags(fdflags, tcp->u_arg[2]) == 0)
163 tprintf("0");
164 break;
165 case F_SETOWN: case F_DUPFD:
166 tprintf(", %ld", tcp->u_arg[2]);
167 break;
168 case F_SETFL:
169 tprintf(", ");
170 if (printflags(openmodes, tcp->u_arg[2] + 1) == 0)
171 tprintf("0");
172 break;
173 case F_SETLK: case F_SETLKW:
174 tprintf(", ");
175 printflock(tcp, tcp->u_arg[2], 0);
176 break;
177 }
178 }
179 else {
180 switch (tcp->u_arg[1]) {
181 case F_DUPFD:
182 case F_SETFD: case F_SETFL:
183 case F_SETLK: case F_SETLKW:
184 case F_SETOWN: case F_GETOWN:
185 break;
186 case F_GETFD:
187 if (tcp->u_rval == 0)
188 return 0;
189 tcp->auxstr = sprintflags(fdflags, tcp->u_rval);
190 return RVAL_HEX|RVAL_STR;
191 case F_GETFL:
192 tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1);
193 return RVAL_HEX|RVAL_STR;
194 case F_GETLK:
195 tprintf(", ");
196 printflock(tcp, tcp->u_arg[2], 1);
197 break;
198 default:
199 tprintf(", %#lx", tcp->u_arg[2]);
200 break;
201 }
202 }
203 return 0;
204}
205
206#ifdef LOCK_SH
207
208int
209sys_flock(tcp)
210struct tcb *tcp;
211{
212 if (entering(tcp)) {
213 tprintf("%ld, ", tcp->u_arg[0]);
214 if (!printflags(flockcmds, tcp->u_arg[1]))
215 tprintf("LOCK_???");
216 }
217 return 0;
218}
219#endif /* LOCK_SH */
220
221int
222sys_close(tcp)
223struct tcb *tcp;
224{
225 if (entering(tcp)) {
226 tprintf("%ld", tcp->u_arg[0]);
227 }
228 return 0;
229}
230
231int
232sys_dup(tcp)
233struct tcb *tcp;
234{
235 if (entering(tcp)) {
236 tprintf("%ld", tcp->u_arg[0]);
237 }
238 return 0;
239}
240
241int
242sys_dup2(tcp)
243struct tcb *tcp;
244{
245 if (entering(tcp)) {
246 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
247 }
248 return 0;
249}
250
251int
252sys_getdtablesize(tcp)
253struct tcb *tcp;
254{
255 return 0;
256}
257
258static int
259decode_select(tcp, args)
260struct tcb *tcp;
261long *args;
262{
263 int i, j, nfds;
264 fd_set fds;
265 struct timeval tv;
266 static char outstr[1024];
267 char *sep;
268 long arg;
269
270 if (entering(tcp)) {
271 nfds = args[0];
272 tprintf("%d", nfds);
273 for (i = 0; i < 3; i++) {
274 arg = args[i+1];
275 if (arg == 0) {
276 tprintf(", NULL");
277 continue;
278 }
279 if (!verbose(tcp)) {
280 tprintf(", %#lx", arg);
281 continue;
282 }
283 if (umove(tcp, arg, &fds) < 0) {
284 tprintf(", [?]");
285 continue;
286 }
287 tprintf(", [");
288 for (j = 0, sep = ""; j < nfds; j++) {
289 if (FD_ISSET(j, &fds)) {
290 tprintf("%s%u", sep, j);
291 sep = " ";
292 }
293 }
294 tprintf("]");
295 }
296 if (!args[4])
297 tprintf(", NULL");
298 else if (!verbose(tcp))
299 tprintf(", %#lx", args[4]);
300 else if (umove(tcp, args[4], &tv) < 0)
301 tprintf(", {...}");
302 else {
303 tprintf(", {%lu, %lu}",
304 (long) tv.tv_sec, (long) tv.tv_usec);
305 }
306 }
307 else {
308 unsigned int cumlen = 0;
309 char *sep = "";
310
311 if (syserror(tcp))
312 return 0;
313
314 if ((nfds = tcp->u_rval) == 0) {
315 tcp->auxstr = "Timeout";
316 return RVAL_STR;
317 }
318 outstr[0] = '\0';
319 for (i = 0; i < 3; i++) {
320 int first = 1;
321 char str[20];
322
323 tcp->auxstr = outstr;
324 arg = args[i+1];
325 if (!arg || umove(tcp, arg, &fds) < 0)
326 continue;
327 for (j = 0; j < args[0]; j++) {
328 if (FD_ISSET(j, &fds)) {
329 if (first) {
330 sprintf(str, "%s%s [%u", sep,
331 i == 0 ? "in" :
332 i == 1 ? "out" :
333 "except", j);
334 first = 0;
335 sep = ", ";
336 }
337 else
338 sprintf(str, " %u", j);
339 cumlen += strlen(str);
340 if (cumlen < sizeof(outstr))
341 strcat(outstr, str);
342 nfds--;
343 }
344 }
345 if (cumlen)
346 strcat(outstr, "]");
347 if (nfds == 0)
348 break;
349 }
350#ifdef LINUX
351 /* This contains no useful information on SunOS. */
352 if (args[4]) {
353 char str[20];
354
355 if (umove(tcp, args[4], &tv) >= 0)
356 sprintf(str, "%sleft {%lu, %lu}", sep,
357 (long) tv.tv_sec, (long) tv.tv_usec);
358 if ((cumlen += strlen(str)) < sizeof(outstr))
359 strcat(outstr, str);
360 }
361#endif /* LINUX */
362 return RVAL_STR;
363 }
364 return 0;
365}
366
367#ifdef LINUX
368
369int
370sys_oldselect(tcp)
371struct tcb *tcp;
372{
373 long args[5];
374
375 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
376 tprintf("[...]");
377 return 0;
378 }
379 return decode_select(tcp, args);
380}
381
382#endif /* LINUX */
383
384int
385sys_select(tcp)
386struct tcb *tcp;
387{
388 long *args = tcp->u_arg;
389 return decode_select(tcp, args);
390}