blob: 9040ebfe6611ec63d45b1a05e037b096cf2c87a8 [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 <dirent.h>
35
Wichert Akkerman328c5e71999-04-16 00:21:26 +000036#ifdef linux
Wichert Akkerman25d0c4f1999-04-18 19:35:42 +000037#define stat libc_stat
38#include <statbuf.h>
39#undef stat
Wichert Akkerman328c5e71999-04-16 00:21:26 +000040#include <asm/stat.h>
41#endif
Wichert Akkerman25d0c4f1999-04-18 19:35:42 +000042#include <sys/stat.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000043#include <fcntl.h>
44
45#ifdef SVR4
46# include <sys/cred.h>
47#endif /* SVR4 */
48
49#include <sys/vfs.h>
50
51#ifdef MAJOR_IN_SYSMACROS
52#include <sys/sysmacros.h>
53#endif
54
55#ifdef MAJOR_IN_MKDEV
56#include <sys/mkdev.h>
57#endif
58
59#ifdef HAVE_SYS_ASYNCH_H
60#include <sys/asynch.h>
61#endif
62
63#ifdef SUNOS4
64#include <ustat.h>
65#endif
66
67/*
68 * This is a really dirty trick but it should always work. Traditional
69 * Unix says r/w/rw are 0/1/2, so we make them true flags 1/2/3 by
70 * adding 1. Just remember to add 1 to any arg decoded with openmodes.
71 */
72struct xlat openmodes[] = {
73 { O_RDWR+1, "O_RDWR" },
74 { O_RDONLY+1, "O_RDONLY" },
75 { O_WRONLY+1, "O_WRONLY" },
76 { O_NONBLOCK, "O_NONBLOCK" },
77 { O_APPEND, "O_APPEND" },
78 { O_CREAT, "O_CREAT" },
79 { O_TRUNC, "O_TRUNC" },
80 { O_EXCL, "O_EXCL" },
81 { O_NOCTTY, "O_NOCTTY" },
82#ifdef O_SYNC
83 { O_SYNC, "O_SYNC" },
84#endif
85#ifdef O_ASYNC
86 { O_ASYNC, "O_ASYNC" },
87#endif
88#ifdef O_DSYNC
89 { O_DSYNC, "O_DSYNC" },
90#endif
91#ifdef O_RSYNC
92 { O_RSYNC, "O_RSYNC" },
93#endif
94#ifdef O_NDELAY
95 { O_NDELAY, "O_NDELAY" },
96#endif
97#ifdef O_PRIV
98 { O_PRIV, "O_PRIV" },
99#endif
100#ifdef O_DIRECT
101 { O_DIRECT, "O_DIRECT" },
102#endif
103#ifdef O_LARGEFILE
104 { O_LARGEFILE, "O_LARGEFILE" },
105#endif
106#ifdef O_DIRECTORY
107 { O_DIRECTORY, "O_DIRECTORY" },
108#endif
109
110#ifdef FNDELAY
111 { FNDELAY, "FNDELAY" },
112#endif
113#ifdef FAPPEND
114 { FAPPEND, "FAPPEND" },
115#endif
116#ifdef FMARK
117 { FMARK, "FMARK" },
118#endif
119#ifdef FDEFER
120 { FDEFER, "FDEFER" },
121#endif
122#ifdef FASYNC
123 { FASYNC, "FASYNC" },
124#endif
125#ifdef FSHLOCK
126 { FSHLOCK, "FSHLOCK" },
127#endif
128#ifdef FEXLOCK
129 { FEXLOCK, "FEXLOCK" },
130#endif
131#ifdef FCREAT
132 { FCREAT, "FCREAT" },
133#endif
134#ifdef FTRUNC
135 { FTRUNC, "FTRUNC" },
136#endif
137#ifdef FEXCL
138 { FEXCL, "FEXCL" },
139#endif
140#ifdef FNBIO
141 { FNBIO, "FNBIO" },
142#endif
143#ifdef FSYNC
144 { FSYNC, "FSYNC" },
145#endif
146#ifdef FNOCTTY
147 { FNOCTTY, "FNOCTTY" },
148#endif
149 { 0, NULL },
150};
151
152int
153sys_open(tcp)
154struct tcb *tcp;
155{
156 if (entering(tcp)) {
157 printpath(tcp, tcp->u_arg[0]);
158 tprintf(", ");
159 /* flags */
160 printflags(openmodes, tcp->u_arg[1] + 1);
161 if (tcp->u_arg[1] & O_CREAT) {
162 /* mode */
163 tprintf(", %#lo", tcp->u_arg[2]);
164 }
165 }
166 return 0;
167}
168
169#ifdef LINUXSPARC
170struct xlat openmodessol[] = {
171 { 0, "O_RDWR" },
172 { 1, "O_RDONLY" },
173 { 2, "O_WRONLY" },
174 { 0x80, "O_NONBLOCK" },
175 { 8, "O_APPEND" },
176 { 0x100, "O_CREAT" },
177 { 0x200, "O_TRUNC" },
178 { 0x400, "O_EXCL" },
179 { 0x800, "O_NOCTTY" },
180 { 0x10, "O_SYNC" },
181 { 0x40, "O_DSYNC" },
182 { 0x8000, "O_RSYNC" },
183 { 4, "O_NDELAY" },
184 { 0x1000, "O_PRIV" },
185 { 0, NULL },
186};
187
188int
189solaris_open(tcp)
190struct tcb *tcp;
191{
192 if (entering(tcp)) {
193 printpath(tcp, tcp->u_arg[0]);
194 tprintf(", ");
195 /* flags */
196 printflags(openmodessol, tcp->u_arg[1] + 1);
197 if (tcp->u_arg[1] & 0x100) {
198 /* mode */
199 tprintf(", %#lo", tcp->u_arg[2]);
200 }
201 }
202 return 0;
203}
204
205#endif
206
207int
208sys_creat(tcp)
209struct tcb *tcp;
210{
211 if (entering(tcp)) {
212 printpath(tcp, tcp->u_arg[0]);
213 tprintf(", %#lo", tcp->u_arg[1]);
214 }
215 return 0;
216}
217
218static struct xlat access_flags[] = {
219 { F_OK, "F_OK", },
220 { R_OK, "R_OK" },
221 { W_OK, "W_OK" },
222 { X_OK, "X_OK" },
223#ifdef EFF_ONLY_OK
224 { EFF_ONLY_OK, "EFF_ONLY_OK" },
225#endif
226#ifdef EX_OK
227 { EX_OK, "EX_OK" },
228#endif
229 { 0, NULL },
230};
231
232int
233sys_access(tcp)
234struct tcb *tcp;
235{
236 if (entering(tcp)) {
237 printpath(tcp, tcp->u_arg[0]);
238 tprintf(", ");
239 printflags(access_flags, tcp->u_arg[1]);
240 }
241 return 0;
242}
243
244int
245sys_umask(tcp)
246struct tcb *tcp;
247{
248 if (entering(tcp)) {
249 tprintf("%#lo", tcp->u_arg[0]);
250 }
251 return RVAL_OCTAL;
252}
253
254static struct xlat whence[] = {
255 { SEEK_SET, "SEEK_SET" },
256 { SEEK_CUR, "SEEK_CUR" },
257 { SEEK_END, "SEEK_END" },
258 { 0, NULL },
259};
260
261int
262sys_lseek(tcp)
263struct tcb *tcp;
264{
265 if (entering(tcp)) {
266 tprintf("%ld, ", tcp->u_arg[0]);
267 if (tcp->u_arg[2] == SEEK_SET)
268 tprintf("%lu, ", tcp->u_arg[1]);
269 else
270 tprintf("%ld, ", tcp->u_arg[1]);
271 printxval(whence, tcp->u_arg[2], "SEEK_???");
272 }
273 return RVAL_UDECIMAL;
274}
275
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000276#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000277int
278sys_llseek (tcp)
279struct tcb *tcp;
280{
281 if (entering(tcp)) {
282 if (tcp->u_arg[4] == SEEK_SET)
283 tprintf("%ld, %llu, ", tcp->u_arg[0],
284 (((unsigned long long int) tcp->u_arg[1]) << 32
285 | (unsigned long) tcp->u_arg[2]));
286 else
287 tprintf("%ld, %lld, ", tcp->u_arg[0],
288 (((long long int) tcp->u_arg[1]) << 32
289 | (unsigned long) tcp->u_arg[2]));
290 }
291 else {
292 if (syserror(tcp))
293 tprintf("%#lx, ", tcp->u_arg[3]);
294 else {
295 long long int off;
296 umove(tcp, tcp->u_arg[3], &off);
297 tprintf("{%lld}, ", off);
298 }
299 printxval(whence, tcp->u_arg[4], "SEEK_???");
300 }
301 return 0;
302}
303#endif
304
305int
306sys_truncate(tcp)
307struct tcb *tcp;
308{
309 if (entering(tcp)) {
310 printpath(tcp, tcp->u_arg[0]);
311 tprintf(", %lu", tcp->u_arg[1]);
312 }
313 return 0;
314}
315
316int
317sys_ftruncate(tcp)
318struct tcb *tcp;
319{
320 if (entering(tcp)) {
321 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
322 }
323 return 0;
324}
325
326/* several stats */
327
328static struct xlat modetypes[] = {
329 { S_IFREG, "S_IFREG" },
330 { S_IFSOCK, "S_IFSOCK" },
331 { S_IFIFO, "S_IFIFO" },
332 { S_IFLNK, "S_IFLNK" },
333 { S_IFDIR, "S_IFDIR" },
334 { S_IFBLK, "S_IFBLK" },
335 { S_IFCHR, "S_IFCHR" },
336 { 0, NULL },
337};
338
339static char *
340sprintmode(mode)
341int mode;
342{
343 static char buf[64];
344 char *s;
345
346 if ((mode & S_IFMT) == 0)
347 s = "";
348 else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
349 sprintf(buf, "%#o", mode);
350 return buf;
351 }
352 sprintf(buf, "%s%s%s%s", s,
353 (mode & S_ISUID) ? "|S_ISUID" : "",
354 (mode & S_ISGID) ? "|S_ISGID" : "",
355 (mode & S_ISVTX) ? "|S_ISVTX" : "");
356 mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
357 if (mode)
358 sprintf(buf + strlen(buf), "|%#o", mode);
359 s = (*buf == '|') ? buf + 1 : buf;
360 return *s ? s : "0";
361}
362
363static char *
364sprinttime(t)
365time_t t;
366{
367 struct tm *tmp;
368 static char buf[32];
369
370 if (t == 0) {
371 sprintf(buf, "0");
372 return buf;
373 }
374 tmp = localtime(&t);
375 sprintf(buf, "%02d/%02d/%02d-%02d:%02d:%02d",
376 tmp->tm_year, tmp->tm_mon + 1, tmp->tm_mday,
377 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
378 return buf;
379}
380
381#ifdef LINUXSPARC
382typedef struct {
383 int tv_sec;
384 int tv_nsec;
385} timestruct_t;
386
387struct solstat {
388 unsigned st_dev;
389 int st_pad1[3]; /* network id */
390 unsigned st_ino;
391 unsigned st_mode;
392 unsigned st_nlink;
393 unsigned st_uid;
394 unsigned st_gid;
395 unsigned st_rdev;
396 int st_pad2[2];
397 int st_size;
398 int st_pad3; /* st_size, off_t expansion */
399 timestruct_t st_atime;
400 timestruct_t st_mtime;
401 timestruct_t st_ctime;
402 int st_blksize;
403 int st_blocks;
404 char st_fstype[16];
405 int st_pad4[8]; /* expansion area */
406};
407
408static void
409printstatsol(tcp, addr)
410struct tcb *tcp;
411int addr;
412{
413 struct solstat statbuf;
414
415 if (!addr) {
416 tprintf("NULL");
417 return;
418 }
419 if (syserror(tcp) || !verbose(tcp)) {
420 tprintf("%#x", addr);
421 return;
422 }
423 if (umove(tcp, addr, &statbuf) < 0) {
424 tprintf("{...}");
425 return;
426 }
427 if (!abbrev(tcp)) {
428 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
429 (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
430 (unsigned long) (statbuf.st_dev & 0x3ffff),
431 (unsigned long) statbuf.st_ino,
432 sprintmode(statbuf.st_mode));
433 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
434 (unsigned long) statbuf.st_nlink,
435 (unsigned long) statbuf.st_uid,
436 (unsigned long) statbuf.st_gid);
437 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
438 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
439 }
440 else
441 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
442 switch (statbuf.st_mode & S_IFMT) {
443 case S_IFCHR: case S_IFBLK:
444 tprintf("st_rdev=makedev(%lu, %lu), ",
445 (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
446 (unsigned long) (statbuf.st_rdev & 0x3ffff));
447 break;
448 default:
449 tprintf("st_size=%u, ", statbuf.st_size);
450 break;
451 }
452 if (!abbrev(tcp)) {
453 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
454 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
455 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
456 }
457 else
458 tprintf("...}");
459}
Wichert Akkermanb859bea1999-04-18 22:50:50 +0000460#endif /* LINUXSPARC */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000461
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000462static void
463realprintstat(tcp, statbuf)
464struct tcb *tcp;
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000465struct stat *statbuf;
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000466{
467 if (!abbrev(tcp)) {
468 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
469 (unsigned long) major(statbuf->st_dev),
470 (unsigned long) minor(statbuf->st_dev),
471 (unsigned long) statbuf->st_ino,
472 sprintmode(statbuf->st_mode));
473 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
474 (unsigned long) statbuf->st_nlink,
475 (unsigned long) statbuf->st_uid,
476 (unsigned long) statbuf->st_gid);
477#ifdef HAVE_ST_BLKSIZE
478 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
479#endif /* HAVE_ST_BLKSIZE */
480#ifdef HAVE_ST_BLOCKS
481 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
482#endif /* HAVE_ST_BLOCKS */
483 }
484 else
485 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
486 switch (statbuf->st_mode & S_IFMT) {
487 case S_IFCHR: case S_IFBLK:
488#ifdef HAVE_ST_RDEV
489 tprintf("st_rdev=makedev(%lu, %lu), ",
490 (unsigned long) major(statbuf->st_rdev),
491 (unsigned long) minor(statbuf->st_rdev));
492#else /* !HAVE_ST_RDEV */
493 tprintf("st_size=makedev(%lu, %lu), ",
494 (unsigned long) major(statbuf->st_size),
495 (unsigned long) minor(statbuf->st_size));
496#endif /* !HAVE_ST_RDEV */
497 break;
498 default:
499 tprintf("st_size=%lu, ", statbuf->st_size);
500 break;
501 }
502 if (!abbrev(tcp)) {
503 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
504 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
505 tprintf("st_ctime=%s}", sprinttime(statbuf->st_ctime));
506 }
507 else
508 tprintf("...}");
509}
510
Nate Sammons771a6ff1999-04-05 22:39:31 +0000511
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000512static void
513printstat(tcp, addr)
514struct tcb *tcp;
515int addr;
516{
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000517 struct stat statbuf;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000518
519#ifdef LINUXSPARC
520 if (current_personality == 1) {
521 printstatsol(tcp, addr);
522 return;
523 }
524#endif /* LINUXSPARC */
525
526 if (!addr) {
527 tprintf("NULL");
528 return;
529 }
530 if (syserror(tcp) || !verbose(tcp)) {
531 tprintf("%#x", addr);
532 return;
533 }
534 if (umove(tcp, addr, &statbuf) < 0) {
535 tprintf("{...}");
536 return;
537 }
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000538
539 realprintstat(tcp, &statbuf);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000540}
541
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000542#ifdef linux
543static void
544convertoldstat(oldbuf, newbuf)
Wichert Akkerman25d0c4f1999-04-18 19:35:42 +0000545const struct __old_kernel_stat *oldbuf;
546struct stat *newbuf;
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000547{
548 newbuf->st_dev=oldbuf->st_dev;
549 newbuf->st_ino=oldbuf->st_ino;
550 newbuf->st_mode=oldbuf->st_mode;
551 newbuf->st_nlink=oldbuf->st_nlink;
552 newbuf->st_uid=oldbuf->st_uid;
553 newbuf->st_gid=oldbuf->st_gid;
554 newbuf->st_rdev=oldbuf->st_rdev;
555 newbuf->st_size=oldbuf->st_size;
556 newbuf->st_atime=oldbuf->st_atime;
557 newbuf->st_mtime=oldbuf->st_mtime;
558 newbuf->st_ctime=oldbuf->st_ctime;
559 newbuf->st_blksize=0; /* not supported in old_stat */
560 newbuf->st_blocks=0; /* not supported in old_stat */
561}
562#endif
563
564
565#ifdef linux
566static void
567printoldstat(tcp, addr)
568struct tcb *tcp;
569int addr;
570{
Wichert Akkerman25d0c4f1999-04-18 19:35:42 +0000571 struct __old_kernel_stat statbuf;
572 struct stat newstatbuf;
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000573
574#ifdef LINUXSPARC
575 if (current_personality == 1) {
576 printstatsol(tcp, addr);
577 return;
578 }
579#endif /* LINUXSPARC */
580
581 if (!addr) {
582 tprintf("NULL");
583 return;
584 }
585 if (syserror(tcp) || !verbose(tcp)) {
586 tprintf("%#x", addr);
587 return;
588 }
589 if (umove(tcp, addr, &statbuf) < 0) {
590 tprintf("{...}");
591 return;
592 }
593
594 convertoldstat(&statbuf, &newstatbuf);
595 realprintstat(tcp, &newstatbuf);
596}
597#endif
598
599
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000600int
601sys_stat(tcp)
602struct tcb *tcp;
603{
604 if (entering(tcp)) {
605 printpath(tcp, tcp->u_arg[0]);
606 tprintf(", ");
607 } else {
608 printstat(tcp, tcp->u_arg[1]);
609 }
610 return 0;
611}
612
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000613#ifdef linux
614int
615sys_oldstat(tcp)
616struct tcb *tcp;
617{
618 if (entering(tcp)) {
619 printpath(tcp, tcp->u_arg[0]);
620 tprintf(", ");
621 } else {
622 printoldstat(tcp, tcp->u_arg[1]);
623 }
624 return 0;
625}
626#endif
627
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000628int
629sys_fstat(tcp)
630struct tcb *tcp;
631{
632 if (entering(tcp))
633 tprintf("%ld, ", tcp->u_arg[0]);
634 else {
635 printstat(tcp, tcp->u_arg[1]);
636 }
637 return 0;
638}
639
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000640#ifdef linux
641int
642sys_oldfstat(tcp)
643struct tcb *tcp;
644{
645 if (entering(tcp))
646 tprintf("%ld, ", tcp->u_arg[0]);
647 else {
648 printoldstat(tcp, tcp->u_arg[1]);
649 }
650 return 0;
651}
652#endif
653
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000654int
655sys_lstat(tcp)
656struct tcb *tcp;
657{
658 if (entering(tcp)) {
659 printpath(tcp, tcp->u_arg[0]);
660 tprintf(", ");
661 } else {
662 printstat(tcp, tcp->u_arg[1]);
663 }
664 return 0;
665}
666
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000667#ifdef linux
668int
669sys_oldlstat(tcp)
670struct tcb *tcp;
671{
672 if (entering(tcp)) {
673 printpath(tcp, tcp->u_arg[0]);
674 tprintf(", ");
675 } else {
676 printoldstat(tcp, tcp->u_arg[1]);
677 }
678 return 0;
679}
680#endif
681
682
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000683#if defined(SVR4) || defined(LINUXSPARC)
684
685int
686sys_xstat(tcp)
687struct tcb *tcp;
688{
689 if (entering(tcp)) {
690 tprintf("%ld, ", tcp->u_arg[0]);
691 printpath(tcp, tcp->u_arg[1]);
692 tprintf(", ");
693 } else {
694 printstat(tcp, tcp->u_arg[2]);
695 }
696 return 0;
697}
698
699int
700sys_fxstat(tcp)
701struct tcb *tcp;
702{
703 if (entering(tcp))
704 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
705 else {
706 printstat(tcp, tcp->u_arg[2]);
707 }
708 return 0;
709}
710
711int
712sys_lxstat(tcp)
713struct tcb *tcp;
714{
715 if (entering(tcp)) {
716 tprintf("%ld, ", tcp->u_arg[0]);
717 printpath(tcp, tcp->u_arg[1]);
718 tprintf(", ");
719 } else {
720 printstat(tcp, tcp->u_arg[2]);
721 }
722 return 0;
723}
724
725int
726sys_xmknod(tcp)
727struct tcb *tcp;
728{
729 int mode = tcp->u_arg[2];
730
731 if (entering(tcp)) {
732 tprintf("%ld, ", tcp->u_arg[0]);
733 printpath(tcp, tcp->u_arg[1]);
734 tprintf(", %s", sprintmode(mode));
735 switch (mode & S_IFMT) {
736 case S_IFCHR: case S_IFBLK:
737#ifdef LINUXSPARC
738 tprintf(", makedev(%lu, %lu)",
739 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
740 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
741#else
742 tprintf(", makedev(%lu, %lu)",
743 (unsigned long) major(tcp->u_arg[3]),
744 (unsigned long) minor(tcp->u_arg[3]));
745#endif
746 break;
747 default:
748 break;
749 }
750 }
751 return 0;
752}
753
754#endif /* SVR4 || LINUXSPARC */
755
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000756#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000757
758static struct xlat fsmagic[] = {
759 { 0xef51, "EXT2_OLD_SUPER_MAGIC" },
760 { 0xef53, "EXT2_SUPER_MAGIC" },
761 { 0x137d, "EXT_SUPER_MAGIC" },
762 { 0x9660, "ISOFS_SUPER_MAGIC" },
763 { 0x137f, "MINIX_SUPER_MAGIC" },
764 { 0x138f, "MINIX_SUPER_MAGIC2" },
765 { 0x2468, "NEW_MINIX_SUPER_MAGIC" },
766 { 0x4d44, "MSDOS_SUPER_MAGIC" },
767 { 0x6969, "NFS_SUPER_MAGIC" },
768 { 0x9fa0, "PROC_SUPER_MAGIC" },
769 { 0x012fd16d, "XIAFS_SUPER_MAGIC" },
770 { 0, NULL },
771};
772
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000773#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000774
775#ifndef SVR4
776
777static char *
778sprintfstype(magic)
779int magic;
780{
781 static char buf[32];
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000782#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000783 char *s;
784
785 s = xlookup(fsmagic, magic);
786 if (s) {
787 sprintf(buf, "\"%s\"", s);
788 return buf;
789 }
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000790#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000791 sprintf(buf, "%#x", magic);
792 return buf;
793}
794
795static void
796printstatfs(tcp, addr)
797struct tcb *tcp;
798long addr;
799{
800 struct statfs statbuf;
801
802 if (syserror(tcp) || !verbose(tcp)) {
803 tprintf("%#lx", addr);
804 return;
805 }
806 if (umove(tcp, addr, &statbuf) < 0) {
807 tprintf("{...}");
808 return;
809 }
810#ifdef ALPHA
811
812 tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
813 sprintfstype(statbuf.f_type),
814 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
815 tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_namelen=%u}",
816 statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, statbuf.f_namelen);
817#else /* !ALPHA */
818 tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
819 sprintfstype(statbuf.f_type),
Nate Sammons5c74d201999-04-06 01:37:51 +0000820 (unsigned long)statbuf.f_bsize,
821 (unsigned long)statbuf.f_blocks,
822 (unsigned long)statbuf.f_bfree);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000823 tprintf("f_files=%lu, f_ffree=%lu",
Nate Sammons5c74d201999-04-06 01:37:51 +0000824 (unsigned long)statbuf.f_files,
825 (unsigned long)statbuf.f_ffree);
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000826#ifdef linux
Nate Sammons5c74d201999-04-06 01:37:51 +0000827 tprintf(", f_namelen=%lu}", (unsigned long)statbuf.f_namelen);
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000828#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000829#endif /* !ALPHA */
830 tprintf("}");
831}
832
833int
834sys_statfs(tcp)
835struct tcb *tcp;
836{
837 if (entering(tcp)) {
838 printpath(tcp, tcp->u_arg[0]);
839 tprintf(", ");
840 } else {
841 printstatfs(tcp, tcp->u_arg[1]);
842 }
843 return 0;
844}
845
846int
847sys_fstatfs(tcp)
848struct tcb *tcp;
849{
850 if (entering(tcp)) {
851 tprintf("%lu, ", tcp->u_arg[0]);
852 } else {
853 printstatfs(tcp, tcp->u_arg[1]);
854 }
855 return 0;
856}
857
Wichert Akkermana0f36c61999-04-16 14:01:34 +0000858#if defined(linux) && defined(__alpha)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000859
860int
861osf_statfs(tcp)
862struct tcb *tcp;
863{
864 if (entering(tcp)) {
865 printpath(tcp, tcp->u_arg[0]);
866 tprintf(", ");
867 } else {
868 printstatfs(tcp, tcp->u_arg[1]);
869 tprintf(", %lu", tcp->u_arg[2]);
870 }
871 return 0;
872}
873
874int
875osf_fstatfs(tcp)
876struct tcb *tcp;
877{
878 if (entering(tcp)) {
879 tprintf("%lu, ", tcp->u_arg[0]);
880 } else {
881 printstatfs(tcp, tcp->u_arg[1]);
882 tprintf(", %lu", tcp->u_arg[2]);
883 }
884 return 0;
885}
Wichert Akkermana0f36c61999-04-16 14:01:34 +0000886#endif /* linux && __alpha */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000887
888#endif /* !SVR4 */
889
890#ifdef SUNOS4
891
892int
893sys_ustat(tcp)
894struct tcb *tcp;
895{
896 struct ustat statbuf;
897
898 if (entering(tcp)) {
899 tprintf("makedev(%lu, %lu), ",
900 (long) major(tcp->u_arg[0]),
901 (long) minor(tcp->u_arg[0]));
902 }
903 else {
904 if (syserror(tcp) || !verbose(tcp))
905 tprintf("%#lx", tcp->u_arg[1]);
906 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
907 tprintf("{...}");
908 else {
909 tprintf("{f_tfree=%lu, f_tinode=%lu, ",
910 statbuf.f_tfree, statbuf.f_tinode);
911 tprintf("f_fname=\"%.*s\", ",
912 (int) sizeof(statbuf.f_fname),
913 statbuf.f_fname);
914 tprintf("f_fpack=\"%.*s\"}",
915 (int) sizeof(statbuf.f_fpack),
916 statbuf.f_fpack);
917 }
918 }
919 return 0;
920}
921
922#endif /* SUNOS4 */
923
924/* directory */
925int
926sys_chdir(tcp)
927struct tcb *tcp;
928{
929 if (entering(tcp)) {
930 printpath(tcp, tcp->u_arg[0]);
931 }
932 return 0;
933}
934
935int
936sys_mkdir(tcp)
937struct tcb *tcp;
938{
939 if (entering(tcp)) {
940 printpath(tcp, tcp->u_arg[0]);
941 tprintf(", %#lo", tcp->u_arg[1]);
942 }
943 return 0;
944}
945
946int
947sys_rmdir(tcp)
948struct tcb *tcp;
949{
950 if (entering(tcp)) {
951 printpath(tcp, tcp->u_arg[0]);
952 }
953 return 0;
954}
955
956int
957sys_fchdir(tcp)
958struct tcb *tcp;
959{
960 if (entering(tcp)) {
961 tprintf("%ld", tcp->u_arg[0]);
962 }
963 return 0;
964}
965
966int
967sys_chroot(tcp)
968struct tcb *tcp;
969{
970 if (entering(tcp)) {
971 printpath(tcp, tcp->u_arg[0]);
972 }
973 return 0;
974}
975
976int
977sys_fchroot(tcp)
978struct tcb *tcp;
979{
980 if (entering(tcp)) {
981 tprintf("%ld", tcp->u_arg[0]);
982 }
983 return 0;
984}
985
986int
987sys_link(tcp)
988struct tcb *tcp;
989{
990 if (entering(tcp)) {
991 printpath(tcp, tcp->u_arg[0]);
992 tprintf(", ");
993 printpath(tcp, tcp->u_arg[1]);
994 }
995 return 0;
996}
997
998int
999sys_unlink(tcp)
1000struct tcb *tcp;
1001{
1002 if (entering(tcp)) {
1003 printpath(tcp, tcp->u_arg[0]);
1004 }
1005 return 0;
1006}
1007
1008int
1009sys_symlink(tcp)
1010struct tcb *tcp;
1011{
1012 if (entering(tcp)) {
1013 printpath(tcp, tcp->u_arg[0]);
1014 tprintf(", ");
1015 printpath(tcp, tcp->u_arg[1]);
1016 }
1017 return 0;
1018}
1019
1020int
1021sys_readlink(tcp)
1022struct tcb *tcp;
1023{
1024 if (entering(tcp)) {
1025 printpath(tcp, tcp->u_arg[0]);
1026 tprintf(", ");
1027 } else {
1028 if (syserror(tcp))
1029 tprintf("%#lx", tcp->u_arg[1]);
1030 else
1031 printpathn(tcp, tcp->u_arg[1], tcp->u_rval);
1032 tprintf(", %lu", tcp->u_arg[2]);
1033 }
1034 return 0;
1035}
1036
1037int
1038sys_rename(tcp)
1039struct tcb *tcp;
1040{
1041 if (entering(tcp)) {
1042 printpath(tcp, tcp->u_arg[0]);
1043 tprintf(", ");
1044 printpath(tcp, tcp->u_arg[1]);
1045 }
1046 return 0;
1047}
1048
1049int
1050sys_chown(tcp)
1051struct tcb *tcp;
1052{
1053 if (entering(tcp)) {
1054 printpath(tcp, tcp->u_arg[0]);
1055 tprintf(", %lu, %lu", tcp->u_arg[1], tcp->u_arg[2]);
1056 }
1057 return 0;
1058}
1059
1060int
1061sys_fchown(tcp)
1062struct tcb *tcp;
1063{
1064 if (entering(tcp)) {
1065 tprintf("%ld, %lu, %lu",
1066 tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
1067 }
1068 return 0;
1069}
1070
1071int
1072sys_chmod(tcp)
1073struct tcb *tcp;
1074{
1075 if (entering(tcp)) {
1076 printpath(tcp, tcp->u_arg[0]);
1077 tprintf(", %#lo", tcp->u_arg[1]);
1078 }
1079 return 0;
1080}
1081
1082int
1083sys_fchmod(tcp)
1084struct tcb *tcp;
1085{
1086 if (entering(tcp)) {
1087 tprintf("%ld, %#lo", tcp->u_arg[0], tcp->u_arg[1]);
1088 }
1089 return 0;
1090}
1091
1092int
1093sys_utimes(tcp)
1094struct tcb *tcp;
1095{
1096 if (entering(tcp)) {
1097 printpath(tcp, tcp->u_arg[0]);
1098 tprintf(", ");
1099 printtv(tcp, tcp->u_arg[1]);
1100 }
1101 return 0;
1102}
1103
1104int
1105sys_utime(tcp)
1106struct tcb *tcp;
1107{
1108 long ut[2];
1109
1110 if (entering(tcp)) {
1111 printpath(tcp, tcp->u_arg[0]);
1112 tprintf(", ");
1113 if (!tcp->u_arg[1])
1114 tprintf("NULL");
1115 else if (!verbose(tcp))
1116 tprintf("%#lx", tcp->u_arg[1]);
1117 else if (umoven(tcp, tcp->u_arg[1], sizeof ut,
1118 (char *) ut) < 0)
1119 tprintf("[?, ?]");
1120 else {
1121 tprintf("[%s,", sprinttime(ut[0]));
1122 tprintf(" %s]", sprinttime(ut[1]));
1123 }
1124 }
1125 return 0;
1126}
1127
1128int
1129sys_mknod(tcp)
1130struct tcb *tcp;
1131{
1132 int mode = tcp->u_arg[1];
1133
1134 if (entering(tcp)) {
1135 printpath(tcp, tcp->u_arg[0]);
1136 tprintf(", %s", sprintmode(mode));
1137 switch (mode & S_IFMT) {
1138 case S_IFCHR: case S_IFBLK:
1139#ifdef LINUXSPARC
1140 if (current_personality == 1)
1141 tprintf(", makedev(%lu, %lu)",
1142 (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff),
1143 (unsigned long) (tcp->u_arg[2] & 0x3ffff));
1144 else
1145#endif
1146 tprintf(", makedev(%lu, %lu)",
1147 (unsigned long) major(tcp->u_arg[2]),
1148 (unsigned long) minor(tcp->u_arg[2]));
1149 break;
1150 default:
1151 break;
1152 }
1153 }
1154 return 0;
1155}
1156
1157int
1158sys_mkfifo(tcp)
1159struct tcb *tcp;
1160{
1161 if (entering(tcp)) {
1162 printpath(tcp, tcp->u_arg[0]);
1163 tprintf(", %#lo", tcp->u_arg[1]);
1164 }
1165 return 0;
1166}
1167
1168int
1169sys_fsync(tcp)
1170struct tcb *tcp;
1171{
1172 if (entering(tcp)) {
1173 tprintf("%ld", tcp->u_arg[0]);
1174 }
1175 return 0;
1176}
1177
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001178#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001179
1180static void
1181printdir(tcp, addr)
1182struct tcb *tcp;
1183long addr;
1184{
1185 struct dirent d;
1186
1187 if (!verbose(tcp)) {
1188 tprintf("%#lx", addr);
1189 return;
1190 }
1191 if (umove(tcp, addr, &d) < 0) {
1192 tprintf("{...}");
1193 return;
1194 }
1195 tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001196 tprintf("d_name=");
1197 printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
1198 tprintf("}");
1199}
1200
1201int
1202sys_readdir(tcp)
1203struct tcb *tcp;
1204{
1205 if (entering(tcp)) {
1206 tprintf("%lu, ", tcp->u_arg[0]);
1207 } else {
1208 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
1209 tprintf("%#lx", tcp->u_arg[1]);
1210 else
1211 printdir(tcp, tcp->u_arg[1]);
1212 /* Not much point in printing this out, it is always 1. */
1213 if (tcp->u_arg[2] != 1)
1214 tprintf(", %lu", tcp->u_arg[2]);
1215 }
1216 return 0;
1217}
1218
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001219#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001220
1221int
1222sys_getdents(tcp)
1223struct tcb *tcp;
1224{
1225 int i, len, dents = 0;
1226 char *buf;
1227
1228 if (entering(tcp)) {
1229 tprintf("%lu, ", tcp->u_arg[0]);
1230 return 0;
1231 }
1232 if (syserror(tcp) || !verbose(tcp)) {
1233 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
1234 return 0;
1235 }
1236#ifdef linux
1237#ifdef __sparc__
1238 tprintf (" = Unknown value\n");
1239 return 0;
1240#endif
1241#endif
1242 len = tcp->u_rval;
1243 if ((buf = malloc(len)) == NULL) {
1244 tprintf("out of memory\n");
1245 return 0;
1246 }
1247 if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
1248 tprintf("{...}, %lu", tcp->u_arg[2]);
1249 free(buf);
1250 return 0;
1251 }
1252 if (!abbrev(tcp))
1253 tprintf("{");
1254 for (i = 0; i < len;) {
1255 struct dirent *d = (struct dirent *) &buf[i];
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001256#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001257 if (!abbrev(tcp)) {
1258 tprintf("%s{d_ino=%lu, d_off=%lu, ",
1259 i ? " " : "", d->d_ino, d->d_off);
1260 tprintf("d_reclen=%u, d_name=\"%s\"}",
1261 d->d_reclen, d->d_name);
1262 }
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001263#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001264#ifdef SVR4
1265 if (!abbrev(tcp)) {
1266 tprintf("%s{d_ino=%lu, d_off=%lu, ",
1267 i ? " " : "", d->d_ino, d->d_off);
1268 tprintf("d_reclen=%u, d_name=\"%s\"}",
1269 d->d_reclen, d->d_name);
1270 }
1271#endif /* SVR4 */
1272#ifdef SUNOS4
1273 if (!abbrev(tcp)) {
1274 tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
1275 i ? " " : "", d->d_off, d->d_fileno,
1276 d->d_reclen);
1277 tprintf("d_namlen=%u, d_name=\"%.*s\"}",
1278 d->d_namlen, d->d_namlen, d->d_name);
1279 }
1280#endif /* SUNOS4 */
1281 i += d->d_reclen;
1282 dents++;
1283 }
1284 if (!abbrev(tcp))
1285 tprintf("}");
1286 else
1287 tprintf("/* %u entries */", dents);
1288 tprintf(", %lu", tcp->u_arg[2]);
1289 free(buf);
1290 return 0;
1291}
1292
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001293#ifdef linux
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001294
1295int
1296sys_getcwd(tcp)
1297struct tcb *tcp;
1298{
1299 if (exiting(tcp)) {
1300 if (syserror(tcp))
1301 tprintf("%#lx", tcp->u_arg[0]);
1302 else
1303 printstr(tcp, tcp->u_arg[0], tcp->u_arg[1]);
1304 tprintf(", %lu", tcp->u_arg[1]);
1305 }
1306 return 0;
1307}
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001308#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001309
1310#ifdef HAVE_SYS_ASYNCH_H
1311
1312int
1313sys_aioread(tcp)
1314struct tcb *tcp;
1315{
1316 struct aio_result_t res;
1317
1318 if (entering(tcp)) {
1319 tprintf("%lu, ", tcp->u_arg[0]);
1320 } else {
1321 if (syserror(tcp))
1322 tprintf("%#lx", tcp->u_arg[1]);
1323 else
1324 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1325 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1326 printxval(whence, tcp->u_arg[4], "L_???");
1327 if (syserror(tcp) || tcp->u_arg[5] == 0
1328 || umove(tcp, tcp->u_arg[5], &res) < 0)
1329 tprintf(", %#lx", tcp->u_arg[5]);
1330 else
1331 tprintf(", {aio_return %d aio_errno %d}",
1332 res.aio_return, res.aio_errno);
1333 }
1334 return 0;
1335}
1336
1337int
1338sys_aiowrite(tcp)
1339struct tcb *tcp;
1340{
1341 struct aio_result_t res;
1342
1343 if (entering(tcp)) {
1344 tprintf("%lu, ", tcp->u_arg[0]);
1345 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1346 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1347 printxval(whence, tcp->u_arg[4], "L_???");
1348 }
1349 else {
1350 if (tcp->u_arg[5] == 0)
1351 tprintf(", NULL");
1352 else if (syserror(tcp)
1353 || umove(tcp, tcp->u_arg[5], &res) < 0)
1354 tprintf(", %#lx", tcp->u_arg[5]);
1355 else
1356 tprintf(", {aio_return %d aio_errno %d}",
1357 res.aio_return, res.aio_errno);
1358 }
1359 return 0;
1360}
1361
1362int
1363sys_aiowait(tcp)
1364struct tcb *tcp;
1365{
1366 if (entering(tcp))
1367 printtv(tcp, tcp->u_arg[0]);
1368 return 0;
1369}
1370
1371int
1372sys_aiocancel(tcp)
1373struct tcb *tcp;
1374{
1375 struct aio_result_t res;
1376
1377 if (exiting(tcp)) {
1378 if (tcp->u_arg[0] == 0)
1379 tprintf("NULL");
1380 else if (syserror(tcp)
1381 || umove(tcp, tcp->u_arg[0], &res) < 0)
1382 tprintf("%#lx", tcp->u_arg[0]);
1383 else
1384 tprintf("{aio_return %d aio_errno %d}",
1385 res.aio_return, res.aio_errno);
1386 }
1387 return 0;
1388}
1389
1390#endif /* HAVE_SYS_ASYNCH_H */