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