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