blob: e1c43fb1245dcbd1b2c7b1585a95d30b6799ae38 [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
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +000061#ifdef F_SETSIG
62 { F_SETSIG, "F_SETSIG" },
63#endif
64#ifdef F_GETSIG
65 { F_GETSIG, "F_GETSIG" },
66#endif
John Hughesbdf48f52001-03-06 15:08:09 +000067#ifdef F_CHKFL
68 { F_CHKFL, "F_CHKFL" },
69#endif
70#ifdef F_DUP2FD
71 { F_DUP2FD, "F_DUP2FD" },
72#endif
73#ifdef F_ALLOCSP
74 { F_ALLOCSP, "F_ALLOCSP" },
75#endif
76#ifdef F_ISSTREAM
77 { F_ISSTREAM, "F_ISSTREAM" },
78#endif
79#ifdef F_PRIV
80 { F_PRIV, "F_PRIV" },
81#endif
82#ifdef F_NPRIV
83 { F_NPRIV, "F_NPRIV" },
84#endif
85#ifdef F_QUOTACL
86 { F_QUOTACL, "F_QUOTACL" },
87#endif
88#ifdef F_BLOCKS
89 { F_BLOCKS, "F_BLOCKS" },
90#endif
91#ifdef F_BLKSIZE
92 { F_BLKSIZE, "F_BLKSIZE" },
93#endif
94#ifdef F_GETOWN
95 { F_GETOWN, "F_GETOWN" },
96#endif
97#ifdef F_SETOWN
98 { F_SETOWN, "F_SETOWN" },
99#endif
100#ifdef F_REVOKE
101 { F_REVOKE, "F_REVOKE" },
102#endif
103#ifdef F_SETLK
104 { F_SETLK, "F_SETLK" },
105#endif
106#ifdef F_SETLKW
107 { F_SETLKW, "F_SETLKW" },
108#endif
109#ifdef F_FREESP
110 { F_FREESP, "F_FREESP" },
111#endif
112#ifdef F_GETLK
113 { F_GETLK, "F_GETLK" },
114#endif
115#ifdef F_SETLK64
116 { F_SETLK64, "F_SETLK64" },
117#endif
118#ifdef F_SETLKW64
119 { F_SETLKW64, "F_SETLKW64" },
120#endif
121#ifdef F_FREESP64
122 { F_FREESP64, "F_FREESP64" },
123#endif
124#ifdef F_GETLK64
125 { F_GETLK64, "F_GETLK64" },
126#endif
127#ifdef F_SHARE
128 { F_SHARE, "F_SHARE" },
129#endif
130#ifdef F_UNSHARE
131 { F_UNSHARE, "F_UNSHARE" },
132#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000133 { 0, NULL },
134};
135
136static struct xlat fdflags[] = {
137#ifdef FD_CLOEXEC
138 { FD_CLOEXEC, "FD_CLOEXEC" },
139#endif
140 { 0, NULL },
141};
142
143#ifdef LOCK_SH
144
145static struct xlat flockcmds[] = {
146 { LOCK_SH, "LOCK_SH" },
147 { LOCK_EX, "LOCK_EX" },
148 { LOCK_NB, "LOCK_NB" },
149 { LOCK_UN, "LOCK_UN" },
150 { 0, NULL },
151};
152
153#endif /* LOCK_SH */
154
155static struct xlat lockfcmds[] = {
156 { F_RDLCK, "F_RDLCK" },
157 { F_WRLCK, "F_WRLCK" },
158 { F_UNLCK, "F_UNLCK" },
159#ifdef F_EXLCK
160 { F_EXLCK, "F_EXLCK" },
161#endif
162#ifdef F_SHLCK
163 { F_SHLCK, "F_SHLCK" },
164#endif
165 { 0, NULL },
166};
167
168static struct xlat whence[] = {
169 { SEEK_SET, "SEEK_SET" },
170 { SEEK_CUR, "SEEK_CUR" },
171 { SEEK_END, "SEEK_END" },
172 { 0, NULL },
173};
174
175/* fcntl/lockf */
176static void
177printflock(tcp, addr, getlk)
178struct tcb *tcp;
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000179long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000180int getlk;
181{
182 struct flock fl;
183
184 if (umove(tcp, addr, &fl) < 0) {
185 tprintf("{...}");
186 return;
187 }
188 tprintf("{type=");
189 printxval(lockfcmds, fl.l_type, "F_???");
190 tprintf(", whence=");
191 printxval(whence, fl.l_whence, "SEEK_???");
192 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
193 if (getlk)
194 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
195 else
196 tprintf("}");
197}
198
John Hughesbdf48f52001-03-06 15:08:09 +0000199#if _LFS64_LARGEFILE
200/* fcntl/lockf */
201static void
202printflock64(tcp, addr, getlk)
203struct tcb *tcp;
204int addr;
205int getlk;
206{
207 struct flock64 fl;
208
209 if (umove(tcp, addr, &fl) < 0) {
210 tprintf("{...}");
211 return;
212 }
213 tprintf("{type=");
214 printxval(lockfcmds, fl.l_type, "F_???");
215 tprintf(", whence=");
216 printxval(whence, fl.l_whence, "SEEK_???");
217 tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len);
218 if (getlk)
219 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
220 else
221 tprintf("}");
222}
223#endif
224
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000225static char *
226sprintflags(xlat, flags)
227struct xlat *xlat;
228int flags;
229{
230 static char outstr[1024];
231 char *sep;
232
233 strcpy(outstr, "flags ");
234 sep = "";
235 for (; xlat->str; xlat++) {
236 if ((flags & xlat->val) == xlat->val) {
237 sprintf(outstr + strlen(outstr),
238 "%s%s", sep, xlat->str);
239 sep = "|";
240 flags &= ~xlat->val;
241 }
242 }
243 if (flags)
244 sprintf(outstr + strlen(outstr),
245 "%s%#x", sep, flags);
246 return outstr;
247}
248
249int
250sys_fcntl(tcp)
251struct tcb *tcp;
252{
253 extern struct xlat openmodes[];
254
255 if (entering(tcp)) {
256 tprintf("%ld, ", tcp->u_arg[0]);
257 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
258 switch (tcp->u_arg[1]) {
259 case F_SETFD:
260 tprintf(", ");
261 if (printflags(fdflags, tcp->u_arg[2]) == 0)
262 tprintf("0");
263 break;
264 case F_SETOWN: case F_DUPFD:
265 tprintf(", %ld", tcp->u_arg[2]);
266 break;
267 case F_SETFL:
268 tprintf(", ");
269 if (printflags(openmodes, tcp->u_arg[2] + 1) == 0)
270 tprintf("0");
271 break;
272 case F_SETLK: case F_SETLKW:
John Hughesbdf48f52001-03-06 15:08:09 +0000273#ifdef F_FREESP
274 case F_FREESP:
275#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000276 tprintf(", ");
277 printflock(tcp, tcp->u_arg[2], 0);
278 break;
John Hughesbdf48f52001-03-06 15:08:09 +0000279#if _LFS64_LARGEFILE
280#ifdef F_FREESP64
281 case F_FREESP64:
282#endif
283 /* Linux glibc defines SETLK64 as SETLK,
284 even though the kernel has different values - as does Solaris. */
285#if defined(F_SETLK64) && F_SETLK64+0!=F_SETLK
286 case F_SETLK64:
287#endif
288#if defined(F_SETLKW64) && F_SETLKW64+0!=F_SETLKW
289 case F_SETLKW64:
290#endif
291 tprintf(", ");
292 printflock64(tcp, tcp->u_arg[2], 0);
293 break;
294#endif
295 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000296 }
297 else {
298 switch (tcp->u_arg[1]) {
299 case F_DUPFD:
300 case F_SETFD: case F_SETFL:
301 case F_SETLK: case F_SETLKW:
302 case F_SETOWN: case F_GETOWN:
303 break;
304 case F_GETFD:
305 if (tcp->u_rval == 0)
306 return 0;
307 tcp->auxstr = sprintflags(fdflags, tcp->u_rval);
308 return RVAL_HEX|RVAL_STR;
309 case F_GETFL:
310 tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1);
311 return RVAL_HEX|RVAL_STR;
312 case F_GETLK:
313 tprintf(", ");
314 printflock(tcp, tcp->u_arg[2], 1);
315 break;
John Hughesbdf48f52001-03-06 15:08:09 +0000316#if _LFS64_LARGEFILE
317#if defined(F_GETLK64) && F_GETLK64+0!=F_GETLK
318 case F_GETLK64:
319#endif
320 tprintf(", ");
321 printflock64(tcp, tcp->u_arg[2], 1);
322 break;
323#endif
324 default:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000325 tprintf(", %#lx", tcp->u_arg[2]);
326 break;
327 }
328 }
329 return 0;
330}
331
332#ifdef LOCK_SH
333
334int
335sys_flock(tcp)
336struct tcb *tcp;
337{
338 if (entering(tcp)) {
339 tprintf("%ld, ", tcp->u_arg[0]);
340 if (!printflags(flockcmds, tcp->u_arg[1]))
341 tprintf("LOCK_???");
342 }
343 return 0;
344}
345#endif /* LOCK_SH */
346
347int
348sys_close(tcp)
349struct tcb *tcp;
350{
351 if (entering(tcp)) {
352 tprintf("%ld", tcp->u_arg[0]);
353 }
354 return 0;
355}
356
357int
358sys_dup(tcp)
359struct tcb *tcp;
360{
361 if (entering(tcp)) {
362 tprintf("%ld", tcp->u_arg[0]);
363 }
364 return 0;
365}
366
367int
368sys_dup2(tcp)
369struct tcb *tcp;
370{
371 if (entering(tcp)) {
372 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
373 }
374 return 0;
375}
376
377int
378sys_getdtablesize(tcp)
379struct tcb *tcp;
380{
381 return 0;
382}
383
384static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000385decode_select(tcp, args, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000386struct tcb *tcp;
387long *args;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000388int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000389{
390 int i, j, nfds;
391 fd_set fds;
392 struct timeval tv;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000393#ifdef ALPHA
394 struct timeval32 {
395 unsigned tv_sec;
396 unsigned tv_usec;
397 } *tv32;
398#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000399 static char outstr[1024];
400 char *sep;
401 long arg;
402
403 if (entering(tcp)) {
404 nfds = args[0];
405 tprintf("%d", nfds);
406 for (i = 0; i < 3; i++) {
407 arg = args[i+1];
408 if (arg == 0) {
409 tprintf(", NULL");
410 continue;
411 }
412 if (!verbose(tcp)) {
413 tprintf(", %#lx", arg);
414 continue;
415 }
416 if (umove(tcp, arg, &fds) < 0) {
417 tprintf(", [?]");
418 continue;
419 }
420 tprintf(", [");
421 for (j = 0, sep = ""; j < nfds; j++) {
422 if (FD_ISSET(j, &fds)) {
423 tprintf("%s%u", sep, j);
424 sep = " ";
425 }
426 }
427 tprintf("]");
428 }
429 if (!args[4])
430 tprintf(", NULL");
431 else if (!verbose(tcp))
432 tprintf(", %#lx", args[4]);
433 else if (umove(tcp, args[4], &tv) < 0)
434 tprintf(", {...}");
435 else {
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000436#ifdef ALPHA
437 if (bitness) {
438 tv32=(struct timeval32*)&tv;
Wichert Akkerman221f54f1999-11-18 17:26:45 +0000439 tprintf(", {%u, %u}", tv32->tv_sec, tv32->tv_usec);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000440 } else
441#endif
442 tprintf(", {%lu, %lu}",
443 (long) tv.tv_sec, (long) tv.tv_usec);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000444 }
445 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000446 else
447 {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000448 unsigned int cumlen = 0;
449 char *sep = "";
450
451 if (syserror(tcp))
452 return 0;
453
454 if ((nfds = tcp->u_rval) == 0) {
455 tcp->auxstr = "Timeout";
456 return RVAL_STR;
457 }
458 outstr[0] = '\0';
459 for (i = 0; i < 3; i++) {
460 int first = 1;
461 char str[20];
462
463 tcp->auxstr = outstr;
464 arg = args[i+1];
465 if (!arg || umove(tcp, arg, &fds) < 0)
466 continue;
467 for (j = 0; j < args[0]; j++) {
468 if (FD_ISSET(j, &fds)) {
469 if (first) {
470 sprintf(str, "%s%s [%u", sep,
471 i == 0 ? "in" :
472 i == 1 ? "out" :
473 "except", j);
474 first = 0;
475 sep = ", ";
476 }
477 else
478 sprintf(str, " %u", j);
479 cumlen += strlen(str);
480 if (cumlen < sizeof(outstr))
481 strcat(outstr, str);
482 nfds--;
483 }
484 }
485 if (cumlen)
486 strcat(outstr, "]");
487 if (nfds == 0)
488 break;
489 }
490#ifdef LINUX
491 /* This contains no useful information on SunOS. */
492 if (args[4]) {
493 char str[20];
494
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000495 if (umove(tcp, args[4], &tv) >= 0) {
496#ifdef ALPHA
497 if (bitness) {
498 tv32=(struct timeval32*)&tv;
499 sprintf(str, "%sleft {%u, %u}", sep,
500 tv32->tv_sec, tv32->tv_usec);
501 } else
502#endif
503 sprintf(str, "%sleft {%lu, %lu}", sep,
504 (long) tv.tv_sec, (long) tv.tv_usec);
505
506 if ((cumlen += strlen(str)) < sizeof(outstr))
507 strcat(outstr, str);
508 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000509 }
510#endif /* LINUX */
511 return RVAL_STR;
512 }
513 return 0;
514}
515
516#ifdef LINUX
517
518int
519sys_oldselect(tcp)
520struct tcb *tcp;
521{
522 long args[5];
523
524 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
525 tprintf("[...]");
526 return 0;
527 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000528 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000529}
530
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000531#ifdef ALPHA
532sys_osf_select(tcp)
533struct tcb *tcp;
534{
535 long *args = tcp->u_arg;
536 return decode_select(tcp, args, 1);
537}
538#endif
539
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000540#endif /* LINUX */
541
542int
543sys_select(tcp)
544struct tcb *tcp;
545{
546 long *args = tcp->u_arg;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000547 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000548}