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