blob: 3b76e7eaa9a9f752d21f14cb85fb0f29f56f6bc1 [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
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000259decode_select(tcp, args, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000260struct tcb *tcp;
261long *args;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000262int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000263{
264 int i, j, nfds;
265 fd_set fds;
266 struct timeval tv;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000267#ifdef ALPHA
268 struct timeval32 {
269 unsigned tv_sec;
270 unsigned tv_usec;
271 } *tv32;
272#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000273 static char outstr[1024];
274 char *sep;
275 long arg;
276
277 if (entering(tcp)) {
278 nfds = args[0];
279 tprintf("%d", nfds);
280 for (i = 0; i < 3; i++) {
281 arg = args[i+1];
282 if (arg == 0) {
283 tprintf(", NULL");
284 continue;
285 }
286 if (!verbose(tcp)) {
287 tprintf(", %#lx", arg);
288 continue;
289 }
290 if (umove(tcp, arg, &fds) < 0) {
291 tprintf(", [?]");
292 continue;
293 }
294 tprintf(", [");
295 for (j = 0, sep = ""; j < nfds; j++) {
296 if (FD_ISSET(j, &fds)) {
297 tprintf("%s%u", sep, j);
298 sep = " ";
299 }
300 }
301 tprintf("]");
302 }
303 if (!args[4])
304 tprintf(", NULL");
305 else if (!verbose(tcp))
306 tprintf(", %#lx", args[4]);
307 else if (umove(tcp, args[4], &tv) < 0)
308 tprintf(", {...}");
309 else {
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000310#ifdef ALPHA
311 if (bitness) {
312 tv32=(struct timeval32*)&tv;
Wichert Akkerman221f54f1999-11-18 17:26:45 +0000313 tprintf(", {%u, %u}", tv32->tv_sec, tv32->tv_usec);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000314 } else
315#endif
316 tprintf(", {%lu, %lu}",
317 (long) tv.tv_sec, (long) tv.tv_usec);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000318 }
319 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000320 else
321 {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000322 unsigned int cumlen = 0;
323 char *sep = "";
324
325 if (syserror(tcp))
326 return 0;
327
328 if ((nfds = tcp->u_rval) == 0) {
329 tcp->auxstr = "Timeout";
330 return RVAL_STR;
331 }
332 outstr[0] = '\0';
333 for (i = 0; i < 3; i++) {
334 int first = 1;
335 char str[20];
336
337 tcp->auxstr = outstr;
338 arg = args[i+1];
339 if (!arg || umove(tcp, arg, &fds) < 0)
340 continue;
341 for (j = 0; j < args[0]; j++) {
342 if (FD_ISSET(j, &fds)) {
343 if (first) {
344 sprintf(str, "%s%s [%u", sep,
345 i == 0 ? "in" :
346 i == 1 ? "out" :
347 "except", j);
348 first = 0;
349 sep = ", ";
350 }
351 else
352 sprintf(str, " %u", j);
353 cumlen += strlen(str);
354 if (cumlen < sizeof(outstr))
355 strcat(outstr, str);
356 nfds--;
357 }
358 }
359 if (cumlen)
360 strcat(outstr, "]");
361 if (nfds == 0)
362 break;
363 }
364#ifdef LINUX
365 /* This contains no useful information on SunOS. */
366 if (args[4]) {
367 char str[20];
368
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000369 if (umove(tcp, args[4], &tv) >= 0) {
370#ifdef ALPHA
371 if (bitness) {
372 tv32=(struct timeval32*)&tv;
373 sprintf(str, "%sleft {%u, %u}", sep,
374 tv32->tv_sec, tv32->tv_usec);
375 } else
376#endif
377 sprintf(str, "%sleft {%lu, %lu}", sep,
378 (long) tv.tv_sec, (long) tv.tv_usec);
379
380 if ((cumlen += strlen(str)) < sizeof(outstr))
381 strcat(outstr, str);
382 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000383 }
384#endif /* LINUX */
385 return RVAL_STR;
386 }
387 return 0;
388}
389
390#ifdef LINUX
391
392int
393sys_oldselect(tcp)
394struct tcb *tcp;
395{
396 long args[5];
397
398 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
399 tprintf("[...]");
400 return 0;
401 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000402 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000403}
404
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000405#ifdef ALPHA
406sys_osf_select(tcp)
407struct tcb *tcp;
408{
409 long *args = tcp->u_arg;
410 return decode_select(tcp, args, 1);
411}
412#endif
413
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000414#endif /* LINUX */
415
416int
417sys_select(tcp)
418struct tcb *tcp;
419{
420 long *args = tcp->u_arg;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000421 return decode_select(tcp, args, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000422}