]> granicus.if.org Git - strace/blob - file.c
df6c5511bbe74608dcc9b4af5b95402add61b8b5
[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                 (unsigned long)statbuf.f_bsize,
711                 (unsigned long)statbuf.f_blocks,
712                 (unsigned long)statbuf.f_bfree);
713         tprintf("f_files=%lu, f_ffree=%lu",
714                 (unsigned long)statbuf.f_files,
715                 (unsigned long)statbuf.f_ffree);
716 #ifdef LINUX
717         tprintf(", f_namelen=%lu}", (unsigned long)statbuf.f_namelen);
718 #endif /* LINUX */
719 #endif /* !ALPHA */
720         tprintf("}");
721 }
722
723 int
724 sys_statfs(tcp)
725 struct tcb *tcp;
726 {
727         if (entering(tcp)) {
728                 printpath(tcp, tcp->u_arg[0]);
729                 tprintf(", ");
730         } else {
731                 printstatfs(tcp, tcp->u_arg[1]);
732         }
733         return 0;
734 }
735
736 int
737 sys_fstatfs(tcp)
738 struct tcb *tcp;
739 {
740         if (entering(tcp)) {
741                 tprintf("%lu, ", tcp->u_arg[0]);
742         } else {
743                 printstatfs(tcp, tcp->u_arg[1]);
744         }
745         return 0;
746 }
747
748 #ifdef LINUX
749 #ifdef ALPHA
750
751 int
752 osf_statfs(tcp)
753 struct tcb *tcp;
754 {
755         if (entering(tcp)) {
756                 printpath(tcp, tcp->u_arg[0]);
757                 tprintf(", ");
758         } else {
759                 printstatfs(tcp, tcp->u_arg[1]);
760                 tprintf(", %lu", tcp->u_arg[2]);
761         }
762         return 0;
763 }
764
765 int
766 osf_fstatfs(tcp)
767 struct tcb *tcp;
768 {
769         if (entering(tcp)) {
770                 tprintf("%lu, ", tcp->u_arg[0]);
771         } else {
772                 printstatfs(tcp, tcp->u_arg[1]);
773                 tprintf(", %lu", tcp->u_arg[2]);
774         }
775         return 0;
776 }
777 #endif /* ALPHA */
778 #endif /* LINUX */
779
780 #endif /* !SVR4 */
781
782 #ifdef SUNOS4
783
784 int
785 sys_ustat(tcp)
786 struct tcb *tcp;
787 {
788         struct ustat statbuf;
789
790         if (entering(tcp)) {
791                 tprintf("makedev(%lu, %lu), ",
792                                 (long) major(tcp->u_arg[0]),
793                                 (long) minor(tcp->u_arg[0]));
794         }
795         else {
796                 if (syserror(tcp) || !verbose(tcp))
797                         tprintf("%#lx", tcp->u_arg[1]);
798                 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
799                         tprintf("{...}");
800                 else {
801                         tprintf("{f_tfree=%lu, f_tinode=%lu, ",
802                                 statbuf.f_tfree, statbuf.f_tinode);
803                         tprintf("f_fname=\"%.*s\", ",
804                                 (int) sizeof(statbuf.f_fname),
805                                 statbuf.f_fname);
806                         tprintf("f_fpack=\"%.*s\"}",
807                                 (int) sizeof(statbuf.f_fpack),
808                                 statbuf.f_fpack);
809                 }
810         }
811         return 0;
812 }
813
814 #endif /* SUNOS4 */
815
816 /* directory */
817 int
818 sys_chdir(tcp)
819 struct tcb *tcp;
820 {
821         if (entering(tcp)) {
822                 printpath(tcp, tcp->u_arg[0]);
823         }
824         return 0;
825 }
826
827 int
828 sys_mkdir(tcp)
829 struct tcb *tcp;
830 {
831         if (entering(tcp)) {
832                 printpath(tcp, tcp->u_arg[0]);
833                 tprintf(", %#lo", tcp->u_arg[1]);
834         }
835         return 0;
836 }
837
838 int
839 sys_rmdir(tcp)
840 struct tcb *tcp;
841 {
842         if (entering(tcp)) {
843                 printpath(tcp, tcp->u_arg[0]);
844         }
845         return 0;
846 }
847
848 int
849 sys_fchdir(tcp)
850 struct tcb *tcp;
851 {
852         if (entering(tcp)) {
853                 tprintf("%ld", tcp->u_arg[0]);
854         }
855         return 0;
856 }
857
858 int
859 sys_chroot(tcp)
860 struct tcb *tcp;
861 {
862         if (entering(tcp)) {
863                 printpath(tcp, tcp->u_arg[0]);
864         }
865         return 0;
866 }
867
868 int
869 sys_fchroot(tcp)
870 struct tcb *tcp;
871 {
872         if (entering(tcp)) {
873                 tprintf("%ld", tcp->u_arg[0]);
874         }
875         return 0;
876 }
877
878 int
879 sys_link(tcp)
880 struct tcb *tcp;
881 {
882         if (entering(tcp)) {
883                 printpath(tcp, tcp->u_arg[0]);
884                 tprintf(", ");
885                 printpath(tcp, tcp->u_arg[1]);
886         }
887         return 0;
888 }
889
890 int
891 sys_unlink(tcp)
892 struct tcb *tcp;
893 {
894         if (entering(tcp)) {
895                 printpath(tcp, tcp->u_arg[0]);
896         }
897         return 0;
898 }
899
900 int
901 sys_symlink(tcp)
902 struct tcb *tcp;
903 {
904         if (entering(tcp)) {
905                 printpath(tcp, tcp->u_arg[0]);
906                 tprintf(", ");
907                 printpath(tcp, tcp->u_arg[1]);
908         }
909         return 0;
910 }
911
912 int
913 sys_readlink(tcp)
914 struct tcb *tcp;
915 {
916         if (entering(tcp)) {
917                 printpath(tcp, tcp->u_arg[0]);
918                 tprintf(", ");
919         } else {
920                 if (syserror(tcp))
921                         tprintf("%#lx", tcp->u_arg[1]);
922                 else
923                         printpathn(tcp, tcp->u_arg[1], tcp->u_rval);
924                 tprintf(", %lu", tcp->u_arg[2]);
925         }
926         return 0;
927 }
928
929 int
930 sys_rename(tcp)
931 struct tcb *tcp;
932 {
933         if (entering(tcp)) {
934                 printpath(tcp, tcp->u_arg[0]);
935                 tprintf(", ");
936                 printpath(tcp, tcp->u_arg[1]);
937         }
938         return 0;
939 }
940
941 int
942 sys_chown(tcp)
943 struct tcb *tcp;
944 {
945         if (entering(tcp)) {
946                 printpath(tcp, tcp->u_arg[0]);
947                 tprintf(", %lu, %lu", tcp->u_arg[1], tcp->u_arg[2]);
948         }
949         return 0;
950 }
951
952 int
953 sys_fchown(tcp)
954 struct tcb *tcp;
955 {
956         if (entering(tcp)) {
957                 tprintf("%ld, %lu, %lu",
958                         tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
959         }
960         return 0;
961 }
962
963 int
964 sys_chmod(tcp)
965 struct tcb *tcp;
966 {
967         if (entering(tcp)) {
968                 printpath(tcp, tcp->u_arg[0]);
969                 tprintf(", %#lo", tcp->u_arg[1]);
970         }
971         return 0;
972 }
973
974 int
975 sys_fchmod(tcp)
976 struct tcb *tcp;
977 {
978         if (entering(tcp)) {
979                 tprintf("%ld, %#lo", tcp->u_arg[0], tcp->u_arg[1]);
980         }
981         return 0;
982 }
983
984 int
985 sys_utimes(tcp)
986 struct tcb *tcp;
987 {
988         if (entering(tcp)) {
989                 printpath(tcp, tcp->u_arg[0]);
990                 tprintf(", ");
991                 printtv(tcp, tcp->u_arg[1]);
992         }
993         return 0;
994 }
995
996 int
997 sys_utime(tcp)
998 struct tcb *tcp;
999 {
1000         long ut[2];
1001
1002         if (entering(tcp)) {
1003                 printpath(tcp, tcp->u_arg[0]);
1004                 tprintf(", ");
1005                 if (!tcp->u_arg[1])
1006                         tprintf("NULL");
1007                 else if (!verbose(tcp))
1008                         tprintf("%#lx", tcp->u_arg[1]);
1009                 else if (umoven(tcp, tcp->u_arg[1], sizeof ut,
1010                     (char *) ut) < 0)
1011                         tprintf("[?, ?]");
1012                 else {
1013                         tprintf("[%s,", sprinttime(ut[0]));
1014                         tprintf(" %s]", sprinttime(ut[1]));
1015                 }
1016         }
1017         return 0;
1018 }
1019
1020 int
1021 sys_mknod(tcp)
1022 struct tcb *tcp;
1023 {
1024         int mode = tcp->u_arg[1];
1025
1026         if (entering(tcp)) {
1027                 printpath(tcp, tcp->u_arg[0]);
1028                 tprintf(", %s", sprintmode(mode));
1029                 switch (mode & S_IFMT) {
1030                 case S_IFCHR: case S_IFBLK:
1031 #ifdef LINUXSPARC
1032                         if (current_personality == 1)
1033                         tprintf(", makedev(%lu, %lu)",
1034                                 (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff),
1035                                 (unsigned long) (tcp->u_arg[2] & 0x3ffff));
1036                         else
1037 #endif  
1038                         tprintf(", makedev(%lu, %lu)",
1039                                 (unsigned long) major(tcp->u_arg[2]),
1040                                 (unsigned long) minor(tcp->u_arg[2]));
1041                         break;
1042                 default:
1043                         break;
1044                 }
1045         }
1046         return 0;
1047 }
1048
1049 int
1050 sys_mkfifo(tcp)
1051 struct tcb *tcp;
1052 {
1053         if (entering(tcp)) {
1054                 printpath(tcp, tcp->u_arg[0]);
1055                 tprintf(", %#lo", tcp->u_arg[1]);
1056         }
1057         return 0;
1058 }
1059
1060 int
1061 sys_fsync(tcp)
1062 struct tcb *tcp;
1063 {
1064         if (entering(tcp)) {
1065                 tprintf("%ld", tcp->u_arg[0]);
1066         }
1067         return 0;
1068 }
1069
1070 #ifdef LINUX
1071
1072 static void
1073 printdir(tcp, addr)
1074 struct tcb *tcp;
1075 long addr;
1076 {
1077         struct dirent d;
1078
1079         if (!verbose(tcp)) {
1080                 tprintf("%#lx", addr);
1081                 return;
1082         }
1083         if (umove(tcp, addr, &d) < 0) {
1084                 tprintf("{...}");
1085                 return;
1086         }
1087         tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
1088 #ifndef LINUX
1089         /* This contains garbage under Linux.  */
1090         tprintf("d_off=%d, ", d.d_off);
1091 #endif /* !LINUX */
1092 #ifndef LINUX
1093         /* No point in printing this out since the syscall returns it. */
1094         tprintf("d_reclen=%u, ", d.d_reclen);
1095 #endif /* !LINUX */
1096         tprintf("d_name=");
1097         printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
1098         tprintf("}");
1099 }
1100
1101 int
1102 sys_readdir(tcp)
1103 struct tcb *tcp;
1104 {
1105         if (entering(tcp)) {
1106                 tprintf("%lu, ", tcp->u_arg[0]);
1107         } else {
1108                 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
1109                         tprintf("%#lx", tcp->u_arg[1]);
1110                 else
1111                         printdir(tcp, tcp->u_arg[1]);
1112                 /* Not much point in printing this out, it is always 1. */
1113                 if (tcp->u_arg[2] != 1)
1114                         tprintf(", %lu", tcp->u_arg[2]);
1115         }
1116         return 0;
1117 }
1118
1119 #endif /* LINUX */
1120
1121 int
1122 sys_getdents(tcp)
1123 struct tcb *tcp;
1124 {
1125         int i, len, dents = 0;
1126         char *buf;
1127
1128         if (entering(tcp)) {
1129                 tprintf("%lu, ", tcp->u_arg[0]);
1130                 return 0;
1131         }
1132         if (syserror(tcp) || !verbose(tcp)) {
1133                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
1134                 return 0;
1135         }
1136 #ifdef linux
1137 #ifdef __sparc__
1138         tprintf (" = Unknown value\n");
1139         return 0;
1140 #endif
1141 #endif
1142         len = tcp->u_rval;
1143         if ((buf = malloc(len)) == NULL) {
1144                 tprintf("out of memory\n");
1145                 return 0;
1146         }
1147         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
1148                 tprintf("{...}, %lu", tcp->u_arg[2]);
1149                 free(buf);
1150                 return 0;
1151         }
1152         if (!abbrev(tcp))
1153                 tprintf("{");
1154         for (i = 0; i < len;) {
1155                 struct dirent *d = (struct dirent *) &buf[i];
1156 #ifdef LINUX
1157                 if (!abbrev(tcp)) {
1158                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
1159                                 i ? " " : "", d->d_ino, d->d_off);
1160                         tprintf("d_reclen=%u, d_name=\"%s\"}",
1161                                 d->d_reclen, d->d_name);
1162                 }
1163 #endif /* LINUX */
1164 #ifdef SVR4
1165                 if (!abbrev(tcp)) {
1166                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
1167                                 i ? " " : "", d->d_ino, d->d_off);
1168                         tprintf("d_reclen=%u, d_name=\"%s\"}",
1169                                 d->d_reclen, d->d_name);
1170                 }
1171 #endif /* SVR4 */
1172 #ifdef SUNOS4
1173                 if (!abbrev(tcp)) {
1174                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
1175                                 i ? " " : "", d->d_off, d->d_fileno,
1176                                 d->d_reclen);
1177                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
1178                                 d->d_namlen, d->d_namlen, d->d_name);
1179                 }
1180 #endif /* SUNOS4 */
1181                 i += d->d_reclen;
1182                 dents++;
1183         }
1184         if (!abbrev(tcp))
1185                 tprintf("}");
1186         else
1187                 tprintf("/* %u entries */", dents);
1188         tprintf(", %lu", tcp->u_arg[2]);
1189         free(buf);
1190         return 0;
1191 }
1192
1193 #ifdef LINUX
1194
1195 int
1196 sys_getcwd(tcp)
1197 struct tcb *tcp;
1198 {
1199     if (exiting(tcp)) {
1200         if (syserror(tcp))
1201             tprintf("%#lx", tcp->u_arg[0]);
1202         else
1203             printstr(tcp, tcp->u_arg[0], tcp->u_arg[1]);
1204         tprintf(", %lu", tcp->u_arg[1]);
1205     }
1206     return 0;
1207 }
1208 #endif /* LINUX */
1209
1210 #ifdef HAVE_SYS_ASYNCH_H
1211
1212 int
1213 sys_aioread(tcp)
1214 struct tcb *tcp;
1215 {
1216         struct aio_result_t res;
1217
1218         if (entering(tcp)) {
1219                 tprintf("%lu, ", tcp->u_arg[0]);
1220         } else {
1221                 if (syserror(tcp))
1222                         tprintf("%#lx", tcp->u_arg[1]);
1223                 else
1224                         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1225                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1226                 printxval(whence, tcp->u_arg[4], "L_???");
1227                 if (syserror(tcp) || tcp->u_arg[5] == 0
1228                     || umove(tcp, tcp->u_arg[5], &res) < 0)
1229                         tprintf(", %#lx", tcp->u_arg[5]);
1230                 else
1231                         tprintf(", {aio_return %d aio_errno %d}",
1232                                 res.aio_return, res.aio_errno);
1233         }
1234         return 0;
1235 }
1236
1237 int
1238 sys_aiowrite(tcp)
1239 struct tcb *tcp;
1240 {
1241         struct aio_result_t res;
1242
1243         if (entering(tcp)) {
1244                 tprintf("%lu, ", tcp->u_arg[0]);
1245                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1246                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1247                 printxval(whence, tcp->u_arg[4], "L_???");
1248         }
1249         else {
1250                 if (tcp->u_arg[5] == 0)
1251                         tprintf(", NULL");
1252                 else if (syserror(tcp)
1253                     || umove(tcp, tcp->u_arg[5], &res) < 0)
1254                         tprintf(", %#lx", tcp->u_arg[5]);
1255                 else
1256                         tprintf(", {aio_return %d aio_errno %d}",
1257                                 res.aio_return, res.aio_errno);
1258         }
1259         return 0;
1260 }
1261
1262 int
1263 sys_aiowait(tcp)
1264 struct tcb *tcp;
1265 {
1266         if (entering(tcp))
1267                 printtv(tcp, tcp->u_arg[0]);
1268         return 0;
1269 }
1270
1271 int
1272 sys_aiocancel(tcp)
1273 struct tcb *tcp;
1274 {
1275         struct aio_result_t res;
1276
1277         if (exiting(tcp)) {
1278                 if (tcp->u_arg[0] == 0)
1279                         tprintf("NULL");
1280                 else if (syserror(tcp)
1281                     || umove(tcp, tcp->u_arg[0], &res) < 0)
1282                         tprintf("%#lx", tcp->u_arg[0]);
1283                 else
1284                         tprintf("{aio_return %d aio_errno %d}",
1285                                 res.aio_return, res.aio_errno);
1286         }
1287         return 0;
1288 }
1289
1290 #endif /* HAVE_SYS_ASYNCH_H */