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