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 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $Id$
31 */
32
33 #include "defs.h"
34
35 #include <dirent.h>
36
37 #ifdef LINUX
38 struct kernel_dirent {
39 unsigned long d_ino;
40 unsigned long d_off;
41 unsigned short d_reclen;
42 char d_name[1];
43 };
44 #else
45 # define kernel_dirent dirent
46 #endif
47
48 #ifdef HAVE_ANDROID_OS
49 #include <linux/fadvise.h>
50
51 // ANDROID: From linux/dirent.h
52
53 struct dirent64 {
54 __u64 d_ino;
55 __s64 d_off;
56 unsigned short d_reclen;
57 unsigned char d_type;
58 char d_name[256];
59 };
60
61 // ANDROID: From kernel_headers/asm/statfs.h
62
63 #if !defined(MIPS)
64 /*
65 * With EABI there is 4 bytes of padding added to this structure.
66 * Let's pack it so the padding goes away to simplify dual ABI support.
67 * Note that user space does NOT have to pack this structure.
68 */
69 struct statfs64 {
70 __u32 f_type;
71 __u32 f_bsize;
72 __u64 f_blocks;
73 __u64 f_bfree;
74 __u64 f_bavail;
75 __u64 f_files;
76 __u64 f_ffree;
77 __kernel_fsid_t f_fsid;
78 __u32 f_namelen;
79 __u32 f_frsize;
80 __u32 f_spare[5];
81 } __attribute__ ((packed,aligned(4)));
82 #else
83 struct statfs64 {
84 __u32 f_type;
85 __u32 f_bsize;
86 __u32 f_frsize;
87 __u32 __pad;
88 __u64 f_blocks;
89 __u64 f_bfree;
90 __u64 f_files;
91 __u64 f_ffree;
92 __u64 f_bavail;
93 __kernel_fsid_t f_fsid;
94 __u32 f_namelen;
95 __u32 f_spare[6];
96 };
97 #endif
98
99
100 #endif /* HAVE_ANDROID_OS */
101
102 #ifdef LINUX
103 # ifdef LINUXSPARC
104 struct stat {
105 unsigned short st_dev;
106 unsigned int st_ino;
107 unsigned short st_mode;
108 short st_nlink;
109 unsigned short st_uid;
110 unsigned short st_gid;
111 unsigned short st_rdev;
112 unsigned int st_size;
113 int st_atime;
114 unsigned int __unused1;
115 int st_mtime;
116 unsigned int __unused2;
117 int st_ctime;
118 unsigned int __unused3;
119 int st_blksize;
120 int st_blocks;
121 unsigned int __unused4[2];
122 };
123 #if defined(SPARC64)
124 struct stat_sparc64 {
125 unsigned int st_dev;
126 unsigned long st_ino;
127 unsigned int st_mode;
128 unsigned int st_nlink;
129 unsigned int st_uid;
130 unsigned int st_gid;
131 unsigned int st_rdev;
132 long st_size;
133 long st_atime;
134 long st_mtime;
135 long st_ctime;
136 long st_blksize;
137 long st_blocks;
138 unsigned long __unused4[2];
139 };
140 #endif /* SPARC64 */
141 # define stat kernel_stat
142 # include <asm/stat.h>
143 # undef stat
144 # else
145 # undef dev_t
146 # undef ino_t
147 # undef mode_t
148 # undef nlink_t
149 # undef uid_t
150 # undef gid_t
151 # undef off_t
152 # undef loff_t
153
154 # define dev_t __kernel_dev_t
155 # define ino_t __kernel_ino_t
156 # define mode_t __kernel_mode_t
157 # define nlink_t __kernel_nlink_t
158 # define uid_t __kernel_uid_t
159 # define gid_t __kernel_gid_t
160 # define off_t __kernel_off_t
161 # define loff_t __kernel_loff_t
162
163 # include <asm/stat.h>
164
165 # undef dev_t
166 # undef ino_t
167 # undef mode_t
168 # undef nlink_t
169 # undef uid_t
170 # undef gid_t
171 # undef off_t
172 # undef loff_t
173
174 # define dev_t dev_t
175 # define ino_t ino_t
176 # define mode_t mode_t
177 # define nlink_t nlink_t
178 # define uid_t uid_t
179 # define gid_t gid_t
180 # define off_t off_t
181 # define loff_t loff_t
182 # endif
183 # ifdef HPPA /* asm-parisc/stat.h defines stat64 */
184 # undef stat64
185 # endif
186 # define stat libc_stat
187 # define stat64 libc_stat64
188 # include <sys/stat.h>
189 # undef stat
190 # undef stat64
191 /* These might be macros. */
192 # undef st_atime
193 # undef st_mtime
194 # undef st_ctime
195 # ifdef HPPA
196 # define stat64 hpux_stat64
197 # endif
198 #else
199 # include <sys/stat.h>
200 #endif
201
202 #include <fcntl.h>
203
204 #ifdef SVR4
205 # include <sys/cred.h>
206 #endif /* SVR4 */
207
208 #ifdef HAVE_SYS_VFS_H
209 #include <sys/vfs.h>
210 #endif
211
212 #ifdef HAVE_LINUX_XATTR_H
213 #include <linux/xattr.h>
214 #elif defined linux
215 #define XATTR_CREATE 1
216 #define XATTR_REPLACE 2
217 #endif
218
219 #ifdef FREEBSD
220 #include <sys/param.h>
221 #include <sys/mount.h>
222 #include <sys/stat.h>
223 #endif
224
225 #if _LFS64_LARGEFILE && (defined(LINUX) || defined(SVR4))
226 # ifdef HAVE_INTTYPES_H
227 # include <inttypes.h>
228 # else
229 # define PRId64 "lld"
230 # define PRIu64 "llu"
231 # endif
232 #endif
233
234 #if HAVE_LONG_LONG_OFF_T
235 /*
236 * Ugly hacks for systems that have typedef long long off_t
237 */
238
239 #define stat64 stat
240 #define HAVE_STAT64 1 /* Ugly hack */
241
242 #define sys_stat64 sys_stat
243 #define sys_fstat64 sys_fstat
244 #define sys_lstat64 sys_lstat
245 #define sys_lseek64 sys_lseek
246 #define sys_truncate64 sys_truncate
247 #define sys_ftruncate64 sys_ftruncate
248 #endif
249
250 #ifdef MAJOR_IN_SYSMACROS
251 #include <sys/sysmacros.h>
252 #endif
253
254 #ifdef MAJOR_IN_MKDEV
255 #include <sys/mkdev.h>
256 #endif
257
258 #ifdef HAVE_SYS_ASYNCH_H
259 #include <sys/asynch.h>
260 #endif
261
262 #ifdef SUNOS4
263 #include <ustat.h>
264 #endif
265
266 const struct xlat open_access_modes[] = {
267 { O_RDONLY, "O_RDONLY" },
268 { O_WRONLY, "O_WRONLY" },
269 { O_RDWR, "O_RDWR" },
270 #ifdef O_ACCMODE
271 { O_ACCMODE, "O_ACCMODE" },
272 #endif
273 { 0, NULL },
274 };
275
276 const struct xlat open_mode_flags[] = {
277 { O_CREAT, "O_CREAT" },
278 { O_EXCL, "O_EXCL" },
279 { O_NOCTTY, "O_NOCTTY" },
280 { O_TRUNC, "O_TRUNC" },
281 { O_APPEND, "O_APPEND" },
282 { O_NONBLOCK, "O_NONBLOCK" },
283 #ifdef O_SYNC
284 { O_SYNC, "O_SYNC" },
285 #endif
286 #ifdef O_ASYNC
287 { O_ASYNC, "O_ASYNC" },
288 #endif
289 #ifdef O_DSYNC
290 { O_DSYNC, "O_DSYNC" },
291 #endif
292 #ifdef O_RSYNC
293 { O_RSYNC, "O_RSYNC" },
294 #endif
295 #if defined(O_NDELAY) && (O_NDELAY != O_NONBLOCK)
296 { O_NDELAY, "O_NDELAY" },
297 #endif
298 #ifdef O_PRIV
299 { O_PRIV, "O_PRIV" },
300 #endif
301 #ifdef O_DIRECT
302 { O_DIRECT, "O_DIRECT" },
303 #endif
304 #ifdef O_LARGEFILE
305 # if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
306 # undef O_LARGEFILE
307 # ifdef SPARC64
308 # define O_LARGEFILE 0x40000
309 # elif defined X86_64 || defined S390X
310 # define O_LARGEFILE 0100000
311 # endif
312 # endif
313 # ifdef O_LARGEFILE
314 { O_LARGEFILE, "O_LARGEFILE" },
315 # endif
316 #endif
317 #ifdef O_DIRECTORY
318 { O_DIRECTORY, "O_DIRECTORY" },
319 #endif
320 #ifdef O_NOFOLLOW
321 { O_NOFOLLOW, "O_NOFOLLOW" },
322 #endif
323 #ifdef O_NOATIME
324 { O_NOATIME, "O_NOATIME" },
325 #endif
326 #ifdef O_CLOEXEC
327 { O_CLOEXEC, "O_CLOEXEC" },
328 #endif
329
330 #ifdef FNDELAY
331 { FNDELAY, "FNDELAY" },
332 #endif
333 #ifdef FAPPEND
334 { FAPPEND, "FAPPEND" },
335 #endif
336 #ifdef FMARK
337 { FMARK, "FMARK" },
338 #endif
339 #ifdef FDEFER
340 { FDEFER, "FDEFER" },
341 #endif
342 #ifdef FASYNC
343 { FASYNC, "FASYNC" },
344 #endif
345 #ifdef FSHLOCK
346 { FSHLOCK, "FSHLOCK" },
347 #endif
348 #ifdef FEXLOCK
349 { FEXLOCK, "FEXLOCK" },
350 #endif
351 #ifdef FCREAT
352 { FCREAT, "FCREAT" },
353 #endif
354 #ifdef FTRUNC
355 { FTRUNC, "FTRUNC" },
356 #endif
357 #ifdef FEXCL
358 { FEXCL, "FEXCL" },
359 #endif
360 #ifdef FNBIO
361 { FNBIO, "FNBIO" },
362 #endif
363 #ifdef FSYNC
364 { FSYNC, "FSYNC" },
365 #endif
366 #ifdef FNOCTTY
367 { FNOCTTY, "FNOCTTY" },
368 #endif
369 #ifdef O_SHLOCK
370 { O_SHLOCK, "O_SHLOCK" },
371 #endif
372 #ifdef O_EXLOCK
373 { O_EXLOCK, "O_EXLOCK" },
374 #endif
375 { 0, NULL },
376 };
377
378 #ifdef LINUX
379
380 #ifndef AT_FDCWD
381 # define AT_FDCWD -100
382 #endif
383
384 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
385 * extension to get the right value. We do this by declaring fd as int here.
386 */
387 static void
print_dirfd(struct tcb * tcp,int fd)388 print_dirfd(struct tcb *tcp, int fd)
389 {
390 if (fd == AT_FDCWD)
391 tprintf("AT_FDCWD, ");
392 else
393 {
394 printfd(tcp, fd);
395 tprintf(", ");
396 }
397 }
398 #endif
399
400 /*
401 * Pity stpcpy() is not standardized...
402 */
403 static char *
str_append(char * dst,const char * src)404 str_append(char *dst, const char *src)
405 {
406 while ((*dst = *src++) != '\0')
407 dst++;
408 return dst;
409 }
410
411 /*
412 * low bits of the open(2) flags define access mode,
413 * other bits are real flags.
414 */
415 const char *
sprint_open_modes(mode_t flags)416 sprint_open_modes(mode_t flags)
417 {
418 static char outstr[1024];
419 char *p;
420 char sep = 0;
421 const char *str;
422 const struct xlat *x;
423
424 p = str_append(outstr, "flags ");
425 str = xlookup(open_access_modes, flags & 3);
426 if (str) {
427 p = str_append(p, str);
428 flags &= ~3;
429 if (!flags)
430 return outstr;
431 sep = '|';
432 }
433
434 for (x = open_mode_flags; x->str; x++) {
435 if ((flags & x->val) == x->val) {
436 if (sep)
437 *p++ = sep;
438 p = str_append(p, x->str);
439 flags &= ~x->val;
440 if (!flags)
441 return outstr;
442 sep = '|';
443 }
444 }
445 /* flags is still nonzero */
446 if (sep)
447 *p++ = sep;
448 sprintf(p, "%#x", flags);
449 return outstr;
450 }
451
452 void
tprint_open_modes(mode_t flags)453 tprint_open_modes(mode_t flags)
454 {
455 tprintf("%s", sprint_open_modes(flags) + sizeof("flags"));
456 }
457
458 static int
decode_open(struct tcb * tcp,int offset)459 decode_open(struct tcb *tcp, int offset)
460 {
461 if (entering(tcp)) {
462 printpath(tcp, tcp->u_arg[offset]);
463 tprintf(", ");
464 /* flags */
465 tprint_open_modes(tcp->u_arg[offset + 1]);
466 if (tcp->u_arg[offset + 1] & O_CREAT) {
467 /* mode */
468 tprintf(", %#lo", tcp->u_arg[offset + 2]);
469 }
470 }
471 return 0;
472 }
473
474 int
sys_open(struct tcb * tcp)475 sys_open(struct tcb *tcp)
476 {
477 return decode_open(tcp, 0);
478 }
479
480 #ifdef LINUX
481 int
sys_openat(struct tcb * tcp)482 sys_openat(struct tcb *tcp)
483 {
484 if (entering(tcp))
485 print_dirfd(tcp, tcp->u_arg[0]);
486 return decode_open(tcp, 1);
487 }
488 #endif
489
490 #ifdef LINUXSPARC
491 static const struct xlat openmodessol[] = {
492 { 0, "O_RDWR" },
493 { 1, "O_RDONLY" },
494 { 2, "O_WRONLY" },
495 { 0x80, "O_NONBLOCK" },
496 { 8, "O_APPEND" },
497 { 0x100, "O_CREAT" },
498 { 0x200, "O_TRUNC" },
499 { 0x400, "O_EXCL" },
500 { 0x800, "O_NOCTTY" },
501 { 0x10, "O_SYNC" },
502 { 0x40, "O_DSYNC" },
503 { 0x8000, "O_RSYNC" },
504 { 4, "O_NDELAY" },
505 { 0x1000, "O_PRIV" },
506 { 0, NULL },
507 };
508
509 int
solaris_open(struct tcb * tcp)510 solaris_open(struct tcb *tcp)
511 {
512 if (entering(tcp)) {
513 printpath(tcp, tcp->u_arg[0]);
514 tprintf(", ");
515 /* flags */
516 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
517 if (tcp->u_arg[1] & 0x100) {
518 /* mode */
519 tprintf(", %#lo", tcp->u_arg[2]);
520 }
521 }
522 return 0;
523 }
524
525 #endif
526
527 int
sys_creat(struct tcb * tcp)528 sys_creat(struct tcb *tcp)
529 {
530 if (entering(tcp)) {
531 printpath(tcp, tcp->u_arg[0]);
532 tprintf(", %#lo", tcp->u_arg[1]);
533 }
534 return 0;
535 }
536
537 static const struct xlat access_flags[] = {
538 { F_OK, "F_OK", },
539 { R_OK, "R_OK" },
540 { W_OK, "W_OK" },
541 { X_OK, "X_OK" },
542 #ifdef EFF_ONLY_OK
543 { EFF_ONLY_OK, "EFF_ONLY_OK" },
544 #endif
545 #ifdef EX_OK
546 { EX_OK, "EX_OK" },
547 #endif
548 { 0, NULL },
549 };
550
551 static int
decode_access(struct tcb * tcp,int offset)552 decode_access(struct tcb *tcp, int offset)
553 {
554 if (entering(tcp)) {
555 printpath(tcp, tcp->u_arg[offset]);
556 tprintf(", ");
557 printflags(access_flags, tcp->u_arg[offset + 1], "?_OK");
558 }
559 return 0;
560 }
561
562 int
sys_access(struct tcb * tcp)563 sys_access(struct tcb *tcp)
564 {
565 return decode_access(tcp, 0);
566 }
567
568 #ifdef LINUX
569 int
sys_faccessat(struct tcb * tcp)570 sys_faccessat(struct tcb *tcp)
571 {
572 if (entering(tcp))
573 print_dirfd(tcp, tcp->u_arg[0]);
574 return decode_access(tcp, 1);
575 }
576 #endif
577
578 int
sys_umask(struct tcb * tcp)579 sys_umask(struct tcb *tcp)
580 {
581 if (entering(tcp)) {
582 tprintf("%#lo", tcp->u_arg[0]);
583 }
584 return RVAL_OCTAL;
585 }
586
587 static const struct xlat whence[] = {
588 { SEEK_SET, "SEEK_SET" },
589 { SEEK_CUR, "SEEK_CUR" },
590 { SEEK_END, "SEEK_END" },
591 { 0, NULL },
592 };
593
594 #ifndef HAVE_LONG_LONG_OFF_T
595 #if defined (LINUX_MIPSN32)
596 int
sys_lseek(struct tcb * tcp)597 sys_lseek(struct tcb *tcp)
598 {
599 long long offset;
600 int _whence;
601
602 if (entering(tcp)) {
603 printfd(tcp, tcp->u_arg[0]);
604 tprintf(", ");
605 offset = tcp->ext_arg[1];
606 _whence = tcp->u_arg[2];
607 if (_whence == SEEK_SET)
608 tprintf("%llu, ", offset);
609 else
610 tprintf("%lld, ", offset);
611 printxval(whence, _whence, "SEEK_???");
612 }
613 return RVAL_UDECIMAL;
614 }
615 #else /* !LINUX_MIPSN32 */
616 int
sys_lseek(struct tcb * tcp)617 sys_lseek(struct tcb *tcp)
618 {
619 off_t offset;
620 int _whence;
621
622 if (entering(tcp)) {
623 printfd(tcp, tcp->u_arg[0]);
624 tprintf(", ");
625 offset = tcp->u_arg[1];
626 _whence = tcp->u_arg[2];
627 if (_whence == SEEK_SET)
628 tprintf("%lu, ", offset);
629 else
630 tprintf("%ld, ", offset);
631 printxval(whence, _whence, "SEEK_???");
632 }
633 return RVAL_UDECIMAL;
634 }
635 #endif /* LINUX_MIPSN32 */
636 #endif
637
638 #ifdef LINUX
639 int
sys_llseek(struct tcb * tcp)640 sys_llseek(struct tcb *tcp)
641 {
642 if (entering(tcp)) {
643 printfd(tcp, tcp->u_arg[0]);
644 /*
645 * This one call takes explicitly two 32-bit arguments hi, lo,
646 * rather than one 64-bit argument for which LONG_LONG works
647 * appropriate for the native byte order.
648 */
649 if (tcp->u_arg[4] == SEEK_SET)
650 tprintf(", %llu, ",
651 ((long long int) tcp->u_arg[1]) << 32 |
652 (unsigned long long) (unsigned) tcp->u_arg[2]);
653 else
654 tprintf(", %lld, ",
655 ((long long int) tcp->u_arg[1]) << 32 |
656 (unsigned long long) (unsigned) tcp->u_arg[2]);
657 }
658 else {
659 long long int off;
660 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
661 tprintf("%#lx, ", tcp->u_arg[3]);
662 else
663 tprintf("[%llu], ", off);
664 printxval(whence, tcp->u_arg[4], "SEEK_???");
665 }
666 return 0;
667 }
668
669 int
sys_readahead(struct tcb * tcp)670 sys_readahead(struct tcb *tcp)
671 {
672 if (entering(tcp)) {
673 int argn;
674 printfd(tcp, tcp->u_arg[0]);
675 tprintf(", ");
676 argn = printllval(tcp, "%lld", 1);
677 tprintf(", %ld", tcp->u_arg[argn]);
678 }
679 return 0;
680 }
681 #endif
682
683 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
684 int
sys_lseek64(struct tcb * tcp)685 sys_lseek64(struct tcb *tcp)
686 {
687 if (entering(tcp)) {
688 int argn;
689 printfd(tcp, tcp->u_arg[0]);
690 tprintf(", ");
691 if (tcp->u_arg[3] == SEEK_SET)
692 argn = printllval(tcp, "%llu, ", 1);
693 else
694 argn = printllval(tcp, "%lld, ", 1);
695 printxval(whence, tcp->u_arg[argn], "SEEK_???");
696 }
697 return RVAL_LUDECIMAL;
698 }
699 #endif
700
701 #ifndef HAVE_LONG_LONG_OFF_T
702 int
sys_truncate(struct tcb * tcp)703 sys_truncate(struct tcb *tcp)
704 {
705 if (entering(tcp)) {
706 printpath(tcp, tcp->u_arg[0]);
707 tprintf(", %lu", tcp->u_arg[1]);
708 }
709 return 0;
710 }
711 #endif
712
713 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
714 int
sys_truncate64(struct tcb * tcp)715 sys_truncate64(struct tcb *tcp)
716 {
717 if (entering(tcp)) {
718 printpath(tcp, tcp->u_arg[0]);
719 printllval(tcp, ", %llu", 1);
720 }
721 return 0;
722 }
723 #endif
724
725 #ifndef HAVE_LONG_LONG_OFF_T
726 int
sys_ftruncate(struct tcb * tcp)727 sys_ftruncate(struct tcb *tcp)
728 {
729 if (entering(tcp)) {
730 printfd(tcp, tcp->u_arg[0]);
731 tprintf(", %lu", tcp->u_arg[1]);
732 }
733 return 0;
734 }
735 #endif
736
737 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
738 int
sys_ftruncate64(struct tcb * tcp)739 sys_ftruncate64(struct tcb *tcp)
740 {
741 if (entering(tcp)) {
742 printfd(tcp, tcp->u_arg[0]);
743 tprintf(", ");
744 printllval(tcp, "%llu", 1);
745 }
746 return 0;
747 }
748 #endif
749
750 /* several stats */
751
752 static const struct xlat modetypes[] = {
753 { S_IFREG, "S_IFREG" },
754 { S_IFSOCK, "S_IFSOCK" },
755 { S_IFIFO, "S_IFIFO" },
756 { S_IFLNK, "S_IFLNK" },
757 { S_IFDIR, "S_IFDIR" },
758 { S_IFBLK, "S_IFBLK" },
759 { S_IFCHR, "S_IFCHR" },
760 { 0, NULL },
761 };
762
763 static const char *
sprintmode(int mode)764 sprintmode(int mode)
765 {
766 static char buf[64];
767 const char *s;
768
769 if ((mode & S_IFMT) == 0)
770 s = "";
771 else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
772 sprintf(buf, "%#o", mode);
773 return buf;
774 }
775 sprintf(buf, "%s%s%s%s", s,
776 (mode & S_ISUID) ? "|S_ISUID" : "",
777 (mode & S_ISGID) ? "|S_ISGID" : "",
778 (mode & S_ISVTX) ? "|S_ISVTX" : "");
779 mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
780 if (mode)
781 sprintf(buf + strlen(buf), "|%#o", mode);
782 s = (*buf == '|') ? buf + 1 : buf;
783 return *s ? s : "0";
784 }
785
786 static char *
sprinttime(time_t t)787 sprinttime(time_t t)
788 {
789 struct tm *tmp;
790 static char buf[32];
791
792 if (t == 0) {
793 strcpy(buf, "0");
794 return buf;
795 }
796 if ((tmp = localtime(&t)))
797 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
798 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
799 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
800 else
801 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
802
803 return buf;
804 }
805
806 #ifdef LINUXSPARC
807 typedef struct {
808 int tv_sec;
809 int tv_nsec;
810 } timestruct_t;
811
812 struct solstat {
813 unsigned st_dev;
814 int st_pad1[3]; /* network id */
815 unsigned st_ino;
816 unsigned st_mode;
817 unsigned st_nlink;
818 unsigned st_uid;
819 unsigned st_gid;
820 unsigned st_rdev;
821 int st_pad2[2];
822 int st_size;
823 int st_pad3; /* st_size, off_t expansion */
824 timestruct_t st_atime;
825 timestruct_t st_mtime;
826 timestruct_t st_ctime;
827 int st_blksize;
828 int st_blocks;
829 char st_fstype[16];
830 int st_pad4[8]; /* expansion area */
831 };
832
833 static void
printstatsol(struct tcb * tcp,long addr)834 printstatsol(struct tcb *tcp, long addr)
835 {
836 struct solstat statbuf;
837
838 if (umove(tcp, addr, &statbuf) < 0) {
839 tprintf("{...}");
840 return;
841 }
842 if (!abbrev(tcp)) {
843 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
844 (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
845 (unsigned long) (statbuf.st_dev & 0x3ffff),
846 (unsigned long) statbuf.st_ino,
847 sprintmode(statbuf.st_mode));
848 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
849 (unsigned long) statbuf.st_nlink,
850 (unsigned long) statbuf.st_uid,
851 (unsigned long) statbuf.st_gid);
852 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
853 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
854 }
855 else
856 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
857 switch (statbuf.st_mode & S_IFMT) {
858 case S_IFCHR: case S_IFBLK:
859 tprintf("st_rdev=makedev(%lu, %lu), ",
860 (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
861 (unsigned long) (statbuf.st_rdev & 0x3ffff));
862 break;
863 default:
864 tprintf("st_size=%u, ", statbuf.st_size);
865 break;
866 }
867 if (!abbrev(tcp)) {
868 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
869 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
870 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
871 }
872 else
873 tprintf("...}");
874 }
875
876 #if defined (SPARC64)
877 static void
printstat_sparc64(struct tcb * tcp,long addr)878 printstat_sparc64(struct tcb *tcp, long addr)
879 {
880 struct stat_sparc64 statbuf;
881
882 if (umove(tcp, addr, &statbuf) < 0) {
883 tprintf("{...}");
884 return;
885 }
886
887 if (!abbrev(tcp)) {
888 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
889 (unsigned long) major(statbuf.st_dev),
890 (unsigned long) minor(statbuf.st_dev),
891 (unsigned long) statbuf.st_ino,
892 sprintmode(statbuf.st_mode));
893 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
894 (unsigned long) statbuf.st_nlink,
895 (unsigned long) statbuf.st_uid,
896 (unsigned long) statbuf.st_gid);
897 tprintf("st_blksize=%lu, ",
898 (unsigned long) statbuf.st_blksize);
899 tprintf("st_blocks=%lu, ",
900 (unsigned long) statbuf.st_blocks);
901 }
902 else
903 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
904 switch (statbuf.st_mode & S_IFMT) {
905 case S_IFCHR: case S_IFBLK:
906 tprintf("st_rdev=makedev(%lu, %lu), ",
907 (unsigned long) major(statbuf.st_rdev),
908 (unsigned long) minor(statbuf.st_rdev));
909 break;
910 default:
911 tprintf("st_size=%lu, ", statbuf.st_size);
912 break;
913 }
914 if (!abbrev(tcp)) {
915 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
916 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
917 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
918 tprintf("}");
919 }
920 else
921 tprintf("...}");
922 }
923 #endif /* SPARC64 */
924 #endif /* LINUXSPARC */
925
926 #if defined LINUX && defined POWERPC64
927 struct stat_powerpc32 {
928 unsigned int st_dev;
929 unsigned int st_ino;
930 unsigned int st_mode;
931 unsigned short st_nlink;
932 unsigned int st_uid;
933 unsigned int st_gid;
934 unsigned int st_rdev;
935 unsigned int st_size;
936 unsigned int st_blksize;
937 unsigned int st_blocks;
938 unsigned int st_atime;
939 unsigned int st_atime_nsec;
940 unsigned int st_mtime;
941 unsigned int st_mtime_nsec;
942 unsigned int st_ctime;
943 unsigned int st_ctime_nsec;
944 unsigned int __unused4;
945 unsigned int __unused5;
946 };
947
948 static void
printstat_powerpc32(struct tcb * tcp,long addr)949 printstat_powerpc32(struct tcb *tcp, long addr)
950 {
951 struct stat_powerpc32 statbuf;
952
953 if (umove(tcp, addr, &statbuf) < 0) {
954 tprintf("{...}");
955 return;
956 }
957
958 if (!abbrev(tcp)) {
959 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
960 major(statbuf.st_dev), minor(statbuf.st_dev),
961 statbuf.st_ino,
962 sprintmode(statbuf.st_mode));
963 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
964 statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
965 tprintf("st_blksize=%u, ", statbuf.st_blksize);
966 tprintf("st_blocks=%u, ", statbuf.st_blocks);
967 }
968 else
969 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
970 switch (statbuf.st_mode & S_IFMT) {
971 case S_IFCHR: case S_IFBLK:
972 tprintf("st_rdev=makedev(%lu, %lu), ",
973 (unsigned long) major(statbuf.st_rdev),
974 (unsigned long) minor(statbuf.st_rdev));
975 break;
976 default:
977 tprintf("st_size=%u, ", statbuf.st_size);
978 break;
979 }
980 if (!abbrev(tcp)) {
981 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
982 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
983 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
984 tprintf("}");
985 }
986 else
987 tprintf("...}");
988 }
989 #endif /* LINUX && POWERPC64 */
990
991 static const struct xlat fileflags[] = {
992 #ifdef FREEBSD
993 { UF_NODUMP, "UF_NODUMP" },
994 { UF_IMMUTABLE, "UF_IMMUTABLE" },
995 { UF_APPEND, "UF_APPEND" },
996 { UF_OPAQUE, "UF_OPAQUE" },
997 { UF_NOUNLINK, "UF_NOUNLINK" },
998 { SF_ARCHIVED, "SF_ARCHIVED" },
999 { SF_IMMUTABLE, "SF_IMMUTABLE" },
1000 { SF_APPEND, "SF_APPEND" },
1001 { SF_NOUNLINK, "SF_NOUNLINK" },
1002 #elif UNIXWARE >= 2
1003 #ifdef _S_ISMLD
1004 { _S_ISMLD, "_S_ISMLD" },
1005 #endif
1006 #ifdef _S_ISMOUNTED
1007 { _S_ISMOUNTED, "_S_ISMOUNTED" },
1008 #endif
1009 #endif
1010 { 0, NULL },
1011 };
1012
1013 #ifdef FREEBSD
1014 int
sys_chflags(struct tcb * tcp)1015 sys_chflags(struct tcb *tcp)
1016 {
1017 if (entering(tcp)) {
1018 printpath(tcp, tcp->u_arg[0]);
1019 tprintf(", ");
1020 printflags(fileflags, tcp->u_arg[1], "UF_???");
1021 }
1022 return 0;
1023 }
1024
1025 int
sys_fchflags(struct tcb * tcp)1026 sys_fchflags(struct tcb *tcp)
1027 {
1028 if (entering(tcp)) {
1029 tprintf("%ld, ", tcp->u_arg[0]);
1030 printflags(fileflags, tcp->u_arg[1], "UF_???");
1031 }
1032 return 0;
1033 }
1034 #endif
1035
1036 #ifndef HAVE_LONG_LONG_OFF_T
1037 static void
realprintstat(struct tcb * tcp,struct stat * statbuf)1038 realprintstat(struct tcb *tcp, struct stat *statbuf)
1039 {
1040 if (!abbrev(tcp)) {
1041 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
1042 (unsigned long) major(statbuf->st_dev),
1043 (unsigned long) minor(statbuf->st_dev),
1044 (unsigned long) statbuf->st_ino,
1045 sprintmode(statbuf->st_mode));
1046 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1047 (unsigned long) statbuf->st_nlink,
1048 (unsigned long) statbuf->st_uid,
1049 (unsigned long) statbuf->st_gid);
1050 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1051 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
1052 #endif
1053 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1054 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
1055 #endif
1056 }
1057 else
1058 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
1059 switch (statbuf->st_mode & S_IFMT) {
1060 case S_IFCHR: case S_IFBLK:
1061 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1062 tprintf("st_rdev=makedev(%lu, %lu), ",
1063 (unsigned long) major(statbuf->st_rdev),
1064 (unsigned long) minor(statbuf->st_rdev));
1065 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
1066 tprintf("st_size=makedev(%lu, %lu), ",
1067 (unsigned long) major(statbuf->st_size),
1068 (unsigned long) minor(statbuf->st_size));
1069 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
1070 break;
1071 default:
1072 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
1073 break;
1074 }
1075 if (!abbrev(tcp)) {
1076 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
1077 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
1078 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
1079 #if HAVE_STRUCT_STAT_ST_FLAGS
1080 tprintf(", st_flags=");
1081 printflags(fileflags, statbuf->st_flags, "UF_???");
1082 #endif
1083 #if HAVE_STRUCT_STAT_ST_ACLCNT
1084 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
1085 #endif
1086 #if HAVE_STRUCT_STAT_ST_LEVEL
1087 tprintf(", st_level=%ld", statbuf->st_level);
1088 #endif
1089 #if HAVE_STRUCT_STAT_ST_FSTYPE
1090 tprintf(", st_fstype=%.*s",
1091 (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
1092 #endif
1093 #if HAVE_STRUCT_STAT_ST_GEN
1094 tprintf(", st_gen=%u", statbuf->st_gen);
1095 #endif
1096 tprintf("}");
1097 }
1098 else
1099 tprintf("...}");
1100 }
1101
1102
1103 static void
printstat(struct tcb * tcp,long addr)1104 printstat(struct tcb *tcp, long addr)
1105 {
1106 struct stat statbuf;
1107
1108 if (!addr) {
1109 tprintf("NULL");
1110 return;
1111 }
1112 if (syserror(tcp) || !verbose(tcp)) {
1113 tprintf("%#lx", addr);
1114 return;
1115 }
1116
1117 #ifdef LINUXSPARC
1118 if (current_personality == 1) {
1119 printstatsol(tcp, addr);
1120 return;
1121 }
1122 #ifdef SPARC64
1123 else if (current_personality == 2) {
1124 printstat_sparc64(tcp, addr);
1125 return;
1126 }
1127 #endif
1128 #endif /* LINUXSPARC */
1129
1130 #if defined LINUX && defined POWERPC64
1131 if (current_personality == 1) {
1132 printstat_powerpc32(tcp, addr);
1133 return;
1134 }
1135 #endif
1136
1137 if (umove(tcp, addr, &statbuf) < 0) {
1138 tprintf("{...}");
1139 return;
1140 }
1141
1142 realprintstat(tcp, &statbuf);
1143 }
1144 #endif /* !HAVE_LONG_LONG_OFF_T */
1145
1146 #if !defined HAVE_STAT64 && defined LINUX && defined X86_64
1147 /*
1148 * Linux x86_64 has unified `struct stat' but its i386 biarch needs
1149 * `struct stat64'. Its <asm-i386/stat.h> definition expects 32-bit `long'.
1150 * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
1151 * __GNUC__ is needed for the required __attribute__ below.
1152 */
1153 struct stat64 {
1154 unsigned long long st_dev;
1155 unsigned char __pad0[4];
1156 unsigned int __st_ino;
1157 unsigned int st_mode;
1158 unsigned int st_nlink;
1159 unsigned int st_uid;
1160 unsigned int st_gid;
1161 unsigned long long st_rdev;
1162 unsigned char __pad3[4];
1163 long long st_size;
1164 unsigned int st_blksize;
1165 unsigned long long st_blocks;
1166 unsigned int st_atime;
1167 unsigned int st_atime_nsec;
1168 unsigned int st_mtime;
1169 unsigned int st_mtime_nsec;
1170 unsigned int st_ctime;
1171 unsigned int st_ctime_nsec;
1172 unsigned long long st_ino;
1173 } __attribute__((packed));
1174 # define HAVE_STAT64 1
1175 # define STAT64_SIZE 96
1176 #endif
1177
1178 #ifdef HAVE_STAT64
1179 static void
printstat64(struct tcb * tcp,long addr)1180 printstat64(struct tcb *tcp, long addr)
1181 {
1182 struct stat64 statbuf;
1183
1184 #ifdef STAT64_SIZE
1185 (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
1186 #endif
1187
1188 if (!addr) {
1189 tprintf("NULL");
1190 return;
1191 }
1192 if (syserror(tcp) || !verbose(tcp)) {
1193 tprintf("%#lx", addr);
1194 return;
1195 }
1196
1197 #ifdef LINUXSPARC
1198 if (current_personality == 1) {
1199 printstatsol(tcp, addr);
1200 return;
1201 }
1202 # ifdef SPARC64
1203 else if (current_personality == 2) {
1204 printstat_sparc64(tcp, addr);
1205 return;
1206 }
1207 # endif
1208 #endif /* LINUXSPARC */
1209
1210 #if defined LINUX && defined X86_64
1211 if (current_personality == 0) {
1212 printstat(tcp, addr);
1213 return;
1214 }
1215 #endif
1216
1217 if (umove(tcp, addr, &statbuf) < 0) {
1218 tprintf("{...}");
1219 return;
1220 }
1221
1222 if (!abbrev(tcp)) {
1223 #ifdef HAVE_LONG_LONG
1224 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1225 #else
1226 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
1227 #endif
1228 (unsigned long) major(statbuf.st_dev),
1229 (unsigned long) minor(statbuf.st_dev),
1230 #ifdef HAVE_LONG_LONG
1231 (unsigned long long) statbuf.st_ino,
1232 #else
1233 (unsigned long) statbuf.st_ino,
1234 #endif
1235 sprintmode(statbuf.st_mode));
1236 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1237 (unsigned long) statbuf.st_nlink,
1238 (unsigned long) statbuf.st_uid,
1239 (unsigned long) statbuf.st_gid);
1240 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1241 tprintf("st_blksize=%lu, ",
1242 (unsigned long) statbuf.st_blksize);
1243 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
1244 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1245 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1246 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
1247 }
1248 else
1249 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1250 switch (statbuf.st_mode & S_IFMT) {
1251 case S_IFCHR: case S_IFBLK:
1252 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1253 tprintf("st_rdev=makedev(%lu, %lu), ",
1254 (unsigned long) major(statbuf.st_rdev),
1255 (unsigned long) minor(statbuf.st_rdev));
1256 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
1257 tprintf("st_size=makedev(%lu, %lu), ",
1258 (unsigned long) major(statbuf.st_size),
1259 (unsigned long) minor(statbuf.st_size));
1260 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
1261 break;
1262 default:
1263 #ifdef HAVE_LONG_LONG
1264 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1265 #else
1266 tprintf("st_size=%lu, ", (unsigned long) statbuf.st_size);
1267 #endif
1268 break;
1269 }
1270 if (!abbrev(tcp)) {
1271 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1272 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1273 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1274 #if HAVE_STRUCT_STAT_ST_FLAGS
1275 tprintf(", st_flags=");
1276 printflags(fileflags, statbuf.st_flags, "UF_???");
1277 #endif
1278 #if HAVE_STRUCT_STAT_ST_ACLCNT
1279 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
1280 #endif
1281 #if HAVE_STRUCT_STAT_ST_LEVEL
1282 tprintf(", st_level=%ld", statbuf.st_level);
1283 #endif
1284 #if HAVE_STRUCT_STAT_ST_FSTYPE
1285 tprintf(", st_fstype=%.*s",
1286 (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
1287 #endif
1288 #if HAVE_STRUCT_STAT_ST_GEN
1289 tprintf(", st_gen=%u", statbuf.st_gen);
1290 #endif
1291 tprintf("}");
1292 }
1293 else
1294 tprintf("...}");
1295 }
1296 #endif /* HAVE_STAT64 */
1297
1298 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1299 static void
convertoldstat(const struct __old_kernel_stat * oldbuf,struct stat * newbuf)1300 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
1301 {
1302 newbuf->st_dev = oldbuf->st_dev;
1303 newbuf->st_ino = oldbuf->st_ino;
1304 newbuf->st_mode = oldbuf->st_mode;
1305 newbuf->st_nlink = oldbuf->st_nlink;
1306 newbuf->st_uid = oldbuf->st_uid;
1307 newbuf->st_gid = oldbuf->st_gid;
1308 newbuf->st_rdev = oldbuf->st_rdev;
1309 newbuf->st_size = oldbuf->st_size;
1310 newbuf->st_atime = oldbuf->st_atime;
1311 newbuf->st_mtime = oldbuf->st_mtime;
1312 newbuf->st_ctime = oldbuf->st_ctime;
1313 newbuf->st_blksize = 0; /* not supported in old_stat */
1314 newbuf->st_blocks = 0; /* not supported in old_stat */
1315 }
1316
1317
1318 static void
printoldstat(struct tcb * tcp,long addr)1319 printoldstat(struct tcb *tcp, long addr)
1320 {
1321 struct __old_kernel_stat statbuf;
1322 struct stat newstatbuf;
1323
1324 if (!addr) {
1325 tprintf("NULL");
1326 return;
1327 }
1328 if (syserror(tcp) || !verbose(tcp)) {
1329 tprintf("%#lx", addr);
1330 return;
1331 }
1332
1333 #ifdef LINUXSPARC
1334 if (current_personality == 1) {
1335 printstatsol(tcp, addr);
1336 return;
1337 }
1338 #endif /* LINUXSPARC */
1339
1340 if (umove(tcp, addr, &statbuf) < 0) {
1341 tprintf("{...}");
1342 return;
1343 }
1344
1345 convertoldstat(&statbuf, &newstatbuf);
1346 realprintstat(tcp, &newstatbuf);
1347 }
1348 #endif /* LINUX && !IA64 && !HPPA && !X86_64 && !S390 && !S390X */
1349
1350 #ifndef HAVE_LONG_LONG_OFF_T
1351 int
sys_stat(struct tcb * tcp)1352 sys_stat(struct tcb *tcp)
1353 {
1354 if (entering(tcp)) {
1355 printpath(tcp, tcp->u_arg[0]);
1356 tprintf(", ");
1357 } else {
1358 printstat(tcp, tcp->u_arg[1]);
1359 }
1360 return 0;
1361 }
1362 #endif
1363
1364 int
sys_stat64(struct tcb * tcp)1365 sys_stat64(struct tcb *tcp)
1366 {
1367 #ifdef HAVE_STAT64
1368 if (entering(tcp)) {
1369 printpath(tcp, tcp->u_arg[0]);
1370 tprintf(", ");
1371 } else {
1372 printstat64(tcp, tcp->u_arg[1]);
1373 }
1374 return 0;
1375 #else
1376 return printargs(tcp);
1377 #endif
1378 }
1379
1380 #ifdef LINUX
1381 static const struct xlat fstatatflags[] = {
1382 #ifndef AT_SYMLINK_NOFOLLOW
1383 # define AT_SYMLINK_NOFOLLOW 0x100
1384 #endif
1385 { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
1386 { 0, NULL },
1387 };
1388 #define utimensatflags fstatatflags
1389
1390 int
sys_newfstatat(struct tcb * tcp)1391 sys_newfstatat(struct tcb *tcp)
1392 {
1393 if (entering(tcp)) {
1394 print_dirfd(tcp, tcp->u_arg[0]);
1395 printpath(tcp, tcp->u_arg[1]);
1396 tprintf(", ");
1397 } else {
1398 #ifdef POWERPC64
1399 if (current_personality == 0)
1400 printstat(tcp, tcp->u_arg[2]);
1401 else
1402 printstat64(tcp, tcp->u_arg[2]);
1403 #elif defined HAVE_STAT64
1404 printstat64(tcp, tcp->u_arg[2]);
1405 #else
1406 printstat(tcp, tcp->u_arg[2]);
1407 #endif
1408 tprintf(", ");
1409 printflags(fstatatflags, tcp->u_arg[3], "AT_???");
1410 }
1411 return 0;
1412 }
1413 #endif
1414
1415 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1416 int
sys_oldstat(struct tcb * tcp)1417 sys_oldstat(struct tcb *tcp)
1418 {
1419 if (entering(tcp)) {
1420 printpath(tcp, tcp->u_arg[0]);
1421 tprintf(", ");
1422 } else {
1423 printoldstat(tcp, tcp->u_arg[1]);
1424 }
1425 return 0;
1426 }
1427 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1428
1429 #ifndef HAVE_LONG_LONG_OFF_T
1430 int
sys_fstat(struct tcb * tcp)1431 sys_fstat(struct tcb *tcp)
1432 {
1433 if (entering(tcp)) {
1434 printfd(tcp, tcp->u_arg[0]);
1435 tprintf(", ");
1436 } else {
1437 printstat(tcp, tcp->u_arg[1]);
1438 }
1439 return 0;
1440 }
1441 #endif
1442
1443 int
sys_fstat64(struct tcb * tcp)1444 sys_fstat64(struct tcb *tcp)
1445 {
1446 #ifdef HAVE_STAT64
1447 if (entering(tcp)) {
1448 printfd(tcp, tcp->u_arg[0]);
1449 tprintf(", ");
1450 } else {
1451 printstat64(tcp, tcp->u_arg[1]);
1452 }
1453 return 0;
1454 #else
1455 return printargs(tcp);
1456 #endif
1457 }
1458
1459 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1460 int
sys_oldfstat(struct tcb * tcp)1461 sys_oldfstat(struct tcb *tcp)
1462 {
1463 if (entering(tcp)) {
1464 printfd(tcp, tcp->u_arg[0]);
1465 tprintf(", ");
1466 } else {
1467 printoldstat(tcp, tcp->u_arg[1]);
1468 }
1469 return 0;
1470 }
1471 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1472
1473 #ifndef HAVE_LONG_LONG_OFF_T
1474 int
sys_lstat(struct tcb * tcp)1475 sys_lstat(struct tcb *tcp)
1476 {
1477 if (entering(tcp)) {
1478 printpath(tcp, tcp->u_arg[0]);
1479 tprintf(", ");
1480 } else {
1481 printstat(tcp, tcp->u_arg[1]);
1482 }
1483 return 0;
1484 }
1485 #endif
1486
1487 int
sys_lstat64(struct tcb * tcp)1488 sys_lstat64(struct tcb *tcp)
1489 {
1490 #ifdef HAVE_STAT64
1491 if (entering(tcp)) {
1492 printpath(tcp, tcp->u_arg[0]);
1493 tprintf(", ");
1494 } else {
1495 printstat64(tcp, tcp->u_arg[1]);
1496 }
1497 return 0;
1498 #else
1499 return printargs(tcp);
1500 #endif
1501 }
1502
1503 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1504 int
sys_oldlstat(struct tcb * tcp)1505 sys_oldlstat(struct tcb *tcp)
1506 {
1507 if (entering(tcp)) {
1508 printpath(tcp, tcp->u_arg[0]);
1509 tprintf(", ");
1510 } else {
1511 printoldstat(tcp, tcp->u_arg[1]);
1512 }
1513 return 0;
1514 }
1515 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1516
1517
1518 #if defined(SVR4) || defined(LINUXSPARC)
1519
1520 int
sys_xstat(struct tcb * tcp)1521 sys_xstat(struct tcb *tcp)
1522 {
1523 if (entering(tcp)) {
1524 tprintf("%ld, ", tcp->u_arg[0]);
1525 printpath(tcp, tcp->u_arg[1]);
1526 tprintf(", ");
1527 } else {
1528 #ifdef _STAT64_VER
1529 if (tcp->u_arg[0] == _STAT64_VER)
1530 printstat64 (tcp, tcp->u_arg[2]);
1531 else
1532 #endif
1533 printstat(tcp, tcp->u_arg[2]);
1534 }
1535 return 0;
1536 }
1537
1538 int
sys_fxstat(struct tcb * tcp)1539 sys_fxstat(struct tcb *tcp)
1540 {
1541 if (entering(tcp))
1542 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1543 else {
1544 #ifdef _STAT64_VER
1545 if (tcp->u_arg[0] == _STAT64_VER)
1546 printstat64 (tcp, tcp->u_arg[2]);
1547 else
1548 #endif
1549 printstat(tcp, tcp->u_arg[2]);
1550 }
1551 return 0;
1552 }
1553
1554 int
sys_lxstat(struct tcb * tcp)1555 sys_lxstat(struct tcb *tcp)
1556 {
1557 if (entering(tcp)) {
1558 tprintf("%ld, ", tcp->u_arg[0]);
1559 printpath(tcp, tcp->u_arg[1]);
1560 tprintf(", ");
1561 } else {
1562 #ifdef _STAT64_VER
1563 if (tcp->u_arg[0] == _STAT64_VER)
1564 printstat64 (tcp, tcp->u_arg[2]);
1565 else
1566 #endif
1567 printstat(tcp, tcp->u_arg[2]);
1568 }
1569 return 0;
1570 }
1571
1572 int
sys_xmknod(struct tcb * tcp)1573 sys_xmknod(struct tcb *tcp)
1574 {
1575 int mode = tcp->u_arg[2];
1576
1577 if (entering(tcp)) {
1578 tprintf("%ld, ", tcp->u_arg[0]);
1579 printpath(tcp, tcp->u_arg[1]);
1580 tprintf(", %s", sprintmode(mode));
1581 switch (mode & S_IFMT) {
1582 case S_IFCHR: case S_IFBLK:
1583 #ifdef LINUXSPARC
1584 tprintf(", makedev(%lu, %lu)",
1585 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
1586 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
1587 #else
1588 tprintf(", makedev(%lu, %lu)",
1589 (unsigned long) major(tcp->u_arg[3]),
1590 (unsigned long) minor(tcp->u_arg[3]));
1591 #endif
1592 break;
1593 default:
1594 break;
1595 }
1596 }
1597 return 0;
1598 }
1599
1600 #ifdef HAVE_SYS_ACL_H
1601
1602 #include <sys/acl.h>
1603
1604 static const struct xlat aclcmds[] = {
1605 #ifdef SETACL
1606 { SETACL, "SETACL" },
1607 #endif
1608 #ifdef GETACL
1609 { GETACL, "GETACL" },
1610 #endif
1611 #ifdef GETACLCNT
1612 { GETACLCNT, "GETACLCNT" },
1613 #endif
1614 #ifdef ACL_GET
1615 { ACL_GET, "ACL_GET" },
1616 #endif
1617 #ifdef ACL_SET
1618 { ACL_SET, "ACL_SET" },
1619 #endif
1620 #ifdef ACL_CNT
1621 { ACL_CNT, "ACL_CNT" },
1622 #endif
1623 { 0, NULL },
1624 };
1625
1626 int
sys_acl(struct tcb * tcp)1627 sys_acl(struct tcb *tcp)
1628 {
1629 if (entering(tcp)) {
1630 printpath(tcp, tcp->u_arg[0]);
1631 tprintf(", ");
1632 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1633 tprintf(", %ld", tcp->u_arg[2]);
1634 /*
1635 * FIXME - dump out the list of aclent_t's pointed to
1636 * by "tcp->u_arg[3]" if it's not NULL.
1637 */
1638 if (tcp->u_arg[3])
1639 tprintf(", %#lx", tcp->u_arg[3]);
1640 else
1641 tprintf(", NULL");
1642 }
1643 return 0;
1644 }
1645
1646
1647 int
sys_facl(struct tcb * tcp)1648 sys_facl(struct tcb *tcp)
1649 {
1650 if (entering(tcp)) {
1651 tprintf("%ld, ", tcp->u_arg[0]);
1652 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1653 tprintf(", %ld", tcp->u_arg[2]);
1654 /*
1655 * FIXME - dump out the list of aclent_t's pointed to
1656 * by "tcp->u_arg[3]" if it's not NULL.
1657 */
1658 if (tcp->u_arg[3])
1659 tprintf(", %#lx", tcp->u_arg[3]);
1660 else
1661 tprintf(", NULL");
1662 }
1663 return 0;
1664 }
1665
1666
1667 static const struct xlat aclipc[] = {
1668 #ifdef IPC_SHM
1669 { IPC_SHM, "IPC_SHM" },
1670 #endif
1671 #ifdef IPC_SEM
1672 { IPC_SEM, "IPC_SEM" },
1673 #endif
1674 #ifdef IPC_MSG
1675 { IPC_MSG, "IPC_MSG" },
1676 #endif
1677 { 0, NULL },
1678 };
1679
1680
1681 int
sys_aclipc(struct tcb * tcp)1682 sys_aclipc(struct tcb *tcp)
1683 {
1684 if (entering(tcp)) {
1685 printxval(aclipc, tcp->u_arg[0], "???IPC???");
1686 tprintf(", %#lx, ", tcp->u_arg[1]);
1687 printxval(aclcmds, tcp->u_arg[2], "???ACL???");
1688 tprintf(", %ld", tcp->u_arg[3]);
1689 /*
1690 * FIXME - dump out the list of aclent_t's pointed to
1691 * by "tcp->u_arg[4]" if it's not NULL.
1692 */
1693 if (tcp->u_arg[4])
1694 tprintf(", %#lx", tcp->u_arg[4]);
1695 else
1696 tprintf(", NULL");
1697 }
1698 return 0;
1699 }
1700
1701 #endif /* HAVE_SYS_ACL_H */
1702
1703 #endif /* SVR4 || LINUXSPARC */
1704
1705 #ifdef LINUX
1706
1707 static const struct xlat fsmagic[] = {
1708 { 0x73757245, "CODA_SUPER_MAGIC" },
1709 { 0x012ff7b7, "COH_SUPER_MAGIC" },
1710 { 0x1373, "DEVFS_SUPER_MAGIC" },
1711 { 0x1cd1, "DEVPTS_SUPER_MAGIC" },
1712 { 0x414A53, "EFS_SUPER_MAGIC" },
1713 { 0xef51, "EXT2_OLD_SUPER_MAGIC" },
1714 { 0xef53, "EXT2_SUPER_MAGIC" },
1715 { 0x137d, "EXT_SUPER_MAGIC" },
1716 { 0xf995e849, "HPFS_SUPER_MAGIC" },
1717 { 0x9660, "ISOFS_SUPER_MAGIC" },
1718 { 0x137f, "MINIX_SUPER_MAGIC" },
1719 { 0x138f, "MINIX_SUPER_MAGIC2" },
1720 { 0x2468, "MINIX2_SUPER_MAGIC" },
1721 { 0x2478, "MINIX2_SUPER_MAGIC2" },
1722 { 0x4d44, "MSDOS_SUPER_MAGIC" },
1723 { 0x564c, "NCP_SUPER_MAGIC" },
1724 { 0x6969, "NFS_SUPER_MAGIC" },
1725 { 0x9fa0, "PROC_SUPER_MAGIC" },
1726 { 0x002f, "QNX4_SUPER_MAGIC" },
1727 { 0x52654973, "REISERFS_SUPER_MAGIC" },
1728 { 0x02011994, "SHMFS_SUPER_MAGIC" },
1729 { 0x517b, "SMB_SUPER_MAGIC" },
1730 { 0x012ff7b6, "SYSV2_SUPER_MAGIC" },
1731 { 0x012ff7b5, "SYSV4_SUPER_MAGIC" },
1732 { 0x00011954, "UFS_MAGIC" },
1733 { 0x54190100, "UFS_CIGAM" },
1734 { 0x012ff7b4, "XENIX_SUPER_MAGIC" },
1735 { 0x012fd16d, "XIAFS_SUPER_MAGIC" },
1736 { 0x62656572, "SYSFS_MAGIC" },
1737 { 0, NULL },
1738 };
1739
1740 #endif /* LINUX */
1741
1742 #ifndef SVR4
1743
1744 static const char *
sprintfstype(int magic)1745 sprintfstype(int magic)
1746 {
1747 static char buf[32];
1748 #ifdef LINUX
1749 const char *s;
1750
1751 s = xlookup(fsmagic, magic);
1752 if (s) {
1753 sprintf(buf, "\"%s\"", s);
1754 return buf;
1755 }
1756 #endif /* LINUX */
1757 sprintf(buf, "%#x", magic);
1758 return buf;
1759 }
1760
1761 static void
printstatfs(struct tcb * tcp,long addr)1762 printstatfs(struct tcb *tcp, long addr)
1763 {
1764 struct statfs statbuf;
1765
1766 if (syserror(tcp) || !verbose(tcp)) {
1767 tprintf("%#lx", addr);
1768 return;
1769 }
1770 if (umove(tcp, addr, &statbuf) < 0) {
1771 tprintf("{...}");
1772 return;
1773 }
1774 #ifdef ALPHA
1775
1776 tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
1777 sprintfstype(statbuf.f_type),
1778 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
1779 tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u",
1780 statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree,
1781 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1],
1782 statbuf.f_namelen);
1783 #else /* !ALPHA */
1784 tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
1785 sprintfstype(statbuf.f_type),
1786 (unsigned long)statbuf.f_bsize,
1787 (unsigned long)statbuf.f_blocks,
1788 (unsigned long)statbuf.f_bfree);
1789 #ifdef MIPS
1790 tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%ld, %ld}",
1791 (unsigned long)statbuf.f_bavail,
1792 (unsigned long)statbuf.f_files,
1793 (unsigned long)statbuf.f_ffree,
1794 statbuf.f_fsid.val[0], statbuf.f_fsid.val[1]);
1795 #else
1796 tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
1797 (unsigned long)statbuf.f_bavail,
1798 (unsigned long)statbuf.f_files,
1799 (unsigned long)statbuf.f_ffree,
1800 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1801 #endif
1802 #ifdef LINUX
1803 tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1804 #endif /* LINUX */
1805 #endif /* !ALPHA */
1806 #ifdef _STATFS_F_FRSIZE
1807 tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1808 #endif
1809 tprintf("}");
1810 }
1811
1812 int
sys_statfs(struct tcb * tcp)1813 sys_statfs(struct tcb *tcp)
1814 {
1815 if (entering(tcp)) {
1816 printpath(tcp, tcp->u_arg[0]);
1817 tprintf(", ");
1818 } else {
1819 printstatfs(tcp, tcp->u_arg[1]);
1820 }
1821 return 0;
1822 }
1823
1824 int
sys_fstatfs(struct tcb * tcp)1825 sys_fstatfs(struct tcb *tcp)
1826 {
1827 if (entering(tcp)) {
1828 printfd(tcp, tcp->u_arg[0]);
1829 tprintf(", ");
1830 } else {
1831 printstatfs(tcp, tcp->u_arg[1]);
1832 }
1833 return 0;
1834 }
1835
1836 #if defined LINUX && defined HAVE_STATFS64
1837 static void
printstatfs64(struct tcb * tcp,long addr)1838 printstatfs64(struct tcb *tcp, long addr)
1839 {
1840 struct statfs64 statbuf;
1841
1842 if (syserror(tcp) || !verbose(tcp)) {
1843 tprintf("%#lx", addr);
1844 return;
1845 }
1846 if (umove(tcp, addr, &statbuf) < 0) {
1847 tprintf("{...}");
1848 return;
1849 }
1850 tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
1851 sprintfstype(statbuf.f_type),
1852 (unsigned long long)statbuf.f_bsize,
1853 (unsigned long long)statbuf.f_blocks,
1854 (unsigned long long)statbuf.f_bfree);
1855 #ifdef MIPS
1856 tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%ld, %ld}",
1857 (unsigned long long)statbuf.f_bavail,
1858 (unsigned long long)statbuf.f_files,
1859 (unsigned long long)statbuf.f_ffree,
1860 statbuf.f_fsid.val[0], statbuf.f_fsid.val[1]);
1861 #else
1862 tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
1863 (unsigned long long)statbuf.f_bavail,
1864 (unsigned long long)statbuf.f_files,
1865 (unsigned long long)statbuf.f_ffree,
1866 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1867 #endif
1868 tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1869 #ifdef _STATFS_F_FRSIZE
1870 tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
1871 #endif
1872 tprintf("}");
1873 }
1874
1875 int
sys_statfs64(struct tcb * tcp)1876 sys_statfs64(struct tcb *tcp)
1877 {
1878 if (entering(tcp)) {
1879 printpath(tcp, tcp->u_arg[0]);
1880 tprintf(", %lu, ", tcp->u_arg[1]);
1881 } else {
1882 if (tcp->u_arg[1] == sizeof (struct statfs64))
1883 printstatfs64(tcp, tcp->u_arg[2]);
1884 else
1885 tprintf("{???}");
1886 }
1887 return 0;
1888 }
1889
1890 int
sys_fstatfs64(struct tcb * tcp)1891 sys_fstatfs64(struct tcb *tcp)
1892 {
1893 if (entering(tcp)) {
1894 printfd(tcp, tcp->u_arg[0]);
1895 tprintf(", %lu, ", tcp->u_arg[1]);
1896 } else {
1897 if (tcp->u_arg[1] == sizeof (struct statfs64))
1898 printstatfs64(tcp, tcp->u_arg[2]);
1899 else
1900 tprintf("{???}");
1901 }
1902 return 0;
1903 }
1904 #endif
1905
1906 #if defined(LINUX) && defined(__alpha)
1907
1908 int
osf_statfs(struct tcb * tcp)1909 osf_statfs(struct tcb *tcp)
1910 {
1911 if (entering(tcp)) {
1912 printpath(tcp, tcp->u_arg[0]);
1913 tprintf(", ");
1914 } else {
1915 printstatfs(tcp, tcp->u_arg[1]);
1916 tprintf(", %lu", tcp->u_arg[2]);
1917 }
1918 return 0;
1919 }
1920
1921 int
osf_fstatfs(struct tcb * tcp)1922 osf_fstatfs(struct tcb *tcp)
1923 {
1924 if (entering(tcp)) {
1925 tprintf("%lu, ", tcp->u_arg[0]);
1926 } else {
1927 printstatfs(tcp, tcp->u_arg[1]);
1928 tprintf(", %lu", tcp->u_arg[2]);
1929 }
1930 return 0;
1931 }
1932 #endif /* LINUX && __alpha */
1933
1934 #endif /* !SVR4 */
1935
1936 #ifdef SUNOS4
1937 int
sys_ustat(struct tcb * tcp)1938 sys_ustat(struct tcb *tcp)
1939 {
1940 struct ustat statbuf;
1941
1942 if (entering(tcp)) {
1943 tprintf("makedev(%lu, %lu), ",
1944 (long) major(tcp->u_arg[0]),
1945 (long) minor(tcp->u_arg[0]));
1946 }
1947 else {
1948 if (syserror(tcp) || !verbose(tcp))
1949 tprintf("%#lx", tcp->u_arg[1]);
1950 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
1951 tprintf("{...}");
1952 else {
1953 tprintf("{f_tfree=%lu, f_tinode=%lu, ",
1954 statbuf.f_tfree, statbuf.f_tinode);
1955 tprintf("f_fname=\"%.*s\", ",
1956 (int) sizeof(statbuf.f_fname),
1957 statbuf.f_fname);
1958 tprintf("f_fpack=\"%.*s\"}",
1959 (int) sizeof(statbuf.f_fpack),
1960 statbuf.f_fpack);
1961 }
1962 }
1963 return 0;
1964 }
1965 #endif /* SUNOS4 */
1966
1967 int
sys_pivotroot(struct tcb * tcp)1968 sys_pivotroot(struct tcb *tcp)
1969 {
1970 if (entering(tcp)) {
1971 printpath(tcp, tcp->u_arg[0]);
1972 tprintf(", ");
1973 printpath(tcp, tcp->u_arg[1]);
1974 }
1975 return 0;
1976 }
1977
1978
1979 /* directory */
1980 int
sys_chdir(struct tcb * tcp)1981 sys_chdir(struct tcb *tcp)
1982 {
1983 if (entering(tcp)) {
1984 printpath(tcp, tcp->u_arg[0]);
1985 }
1986 return 0;
1987 }
1988
1989 static int
decode_mkdir(struct tcb * tcp,int offset)1990 decode_mkdir(struct tcb *tcp, int offset)
1991 {
1992 if (entering(tcp)) {
1993 printpath(tcp, tcp->u_arg[offset]);
1994 tprintf(", %#lo", tcp->u_arg[offset + 1]);
1995 }
1996 return 0;
1997 }
1998
1999 int
sys_mkdir(struct tcb * tcp)2000 sys_mkdir(struct tcb *tcp)
2001 {
2002 return decode_mkdir(tcp, 0);
2003 }
2004
2005 #ifdef LINUX
2006 int
sys_mkdirat(struct tcb * tcp)2007 sys_mkdirat(struct tcb *tcp)
2008 {
2009 if (entering(tcp))
2010 print_dirfd(tcp, tcp->u_arg[0]);
2011 return decode_mkdir(tcp, 1);
2012 }
2013 #endif
2014
2015 int
sys_rmdir(struct tcb * tcp)2016 sys_rmdir(struct tcb *tcp)
2017 {
2018 if (entering(tcp)) {
2019 printpath(tcp, tcp->u_arg[0]);
2020 }
2021 return 0;
2022 }
2023
2024 int
sys_fchdir(struct tcb * tcp)2025 sys_fchdir(struct tcb *tcp)
2026 {
2027 if (entering(tcp)) {
2028 printfd(tcp, tcp->u_arg[0]);
2029 }
2030 return 0;
2031 }
2032
2033 int
sys_chroot(struct tcb * tcp)2034 sys_chroot(struct tcb *tcp)
2035 {
2036 if (entering(tcp)) {
2037 printpath(tcp, tcp->u_arg[0]);
2038 }
2039 return 0;
2040 }
2041
2042 #if defined(SUNOS4) || defined(SVR4)
2043 int
sys_fchroot(struct tcb * tcp)2044 sys_fchroot(struct tcb *tcp)
2045 {
2046 if (entering(tcp)) {
2047 printfd(tcp, tcp->u_arg[0]);
2048 }
2049 return 0;
2050 }
2051 #endif /* SUNOS4 || SVR4 */
2052
2053 int
sys_link(struct tcb * tcp)2054 sys_link(struct tcb *tcp)
2055 {
2056 if (entering(tcp)) {
2057 printpath(tcp, tcp->u_arg[0]);
2058 tprintf(", ");
2059 printpath(tcp, tcp->u_arg[1]);
2060 }
2061 return 0;
2062 }
2063
2064 #ifdef LINUX
2065 int
sys_linkat(struct tcb * tcp)2066 sys_linkat(struct tcb *tcp)
2067 {
2068 if (entering(tcp)) {
2069 print_dirfd(tcp, tcp->u_arg[0]);
2070 printpath(tcp, tcp->u_arg[1]);
2071 tprintf(", ");
2072 print_dirfd(tcp, tcp->u_arg[2]);
2073 printpath(tcp, tcp->u_arg[3]);
2074 tprintf(", ");
2075 printfd(tcp, tcp->u_arg[4]);
2076 }
2077 return 0;
2078 }
2079 #endif
2080
2081 int
sys_unlink(struct tcb * tcp)2082 sys_unlink(struct tcb *tcp)
2083 {
2084 if (entering(tcp)) {
2085 printpath(tcp, tcp->u_arg[0]);
2086 }
2087 return 0;
2088 }
2089
2090 #ifdef LINUX
2091 static const struct xlat unlinkatflags[] = {
2092 #ifndef AT_REMOVEDIR
2093 # define AT_REMOVEDIR 0x200
2094 #endif
2095 { AT_REMOVEDIR, "AT_REMOVEDIR" },
2096 { 0, NULL },
2097 };
2098
2099 int
sys_unlinkat(struct tcb * tcp)2100 sys_unlinkat(struct tcb *tcp)
2101 {
2102 if (entering(tcp)) {
2103 print_dirfd(tcp, tcp->u_arg[0]);
2104 printpath(tcp, tcp->u_arg[1]);
2105 tprintf(", ");
2106 printflags(unlinkatflags, tcp->u_arg[2], "AT_???");
2107 }
2108 return 0;
2109 }
2110 #endif
2111
2112 int
sys_symlink(struct tcb * tcp)2113 sys_symlink(struct tcb *tcp)
2114 {
2115 if (entering(tcp)) {
2116 printpath(tcp, tcp->u_arg[0]);
2117 tprintf(", ");
2118 printpath(tcp, tcp->u_arg[1]);
2119 }
2120 return 0;
2121 }
2122
2123 #ifdef LINUX
2124 int
sys_symlinkat(struct tcb * tcp)2125 sys_symlinkat(struct tcb *tcp)
2126 {
2127 if (entering(tcp)) {
2128 printpath(tcp, tcp->u_arg[0]);
2129 tprintf(", ");
2130 print_dirfd(tcp, tcp->u_arg[1]);
2131 printpath(tcp, tcp->u_arg[2]);
2132 }
2133 return 0;
2134 }
2135 #endif
2136
2137 static int
decode_readlink(struct tcb * tcp,int offset)2138 decode_readlink(struct tcb *tcp, int offset)
2139 {
2140 if (entering(tcp)) {
2141 printpath(tcp, tcp->u_arg[offset]);
2142 tprintf(", ");
2143 } else {
2144 if (syserror(tcp))
2145 tprintf("%#lx", tcp->u_arg[offset + 1]);
2146 else
2147 printpathn(tcp, tcp->u_arg[offset + 1], tcp->u_rval);
2148 tprintf(", %lu", tcp->u_arg[offset + 2]);
2149 }
2150 return 0;
2151 }
2152
2153 int
sys_readlink(struct tcb * tcp)2154 sys_readlink(struct tcb *tcp)
2155 {
2156 return decode_readlink(tcp, 0);
2157 }
2158
2159 #ifdef LINUX
2160 int
sys_readlinkat(struct tcb * tcp)2161 sys_readlinkat(struct tcb *tcp)
2162 {
2163 if (entering(tcp))
2164 print_dirfd(tcp, tcp->u_arg[0]);
2165 return decode_readlink(tcp, 1);
2166 }
2167 #endif
2168
2169 int
sys_rename(struct tcb * tcp)2170 sys_rename(struct tcb *tcp)
2171 {
2172 if (entering(tcp)) {
2173 printpath(tcp, tcp->u_arg[0]);
2174 tprintf(", ");
2175 printpath(tcp, tcp->u_arg[1]);
2176 }
2177 return 0;
2178 }
2179
2180 #ifdef LINUX
2181 int
sys_renameat(struct tcb * tcp)2182 sys_renameat(struct tcb *tcp)
2183 {
2184 if (entering(tcp)) {
2185 print_dirfd(tcp, tcp->u_arg[0]);
2186 printpath(tcp, tcp->u_arg[1]);
2187 tprintf(", ");
2188 print_dirfd(tcp, tcp->u_arg[2]);
2189 printpath(tcp, tcp->u_arg[3]);
2190 }
2191 return 0;
2192 }
2193 #endif
2194
2195 int
sys_chown(struct tcb * tcp)2196 sys_chown(struct tcb *tcp)
2197 {
2198 if (entering(tcp)) {
2199 printpath(tcp, tcp->u_arg[0]);
2200 printuid(", ", tcp->u_arg[1]);
2201 printuid(", ", tcp->u_arg[2]);
2202 }
2203 return 0;
2204 }
2205
2206 #ifdef LINUX
2207 int
sys_fchownat(struct tcb * tcp)2208 sys_fchownat(struct tcb *tcp)
2209 {
2210 if (entering(tcp)) {
2211 print_dirfd(tcp, tcp->u_arg[0]);
2212 printpath(tcp, tcp->u_arg[1]);
2213 printuid(", ", tcp->u_arg[2]);
2214 printuid(", ", tcp->u_arg[3]);
2215 tprintf(", ");
2216 printflags(fstatatflags, tcp->u_arg[4], "AT_???");
2217 }
2218 return 0;
2219 }
2220 #endif
2221
2222 int
sys_fchown(struct tcb * tcp)2223 sys_fchown(struct tcb *tcp)
2224 {
2225 if (entering(tcp)) {
2226 printfd(tcp, tcp->u_arg[0]);
2227 printuid(", ", tcp->u_arg[1]);
2228 printuid(", ", tcp->u_arg[2]);
2229 }
2230 return 0;
2231 }
2232
2233 static int
decode_chmod(struct tcb * tcp,int offset)2234 decode_chmod(struct tcb *tcp, int offset)
2235 {
2236 if (entering(tcp)) {
2237 printpath(tcp, tcp->u_arg[offset]);
2238 tprintf(", %#lo", tcp->u_arg[offset + 1]);
2239 }
2240 return 0;
2241 }
2242
2243 int
sys_chmod(struct tcb * tcp)2244 sys_chmod(struct tcb *tcp)
2245 {
2246 return decode_chmod(tcp, 0);
2247 }
2248
2249 #ifdef LINUX
2250 int
sys_fchmodat(struct tcb * tcp)2251 sys_fchmodat(struct tcb *tcp)
2252 {
2253 if (entering(tcp))
2254 print_dirfd(tcp, tcp->u_arg[0]);
2255 return decode_chmod(tcp, 1);
2256 }
2257 #endif
2258
2259 int
sys_fchmod(struct tcb * tcp)2260 sys_fchmod(struct tcb *tcp)
2261 {
2262 if (entering(tcp)) {
2263 printfd(tcp, tcp->u_arg[0]);
2264 tprintf(", %#lo", tcp->u_arg[1]);
2265 }
2266 return 0;
2267 }
2268
2269 #ifdef ALPHA
2270 int
sys_osf_utimes(struct tcb * tcp)2271 sys_osf_utimes(struct tcb *tcp)
2272 {
2273 if (entering(tcp)) {
2274 printpath(tcp, tcp->u_arg[0]);
2275 tprintf(", ");
2276 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
2277 }
2278 return 0;
2279 }
2280 #endif
2281
2282 static int
decode_utimes(struct tcb * tcp,int offset,int special)2283 decode_utimes(struct tcb *tcp, int offset, int special)
2284 {
2285 if (entering(tcp)) {
2286 printpath(tcp, tcp->u_arg[offset]);
2287 tprintf(", ");
2288 if (tcp->u_arg[offset + 1] == 0)
2289 tprintf("NULL");
2290 else {
2291 tprintf("{");
2292 printtv_bitness(tcp, tcp->u_arg[offset + 1],
2293 BITNESS_CURRENT, special);
2294 tprintf(", ");
2295 printtv_bitness(tcp, tcp->u_arg[offset + 1]
2296 + sizeof (struct timeval),
2297 BITNESS_CURRENT, special);
2298 tprintf("}");
2299 }
2300 }
2301 return 0;
2302 }
2303
2304 int
sys_utimes(struct tcb * tcp)2305 sys_utimes(struct tcb *tcp)
2306 {
2307 return decode_utimes(tcp, 0, 0);
2308 }
2309
2310 #ifdef LINUX
2311 int
sys_futimesat(struct tcb * tcp)2312 sys_futimesat(struct tcb *tcp)
2313 {
2314 if (entering(tcp))
2315 print_dirfd(tcp, tcp->u_arg[0]);
2316 return decode_utimes(tcp, 1, 0);
2317 }
2318
2319 int
sys_utimensat(struct tcb * tcp)2320 sys_utimensat(struct tcb *tcp)
2321 {
2322 if (entering(tcp)) {
2323 print_dirfd(tcp, tcp->u_arg[0]);
2324 decode_utimes(tcp, 1, 1);
2325 tprintf(", ");
2326 printflags(utimensatflags, tcp->u_arg[3], "AT_???");
2327 }
2328 return 0;
2329 }
2330 #endif
2331
2332 int
sys_utime(struct tcb * tcp)2333 sys_utime(struct tcb *tcp)
2334 {
2335 union {
2336 long utl[2];
2337 int uti[2];
2338 } u;
2339
2340 if (entering(tcp)) {
2341 printpath(tcp, tcp->u_arg[0]);
2342 tprintf(", ");
2343 if (!tcp->u_arg[1])
2344 tprintf("NULL");
2345 else if (!verbose(tcp))
2346 tprintf("%#lx", tcp->u_arg[1]);
2347 else if (umoven(tcp, tcp->u_arg[1],
2348 2 * personality_wordsize[current_personality],
2349 (char *) &u) < 0)
2350 tprintf("[?, ?]");
2351 else if (personality_wordsize[current_personality]
2352 == sizeof u.utl[0]) {
2353 tprintf("[%s,", sprinttime(u.utl[0]));
2354 tprintf(" %s]", sprinttime(u.utl[1]));
2355 }
2356 else if (personality_wordsize[current_personality]
2357 == sizeof u.uti[0]) {
2358 tprintf("[%s,", sprinttime(u.uti[0]));
2359 tprintf(" %s]", sprinttime(u.uti[1]));
2360 }
2361 else
2362 abort();
2363 }
2364 return 0;
2365 }
2366
2367 static int
decode_mknod(struct tcb * tcp,int offset)2368 decode_mknod(struct tcb *tcp, int offset)
2369 {
2370 int mode = tcp->u_arg[offset + 1];
2371
2372 if (entering(tcp)) {
2373 printpath(tcp, tcp->u_arg[offset]);
2374 tprintf(", %s", sprintmode(mode));
2375 switch (mode & S_IFMT) {
2376 case S_IFCHR: case S_IFBLK:
2377 #ifdef LINUXSPARC
2378 if (current_personality == 1)
2379 tprintf(", makedev(%lu, %lu)",
2380 (unsigned long) ((tcp->u_arg[offset + 2] >> 18) & 0x3fff),
2381 (unsigned long) (tcp->u_arg[offset + 2] & 0x3ffff));
2382 else
2383 #endif
2384 tprintf(", makedev(%lu, %lu)",
2385 (unsigned long) major(tcp->u_arg[offset + 2]),
2386 (unsigned long) minor(tcp->u_arg[offset + 2]));
2387 break;
2388 default:
2389 break;
2390 }
2391 }
2392 return 0;
2393 }
2394
2395 int
sys_mknod(struct tcb * tcp)2396 sys_mknod(struct tcb *tcp)
2397 {
2398 return decode_mknod(tcp, 0);
2399 }
2400
2401 #ifdef LINUX
2402 int
sys_mknodat(struct tcb * tcp)2403 sys_mknodat(struct tcb *tcp)
2404 {
2405 if (entering(tcp))
2406 print_dirfd(tcp, tcp->u_arg[0]);
2407 return decode_mknod(tcp, 1);
2408 }
2409 #endif
2410
2411 #ifdef FREEBSD
2412 int
sys_mkfifo(struct tcb * tcp)2413 sys_mkfifo(struct tcb *tcp)
2414 {
2415 if (entering(tcp)) {
2416 printpath(tcp, tcp->u_arg[0]);
2417 tprintf(", %#lo", tcp->u_arg[1]);
2418 }
2419 return 0;
2420 }
2421 #endif /* FREEBSD */
2422
2423 int
sys_fsync(struct tcb * tcp)2424 sys_fsync(struct tcb *tcp)
2425 {
2426 if (entering(tcp)) {
2427 printfd(tcp, tcp->u_arg[0]);
2428 }
2429 return 0;
2430 }
2431
2432 #ifdef LINUX
2433
2434 static void
printdir(struct tcb * tcp,long addr)2435 printdir(struct tcb *tcp, long addr)
2436 {
2437 struct dirent d;
2438
2439 if (!verbose(tcp)) {
2440 tprintf("%#lx", addr);
2441 return;
2442 }
2443 if (umove(tcp, addr, &d) < 0) {
2444 tprintf("{...}");
2445 return;
2446 }
2447 tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
2448 tprintf("d_name=");
2449 printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
2450 tprintf("}");
2451 }
2452
2453 int
sys_readdir(struct tcb * tcp)2454 sys_readdir(struct tcb *tcp)
2455 {
2456 if (entering(tcp)) {
2457 printfd(tcp, tcp->u_arg[0]);
2458 tprintf(", ");
2459 } else {
2460 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
2461 tprintf("%#lx", tcp->u_arg[1]);
2462 else
2463 printdir(tcp, tcp->u_arg[1]);
2464 /* Not much point in printing this out, it is always 1. */
2465 if (tcp->u_arg[2] != 1)
2466 tprintf(", %lu", tcp->u_arg[2]);
2467 }
2468 return 0;
2469 }
2470
2471 #endif /* LINUX */
2472
2473 #if defined FREEBSD || defined LINUX
2474 static const struct xlat direnttypes[] = {
2475 { DT_UNKNOWN, "DT_UNKNOWN" },
2476 { DT_FIFO, "DT_FIFO" },
2477 { DT_CHR, "DT_CHR" },
2478 { DT_DIR, "DT_DIR" },
2479 { DT_BLK, "DT_BLK" },
2480 { DT_REG, "DT_REG" },
2481 { DT_LNK, "DT_LNK" },
2482 { DT_SOCK, "DT_SOCK" },
2483 { DT_WHT, "DT_WHT" },
2484 { 0, NULL },
2485 };
2486
2487 #endif
2488
2489 int
sys_getdents(struct tcb * tcp)2490 sys_getdents(struct tcb *tcp)
2491 {
2492 int i, len, dents = 0;
2493 char *buf;
2494
2495 if (entering(tcp)) {
2496 printfd(tcp, tcp->u_arg[0]);
2497 tprintf(", ");
2498 return 0;
2499 }
2500 if (syserror(tcp) || !verbose(tcp)) {
2501 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2502 return 0;
2503 }
2504 len = tcp->u_rval;
2505 buf = len ? malloc(len) : NULL;
2506 if (len && !buf) {
2507 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2508 fprintf(stderr, "out of memory\n");
2509 return 0;
2510 }
2511 if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2512 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2513 free(buf);
2514 return 0;
2515 }
2516 if (!abbrev(tcp))
2517 tprintf("{");
2518 for (i = 0; i < len;) {
2519 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2520 #ifdef LINUX
2521 if (!abbrev(tcp)) {
2522 tprintf("%s{d_ino=%lu, d_off=%lu, ",
2523 i ? " " : "", d->d_ino, d->d_off);
2524 tprintf("d_reclen=%u, d_name=\"%s\"}",
2525 d->d_reclen, d->d_name);
2526 }
2527 #endif /* LINUX */
2528 #ifdef SVR4
2529 if (!abbrev(tcp)) {
2530 tprintf("%s{d_ino=%lu, d_off=%lu, ",
2531 i ? " " : "",
2532 (unsigned long) d->d_ino,
2533 (unsigned long) d->d_off);
2534 tprintf("d_reclen=%u, d_name=\"%s\"}",
2535 d->d_reclen, d->d_name);
2536 }
2537 #endif /* SVR4 */
2538 #ifdef SUNOS4
2539 if (!abbrev(tcp)) {
2540 tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2541 i ? " " : "", d->d_off, d->d_fileno,
2542 d->d_reclen);
2543 tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2544 d->d_namlen, d->d_namlen, d->d_name);
2545 }
2546 #endif /* SUNOS4 */
2547 #ifdef FREEBSD
2548 if (!abbrev(tcp)) {
2549 tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2550 i ? " " : "", d->d_fileno, d->d_reclen);
2551 printxval(direnttypes, d->d_type, "DT_???");
2552 tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2553 d->d_namlen, d->d_namlen, d->d_name);
2554 }
2555 #endif /* FREEBSD */
2556 if (!d->d_reclen) {
2557 tprintf("/* d_reclen == 0, problem here */");
2558 break;
2559 }
2560 i += d->d_reclen;
2561 dents++;
2562 }
2563 if (!abbrev(tcp))
2564 tprintf("}");
2565 else
2566 tprintf("/* %u entries */", dents);
2567 tprintf(", %lu", tcp->u_arg[2]);
2568 free(buf);
2569 return 0;
2570 }
2571
2572
2573 #if _LFS64_LARGEFILE
2574 int
sys_getdents64(struct tcb * tcp)2575 sys_getdents64(struct tcb *tcp)
2576 {
2577 int i, len, dents = 0;
2578 char *buf;
2579
2580 if (entering(tcp)) {
2581 printfd(tcp, tcp->u_arg[0]);
2582 tprintf(", ");
2583 return 0;
2584 }
2585 if (syserror(tcp) || !verbose(tcp)) {
2586 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2587 return 0;
2588 }
2589 len = tcp->u_rval;
2590 buf = len ? malloc(len) : NULL;
2591 if (len && !buf) {
2592 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2593 fprintf(stderr, "out of memory\n");
2594 return 0;
2595 }
2596 if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2597 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2598 free(buf);
2599 return 0;
2600 }
2601 if (!abbrev(tcp))
2602 tprintf("{");
2603 for (i = 0; i < len;) {
2604 struct dirent64 *d = (struct dirent64 *) &buf[i];
2605 #if defined(LINUX) || defined(SVR4)
2606 if (!abbrev(tcp)) {
2607 tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64 ", ",
2608 i ? " " : "",
2609 d->d_ino,
2610 d->d_off);
2611 #ifdef LINUX
2612 tprintf("d_type=");
2613 printxval(direnttypes, d->d_type, "DT_???");
2614 tprintf(", ");
2615 #endif
2616 tprintf("d_reclen=%u, d_name=\"%s\"}",
2617 d->d_reclen, d->d_name);
2618 }
2619 #endif /* LINUX || SVR4 */
2620 #ifdef SUNOS4
2621 if (!abbrev(tcp)) {
2622 tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2623 i ? " " : "", d->d_off, d->d_fileno,
2624 d->d_reclen);
2625 tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2626 d->d_namlen, d->d_namlen, d->d_name);
2627 }
2628 #endif /* SUNOS4 */
2629 if (!d->d_reclen) {
2630 tprintf("/* d_reclen == 0, problem here */");
2631 break;
2632 }
2633 i += d->d_reclen;
2634 dents++;
2635 }
2636 if (!abbrev(tcp))
2637 tprintf("}");
2638 else
2639 tprintf("/* %u entries */", dents);
2640 tprintf(", %lu", tcp->u_arg[2]);
2641 free(buf);
2642 return 0;
2643 }
2644 #endif
2645
2646 #ifdef FREEBSD
2647 int
sys_getdirentries(struct tcb * tcp)2648 sys_getdirentries(struct tcb *tcp)
2649 {
2650 int i, len, dents = 0;
2651 long basep;
2652 char *buf;
2653
2654 if (entering(tcp)) {
2655 printfd(tcp, tcp->u_arg[0]);
2656 tprintf(", ");
2657 return 0;
2658 }
2659 if (syserror(tcp) || !verbose(tcp)) {
2660 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2661 return 0;
2662 }
2663 len = tcp->u_rval;
2664 if ((buf = malloc(len)) == NULL) {
2665 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2666 fprintf(stderr, "out of memory\n");
2667 return 0;
2668 }
2669 if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2670 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2671 free(buf);
2672 return 0;
2673 }
2674 if (!abbrev(tcp))
2675 tprintf("{");
2676 for (i = 0; i < len;) {
2677 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2678 if (!abbrev(tcp)) {
2679 tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2680 i ? " " : "", d->d_fileno, d->d_reclen);
2681 printxval(direnttypes, d->d_type, "DT_???");
2682 tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2683 d->d_namlen, d->d_namlen, d->d_name);
2684 }
2685 if (!d->d_reclen) {
2686 tprintf("/* d_reclen == 0, problem here */");
2687 break;
2688 }
2689 i += d->d_reclen;
2690 dents++;
2691 }
2692 if (!abbrev(tcp))
2693 tprintf("}");
2694 else
2695 tprintf("/* %u entries */", dents);
2696 free(buf);
2697 tprintf(", %lu", tcp->u_arg[2]);
2698 if (umove(tcp, tcp->u_arg[3], &basep) < 0)
2699 tprintf(", %#lx", tcp->u_arg[3]);
2700 else
2701 tprintf(", [%lu]", basep);
2702 return 0;
2703 }
2704 #endif
2705
2706 #ifdef LINUX
2707 int
sys_getcwd(struct tcb * tcp)2708 sys_getcwd(struct tcb *tcp)
2709 {
2710 if (exiting(tcp)) {
2711 if (syserror(tcp))
2712 tprintf("%#lx", tcp->u_arg[0]);
2713 else
2714 printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
2715 tprintf(", %lu", tcp->u_arg[1]);
2716 }
2717 return 0;
2718 }
2719 #endif /* LINUX */
2720
2721 #ifdef FREEBSD
2722 int
sys___getcwd(struct tcb * tcp)2723 sys___getcwd(struct tcb *tcp)
2724 {
2725 if (exiting(tcp)) {
2726 if (syserror(tcp))
2727 tprintf("%#lx", tcp->u_arg[0]);
2728 else
2729 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
2730 tprintf(", %lu", tcp->u_arg[1]);
2731 }
2732 return 0;
2733 }
2734 #endif
2735
2736 #ifdef HAVE_SYS_ASYNCH_H
2737
2738 int
sys_aioread(struct tcb * tcp)2739 sys_aioread(struct tcb *tcp)
2740 {
2741 struct aio_result_t res;
2742
2743 if (entering(tcp)) {
2744 tprintf("%lu, ", tcp->u_arg[0]);
2745 } else {
2746 if (syserror(tcp))
2747 tprintf("%#lx", tcp->u_arg[1]);
2748 else
2749 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2750 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2751 printxval(whence, tcp->u_arg[4], "L_???");
2752 if (syserror(tcp) || tcp->u_arg[5] == 0
2753 || umove(tcp, tcp->u_arg[5], &res) < 0)
2754 tprintf(", %#lx", tcp->u_arg[5]);
2755 else
2756 tprintf(", {aio_return %d aio_errno %d}",
2757 res.aio_return, res.aio_errno);
2758 }
2759 return 0;
2760 }
2761
2762 int
sys_aiowrite(struct tcb * tcp)2763 sys_aiowrite(struct tcb *tcp)
2764 {
2765 struct aio_result_t res;
2766
2767 if (entering(tcp)) {
2768 tprintf("%lu, ", tcp->u_arg[0]);
2769 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2770 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2771 printxval(whence, tcp->u_arg[4], "L_???");
2772 }
2773 else {
2774 if (tcp->u_arg[5] == 0)
2775 tprintf(", NULL");
2776 else if (syserror(tcp)
2777 || umove(tcp, tcp->u_arg[5], &res) < 0)
2778 tprintf(", %#lx", tcp->u_arg[5]);
2779 else
2780 tprintf(", {aio_return %d aio_errno %d}",
2781 res.aio_return, res.aio_errno);
2782 }
2783 return 0;
2784 }
2785
2786 int
sys_aiowait(struct tcb * tcp)2787 sys_aiowait(struct tcb *tcp)
2788 {
2789 if (entering(tcp))
2790 printtv(tcp, tcp->u_arg[0]);
2791 return 0;
2792 }
2793
2794 int
sys_aiocancel(struct tcb * tcp)2795 sys_aiocancel(struct tcb *tcp)
2796 {
2797 struct aio_result_t res;
2798
2799 if (exiting(tcp)) {
2800 if (tcp->u_arg[0] == 0)
2801 tprintf("NULL");
2802 else if (syserror(tcp)
2803 || umove(tcp, tcp->u_arg[0], &res) < 0)
2804 tprintf("%#lx", tcp->u_arg[0]);
2805 else
2806 tprintf("{aio_return %d aio_errno %d}",
2807 res.aio_return, res.aio_errno);
2808 }
2809 return 0;
2810 }
2811
2812 #endif /* HAVE_SYS_ASYNCH_H */
2813
2814 static const struct xlat xattrflags[] = {
2815 #ifdef XATTR_CREATE
2816 { XATTR_CREATE, "XATTR_CREATE" },
2817 { XATTR_REPLACE, "XATTR_REPLACE" },
2818 #endif
2819 { 0, NULL }
2820 };
2821
2822 static void
print_xattr_val(struct tcb * tcp,int failed,unsigned long arg,unsigned long insize,unsigned long size)2823 print_xattr_val(struct tcb *tcp, int failed,
2824 unsigned long arg,
2825 unsigned long insize,
2826 unsigned long size)
2827 {
2828 if (!failed) {
2829 unsigned long capacity = 4 * size + 1;
2830 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
2831 if (buf == NULL || /* probably a bogus size argument */
2832 umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
2833 failed = 1;
2834 }
2835 else {
2836 unsigned char *out = buf;
2837 unsigned char *in = &buf[3 * size];
2838 size_t i;
2839 for (i = 0; i < size; ++i) {
2840 if (isprint(in[i]))
2841 *out++ = in[i];
2842 else {
2843 #define tohex(n) "0123456789abcdef"[n]
2844 *out++ = '\\';
2845 *out++ = 'x';
2846 *out++ = tohex(in[i] / 16);
2847 *out++ = tohex(in[i] % 16);
2848 }
2849 }
2850 /* Don't print terminating NUL if there is one. */
2851 if (i > 0 && in[i - 1] == '\0')
2852 out -= 4;
2853 *out = '\0';
2854 tprintf(", \"%s\", %ld", buf, insize);
2855 }
2856 free(buf);
2857 }
2858 if (failed)
2859 tprintf(", 0x%lx, %ld", arg, insize);
2860 }
2861
2862 int
sys_setxattr(struct tcb * tcp)2863 sys_setxattr(struct tcb *tcp)
2864 {
2865 if (entering(tcp)) {
2866 printpath(tcp, tcp->u_arg[0]);
2867 tprintf(", ");
2868 printstr(tcp, tcp->u_arg[1], -1);
2869 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2870 tprintf(", ");
2871 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2872 }
2873 return 0;
2874 }
2875
2876 int
sys_fsetxattr(struct tcb * tcp)2877 sys_fsetxattr(struct tcb *tcp)
2878 {
2879 if (entering(tcp)) {
2880 printfd(tcp, tcp->u_arg[0]);
2881 tprintf(", ");
2882 printstr(tcp, tcp->u_arg[1], -1);
2883 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2884 tprintf(", ");
2885 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2886 }
2887 return 0;
2888 }
2889
2890 int
sys_getxattr(struct tcb * tcp)2891 sys_getxattr(struct tcb *tcp)
2892 {
2893 if (entering(tcp)) {
2894 printpath(tcp, tcp->u_arg[0]);
2895 tprintf(", ");
2896 printstr(tcp, tcp->u_arg[1], -1);
2897 } else {
2898 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2899 tcp->u_rval);
2900 }
2901 return 0;
2902 }
2903
2904 int
sys_fgetxattr(struct tcb * tcp)2905 sys_fgetxattr(struct tcb *tcp)
2906 {
2907 if (entering(tcp)) {
2908 printfd(tcp, tcp->u_arg[0]);
2909 tprintf(", ");
2910 printstr(tcp, tcp->u_arg[1], -1);
2911 } else {
2912 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2913 tcp->u_rval);
2914 }
2915 return 0;
2916 }
2917
2918 int
sys_listxattr(struct tcb * tcp)2919 sys_listxattr(struct tcb *tcp)
2920 {
2921 if (entering(tcp)) {
2922 printpath(tcp, tcp->u_arg[0]);
2923 } else {
2924 /* XXX Print value in format */
2925 tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2926 }
2927 return 0;
2928 }
2929
2930 int
sys_flistxattr(struct tcb * tcp)2931 sys_flistxattr(struct tcb *tcp)
2932 {
2933 if (entering(tcp)) {
2934 printfd(tcp, tcp->u_arg[0]);
2935 } else {
2936 /* XXX Print value in format */
2937 tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2938 }
2939 return 0;
2940 }
2941
2942 int
sys_removexattr(struct tcb * tcp)2943 sys_removexattr(struct tcb *tcp)
2944 {
2945 if (entering(tcp)) {
2946 printpath(tcp, tcp->u_arg[0]);
2947 tprintf(", ");
2948 printstr(tcp, tcp->u_arg[1], -1);
2949 }
2950 return 0;
2951 }
2952
2953 int
sys_fremovexattr(struct tcb * tcp)2954 sys_fremovexattr(struct tcb *tcp)
2955 {
2956 if (entering(tcp)) {
2957 printfd(tcp, tcp->u_arg[0]);
2958 tprintf(", ");
2959 printstr(tcp, tcp->u_arg[1], -1);
2960 }
2961 return 0;
2962 }
2963
2964
2965 static const struct xlat advise[] = {
2966 { POSIX_FADV_NORMAL, "POSIX_FADV_NORMAL" },
2967 { POSIX_FADV_RANDOM, "POSIX_FADV_RANDOM" },
2968 { POSIX_FADV_SEQUENTIAL, "POSIX_FADV_SEQUENTIAL" },
2969 { POSIX_FADV_WILLNEED, "POSIX_FADV_WILLNEED" },
2970 { POSIX_FADV_DONTNEED, "POSIX_FADV_DONTNEED" },
2971 { POSIX_FADV_NOREUSE, "POSIX_FADV_NOREUSE" },
2972 { 0, NULL }
2973 };
2974
2975
2976 #ifdef LINUX
2977 int
sys_fadvise64(struct tcb * tcp)2978 sys_fadvise64(struct tcb *tcp)
2979 {
2980 if (entering(tcp)) {
2981 int argn;
2982 printfd(tcp, tcp->u_arg[0]);
2983 tprintf(", ");
2984 argn = printllval(tcp, "%lld", 1);
2985 tprintf(", %ld, ", tcp->u_arg[argn++]);
2986 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
2987 }
2988 return 0;
2989 }
2990 #endif
2991
2992
2993 int
sys_fadvise64_64(struct tcb * tcp)2994 sys_fadvise64_64(struct tcb *tcp)
2995 {
2996 if (entering(tcp)) {
2997 int argn;
2998 printfd(tcp, tcp->u_arg[0]);
2999 tprintf(", ");
3000 #if defined ARM || defined POWERPC
3001 argn = printllval(tcp, "%lld, ", 2);
3002 #else
3003 argn = printllval(tcp, "%lld, ", 1);
3004 #endif
3005 argn = printllval(tcp, "%lld, ", argn);
3006 #if defined ARM || defined POWERPC
3007 printxval(advise, tcp->u_arg[1], "POSIX_FADV_???");
3008 #else
3009 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
3010 #endif
3011 }
3012 return 0;
3013 }
3014
3015 #ifdef LINUX
3016 static const struct xlat inotify_modes[] = {
3017 { 0x00000001, "IN_ACCESS" },
3018 { 0x00000002, "IN_MODIFY" },
3019 { 0x00000004, "IN_ATTRIB" },
3020 { 0x00000008, "IN_CLOSE_WRITE"},
3021 { 0x00000010, "IN_CLOSE_NOWRITE"},
3022 { 0x00000020, "IN_OPEN" },
3023 { 0x00000040, "IN_MOVED_FROM" },
3024 { 0x00000080, "IN_MOVED_TO" },
3025 { 0x00000100, "IN_CREATE" },
3026 { 0x00000200, "IN_DELETE" },
3027 { 0x00000400, "IN_DELETE_SELF"},
3028 { 0x00000800, "IN_MOVE_SELF" },
3029 { 0x00002000, "IN_UNMOUNT" },
3030 { 0x00004000, "IN_Q_OVERFLOW" },
3031 { 0x00008000, "IN_IGNORED" },
3032 { 0x01000000, "IN_ONLYDIR" },
3033 { 0x02000000, "IN_DONT_FOLLOW"},
3034 { 0x20000000, "IN_MASK_ADD" },
3035 { 0x40000000, "IN_ISDIR" },
3036 { 0x80000000, "IN_ONESHOT" },
3037 { 0, NULL }
3038 };
3039
3040 static const struct xlat inotify_init_flags[] = {
3041 { 0x00000800, "IN_NONBLOCK" },
3042 { 0x00080000, "IN_CLOEXEC" },
3043 { 0, NULL }
3044 };
3045
3046 int
sys_inotify_add_watch(struct tcb * tcp)3047 sys_inotify_add_watch(struct tcb *tcp)
3048 {
3049 if (entering(tcp)) {
3050 printfd(tcp, tcp->u_arg[0]);
3051 tprintf(", ");
3052 printpath(tcp, tcp->u_arg[1]);
3053 tprintf(", ");
3054 printflags(inotify_modes, tcp->u_arg[2], "IN_???");
3055 }
3056 return 0;
3057 }
3058
3059 int
sys_inotify_rm_watch(struct tcb * tcp)3060 sys_inotify_rm_watch(struct tcb *tcp)
3061 {
3062 if (entering(tcp)) {
3063 printfd(tcp, tcp->u_arg[0]);
3064 tprintf(", %ld", tcp->u_arg[1]);
3065 }
3066 return 0;
3067 }
3068
3069 int
sys_inotify_init1(struct tcb * tcp)3070 sys_inotify_init1(struct tcb *tcp)
3071 {
3072 if (entering(tcp))
3073 printflags(inotify_init_flags, tcp->u_arg[0], "IN_???");
3074 return 0;
3075 }
3076
3077 int
sys_fallocate(struct tcb * tcp)3078 sys_fallocate(struct tcb *tcp)
3079 {
3080 if (entering(tcp)) {
3081 int argn;
3082 printfd(tcp, tcp->u_arg[0]); /* fd */
3083 tprintf(", ");
3084 tprintf("%#lo, ", tcp->u_arg[1]); /* mode */
3085 argn = printllval(tcp, "%llu, ", 2); /* offset */
3086 printllval(tcp, "%llu", argn); /* len */
3087 }
3088 return 0;
3089 }
3090 #endif
3091