blob: ce62d4e9475e0f6d8a5b39d5a7a6055878f525fa [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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * 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#include <fcntl.h>
36#include <sys/file.h>
37
38static struct xlat fcntlcmds[] = {
39 { F_DUPFD, "F_DUPFD" },
40 { F_GETFD, "F_GETFD" },
41 { F_SETFD, "F_SETFD" },
42 { F_GETFL, "F_GETFL" },
43 { F_SETFL, "F_SETFL" },
44 { F_GETLK, "F_GETLK" },
45 { F_SETLK, "F_SETLK" },
46 { F_SETLKW, "F_SETLKW" },
47 { F_GETOWN, "F_GETOWN" },
48 { F_SETOWN, "F_SETOWN" },
49#ifdef F_RSETLK
50 { F_RSETLK, "F_RSETLK" },
51#endif
52#ifdef F_RSETLKW
53 { F_RSETLKW, "F_RSETLKW" },
54#endif
55#ifdef F_RGETLK
56 { F_RGETLK, "F_RGETLK" },
57#endif
58#ifdef F_CNVT
59 { F_CNVT, "F_CNVT" },
60#endif
61 { 0, NULL },
62};
63
64static struct xlat fdflags[] = {
65#ifdef FD_CLOEXEC
66 { FD_CLOEXEC, "FD_CLOEXEC" },
67#endif
68 { 0, NULL },
69};
70
71#ifdef LOCK_SH
72
73static struct xlat flockcmds[] = {
74 { LOCK_SH, "LOCK_SH" },
75 { LOCK_EX, "LOCK_EX" },
76 { LOCK_NB, "LOCK_NB" },
77 { LOCK_UN, "LOCK_UN" },
78 { 0, NULL },
79};
80
81#endif /* LOCK_SH */
82
83static struct xlat lockfcmds[] = {
84 { F_RDLCK, "F_RDLCK" },
85 { F_WRLCK, "F_WRLCK" },
86 { F_UNLCK, "F_UNLCK" },
87#ifdef F_EXLCK
88 { F_EXLCK, "F_EXLCK" },
89#endif
90#ifdef F_SHLCK
91 { F_SHLCK, "F_SHLCK" },
92#endif
93 { 0, NULL },
94};
95
96static struct xlat whence[] = {
97 { SEEK_SET, "SEEK_SET" },
98 { SEEK_CUR, "SEEK_CUR" },
99 { SEEK_END, "SEEK_END" },
100 { 0, NULL },
101};
102
103/* fcntl/lockf */
104static void
105printflock(tcp, addr, getlk)
106struct tcb *tcp;
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000107long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000108int getlk;
109{
110 struct flock fl;
111
112 if (umove(tcp, addr, &fl) < 0) {
113 tprintf("{...}");
114 return;
115 }
116 tprintf("{type=");
117 printxval(lockfcmds, fl.l_type, "F_???");
118 tprintf(", whence=");
119 printxval(whence, fl.l_whence, "SEEK_???");
120 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
121 if (getlk)
122 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
123 else
124 tprintf("}");
125}
126
127static char *
128sprintflags(xlat, flags)
129struct xlat *xlat;
130int flags;
131{
132 static char outstr[1024];
133 char *sep;
134
135 strcpy(outstr, "flags ");
136 sep = "";
137 for (; xlat->str; xlat++) {
138 if ((flags & xlat->val) == xlat->val) {
139 sprintf(outstr + strlen(outstr),
140 "%s%s", sep, xlat->str);
141 sep = "|";
142 flags &= ~xlat->val;
143 }
144 }
145 if (flags)
146 sprintf(outstr + strlen(outstr),
147 "%s%#x", sep, flags);
148 return outstr;
149}
150
151int
152sys_fcntl(tcp)
153struct tcb *tcp;
154{
155 extern struct xlat openmodes[];
156
157 if (entering(tcp)) {
158 tprintf("%ld, ", tcp->u_arg[0]);
159 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
160 switch (tcp->u_arg[1]) {
161 case F_SETFD:
162 tprintf(", ");
163 if (printflags(fdflags, tcp->u_arg[2]) == 0)
164 tprintf("0");
165 break;
166 case F_SETOWN: case F_DUPFD:
167 tprintf(", %ld", tcp->u_arg[2]);
168 break;
169 case F_SETFL:
170 tprintf(", ");
171 if (printflags(openmodes, tcp->u_arg[2] + 1) == 0)
172 tprintf("0");
173 break;
174 case F_SETLK: case F_SETLKW:
175 tprintf(", ");
176 printflock(tcp, tcp->u_arg[2], 0);
177 break;
178 }
179 }
180 else {
181 switch (tcp->u_arg[1]) {
182 case F_DUPFD:
183 case F_SETFD: case F_SETFL:
184 case F_SETLK: case F_SETLKW:
185 case F_SETOWN: case F_GETOWN:
186 break;
187 case F_GETFD:
188 if (tcp->u_rval == 0)
189 return 0;
190 tcp->auxstr = sprintflags(fdflags, tcp->u_rval);
191 return RVAL_HEX|RVAL_STR;
192 case F_GETFL:
193 tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1);
194 return RVAL_HEX|RVAL_STR;
195 case F_GETLK:
196 tprintf(", ");
197 printflock(tcp, tcp->u_arg[2], 1);
198 break;
199 default:
200 tprintf(", %#lx", tcp->u_arg[2]);
201 break;
202 }
203 }
204 return 0;
205}
206
207#ifdef LOCK_SH
208
209int
210sys_flock(tcp)
211struct tcb *tcp;
212{
213 if (entering(tcp)) {
214 tprintf("%ld, ", tcp->u_arg[0]);
215 if (!printflags(flockcmds, tcp->u_arg[1]))
216 tprintf("LOCK_???");
217 }
218 return 0;
219}
220#endif /* LOCK_SH */
221
222int
223sys_close(tcp)
224struct tcb *tcp;
225{
226 if (entering(tcp)) {
227 tprintf("%ld", tcp->u_arg[0]);
228 }
229 return 0;
230}
231
232int
233sys_dup(tcp)
234struct tcb *tcp;
235{
236 if (entering(tcp)) {
237 tprintf("%ld", tcp->u_arg[0]);
238 }
239 return 0;
240}
241
242int
243sys_dup2(tcp)
244struct tcb *tcp;
245{
246 if (entering(tcp)) {
247 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
248 }
249 return 0;
250}
251
252int
253sys_getdtablesize(tcp)
254struct tcb *tcp;
255{
256 return 0;
257}
258
259static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000260decode_select(tcp, args, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000261struct tcb *tcp;
262long *args;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000263int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000264{
265 int i, j, nfds;
266 fd_set fds;
267 struct timeval tv;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000268#ifdef ALPHA
269 struct timeval32 {
270 unsigned tv_sec;
271 unsigned tv_usec;
272 } *tv32;
273#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000274 static char outstr[1024];
275 char *sep;
276 long arg;
277
278 if (entering(tcp)) {
279 nfds = args[0];
280 tprintf("%d", nfds);
281 for (i = 0; i < 3; i++) {
282 arg = args[i+1];
283 if (arg == 0) {
284 tprintf(", NULL");
285 continue;
286 }
287 if (!verbose(tcp)) {
288 tprintf(", %#lx", arg);
289 continue;
290 }
291 if (umove(tcp, arg, &fds) < 0) {
292 tprintf(", [?]");
293 continue;
294 }
295 tprintf(", [");
296 for (j = 0, sep = ""; j < nfds; j++) {
297 if (FD_ISSET(j, &fds)) {
298 tprintf("%s%u", sep, j);
299 sep = " ";
300 }
301 }
302 tprintf("]");
303 }
304 if (!args[4])
305 tprintf(", NULL");
306 else if (!verbose(tcp))
307 tprintf(", %#lx", args[4]);
308 else if (umove(tcp, args[4], &tv) < 0)
309 tprintf(", {...}");
310 else {
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000311#ifdef ALPHA
312 if (bitness) {
313 tv32=(struct timeval32*)&tv;
Wichert Akkerman221f54f1999-11-18 17:26:45 +0000314 tprintf(", {%u, %u}", tv32->tv_sec, tv32->tv_usec);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000315 } else
316#endif
317 tprintf(", {%lu, %lu}",
318 (long) tv.tv_sec, (long) tv.tv_usec);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000319 }
320 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000321 else
322 {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000323 unsigned int cumlen = 0;
324 char *sep = "";
325
326 if (syserror(tcp))
327 return 0;
328
329 if ((nfds = tcp->u_rval) == 0) {
330 tcp->auxstr = "Timeout";
331 return RVAL_STR;
332 }
333 outstr[0] = '\0';
334 for (i = 0; i < 3; i++) {
335 int first = 1;
336 char str[20];
337
338 tcp->auxstr = outstr;
339 arg = args[i+1];
340 if (!arg || umove(tcp, arg, &fds) < 0)
341 continue;
342 for (j = 0; j < args[0]; j++) {
343 if (FD_ISSET(j, &fds)) {
344 if (first) {
345 sprintf(str, "%s%s [%u", sep,
346 i == 0 ? "in" :
347 i == 1 ? "out" :
348 "except", j);
349 first = 0;
350 sep = ", ";
351 }
352 else
353 sprintf(str, " %u", j);
354 cumlen += strlen(str);
355 if (cumlen < sizeof(outstr))
356 strcat(outstr, str);
357 nfds--;
358 }
359 }
360 if (cumlen)
361 strcat(outstr, "]");
362 if (nfds == 0)
363 break;
364 }
365#ifdef LINUX
366 /* This contains no useful information on SunOS. */
367 if (args[4]) {
368 char str[20];
369
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000370 if (umove(tcp, args[4], &tv) >= 0) {
371#ifdef ALPHA
372 if (bitness) {
373 tv32=(struct timeval32*)&tv;
374 sprintf(str, "%sleft {%u, %u}", sep,
375 tv32->tv_sec, tv32->tv_usec);
376 } else
377#endif
378 sprintf(str, "%sleft {%lu, %lu}", sep,
379 (long) tv.tv_sec, (long) tv.tv_usec);
380
381 if ((cumlen += strlen(str)) < sizeof(outstr))
382 strcat(outstr, str);
383 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000384 }
385#endif /* LINUX */
386 return RVAL_STR;
387 }
388 return 0;
389}
390
391#ifdef LINUX
392
393int
394sys_oldselect(tcp)
395struct tcb *tcp;
396{
397 long args[5];
398
399 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
400 tprintf("[...]");
401 return 0;
402 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000403 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000404}
405
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000406#ifdef ALPHA
407sys_osf_select(tcp)
408struct tcb *tcp;
409{
410 long *args = tcp->u_arg;
411 return decode_select(tcp, args, 1);
412}
413#endif
414
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000415#endif /* LINUX */
416
417int
418sys_select(tcp)
419struct tcb *tcp;
420{
421 long *args = tcp->u_arg;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000422 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000423}