X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=file.c;h=52c36312f30cd270728a198e356f2a3ddb63a55c;hb=aa524c88c49814863cb7f19e5c8a8eeca6ce22fe;hp=50fdd4ac87b96f8413b0fa3e1166c454469d40d9;hpb=8fe2c989867d7ce4fe8ba0e05266e6195488928d;p=strace diff --git a/file.c b/file.c index 50fdd4ac..52c36312 100644 --- a/file.c +++ b/file.c @@ -1,4 +1,5 @@ /* +#ifdef LINUX * Copyright (c) 1991, 1992 Paul Kranenburg * Copyright (c) 1993 Branko Lankester * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey @@ -33,17 +34,18 @@ #include "defs.h" #include -#ifdef linux +#ifdef LINUX #define dirent kernel_dirent #define dirent64 kernel_dirent64 #include #include #undef dirent +#undef dirent64 #else #define kernel_dirent dirent #endif -#ifdef linux +#ifdef LINUX # ifdef LINUXSPARC struct stat { unsigned short st_dev; @@ -64,6 +66,24 @@ struct stat { int st_blocks; unsigned int __unused4[2]; }; +#if defined(SPARC64) +struct stat_sparc64 { + unsigned int st_dev; + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + long st_size; + long st_atime; + long st_mtime; + long st_ctime; + long st_blksize; + long st_blocks; + unsigned long __unused4[2]; +}; +#endif /* SPARC64 */ # define stat kernel_stat # include # undef stat @@ -106,11 +126,21 @@ struct stat { # define off_t off_t # define loff_t loff_t # endif +# ifdef HPPA /* asm-parisc/stat.h defines stat64 */ +# undef stat64 +# endif # define stat libc_stat # define stat64 libc_stat64 # include # undef stat # undef stat64 + /* These might be macros. */ +# undef st_atime +# undef st_mtime +# undef st_ctime +# ifdef HPPA +# define stat64 hpux_stat64 +# endif #else # include #endif @@ -125,12 +155,35 @@ struct stat { #include #endif +#ifdef HAVE_LINUX_XATTR_H +#include +#elif defined linux +#define XATTR_CREATE 1 +#define XATTR_REPLACE 2 +#endif + #ifdef FREEBSD #include #include #include #endif +#if HAVE_LONG_LONG_OFF_T +/* + * Ugly hacks for systems that have typedef long long off_t + */ + +#define stat64 stat +#define HAVE_STAT64 1 /* Ugly hack */ + +#define sys_stat64 sys_stat +#define sys_fstat64 sys_fstat +#define sys_lstat64 sys_lstat +#define sys_lseek64 sys_lseek +#define sys_truncate64 sys_truncate +#define sys_ftruncate64 sys_ftruncate +#endif + #ifdef MAJOR_IN_SYSMACROS #include #endif @@ -152,7 +205,7 @@ struct stat { * Unix says r/w/rw are 0/1/2, so we make them true flags 1/2/3 by * adding 1. Just remember to add 1 to any arg decoded with openmodes. */ -struct xlat openmodes[] = { +const struct xlat openmodes[] = { { O_RDWR+1, "O_RDWR" }, { O_RDONLY+1, "O_RDONLY" }, { O_WRONLY+1, "O_WRONLY" }, @@ -184,7 +237,17 @@ struct xlat openmodes[] = { { O_DIRECT, "O_DIRECT" }, #endif #ifdef O_LARGEFILE +# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */ +# undef O_LARGEFILE +# ifdef SPARC64 +# define O_LARGEFILE 0x40000 +# elif defined X86_64 || defined S390X +# define O_LARGEFILE 0100000 +# endif +# endif +# ifdef O_LARGEFILE { O_LARGEFILE, "O_LARGEFILE" }, +# endif #endif #ifdef O_DIRECTORY { O_DIRECTORY, "O_DIRECTORY" }, @@ -192,6 +255,9 @@ struct xlat openmodes[] = { #ifdef O_NOFOLLOW { O_NOFOLLOW, "O_NOFOLLOW" }, #endif +#ifdef O_NOATIME + { O_NOATIME, "O_NOATIME" }, +#endif #ifdef FNDELAY { FNDELAY, "FNDELAY" }, @@ -231,7 +297,7 @@ struct xlat openmodes[] = { #endif #ifdef FNOCTTY { FNOCTTY, "FNOCTTY" }, -#endif +#endif #ifdef O_SHLOCK { O_SHLOCK, "O_SHLOCK" }, #endif @@ -249,7 +315,7 @@ struct tcb *tcp; printpath(tcp, tcp->u_arg[0]); tprintf(", "); /* flags */ - printflags(openmodes, tcp->u_arg[1] + 1); + printflags(openmodes, tcp->u_arg[1] + 1, "O_???"); if (tcp->u_arg[1] & O_CREAT) { /* mode */ tprintf(", %#lo", tcp->u_arg[2]); @@ -259,7 +325,7 @@ struct tcb *tcp; } #ifdef LINUXSPARC -struct xlat openmodessol[] = { +const struct xlat openmodessol[] = { { 0, "O_RDWR" }, { 1, "O_RDONLY" }, { 2, "O_WRONLY" }, @@ -285,7 +351,7 @@ struct tcb *tcp; printpath(tcp, tcp->u_arg[0]); tprintf(", "); /* flags */ - printflags(openmodessol, tcp->u_arg[1] + 1); + printflags(openmodessol, tcp->u_arg[1] + 1, "O_???"); if (tcp->u_arg[1] & 0x100) { /* mode */ tprintf(", %#lo", tcp->u_arg[2]); @@ -307,7 +373,7 @@ struct tcb *tcp; return 0; } -static struct xlat access_flags[] = { +static const struct xlat access_flags[] = { { F_OK, "F_OK", }, { R_OK, "R_OK" }, { W_OK, "W_OK" }, @@ -328,7 +394,7 @@ struct tcb *tcp; if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); tprintf(", "); - printflags(access_flags, tcp->u_arg[1]); + printflags(access_flags, tcp->u_arg[1], "?_OK"); } return 0; } @@ -343,13 +409,14 @@ struct tcb *tcp; return RVAL_OCTAL; } -static struct xlat whence[] = { +static const struct xlat whence[] = { { SEEK_SET, "SEEK_SET" }, { SEEK_CUR, "SEEK_CUR" }, { SEEK_END, "SEEK_END" }, { 0, NULL }, }; +#ifndef HAVE_LONG_LONG_OFF_T int sys_lseek(tcp) struct tcb *tcp; @@ -359,45 +426,37 @@ struct tcb *tcp; if (entering(tcp)) { tprintf("%ld, ", tcp->u_arg[0]); -#ifndef FREEBSD offset = tcp->u_arg[1]; _whence = tcp->u_arg[2]; if (_whence == SEEK_SET) tprintf("%lu, ", offset); else - tprintf("%ld, ", offset); -#else /* FREEBSD */ - offset = ((off_t) tcp->u_arg[1] << 32) + tcp->u_arg[2]; - _whence = tcp->u_arg[4]; - if (_whence == SEEK_SET) - tprintf("%llu, ", offset); - else - tprintf("%lld, ", offset); -#endif + tprintf("%ld, ", offset); printxval(whence, _whence, "SEEK_???"); - } -#ifdef FREEBSD - else - if (!syserror(tcp)) - return RVAL_LUDECIMAL; -#endif /* FREEBSD */ + } return RVAL_UDECIMAL; } +#endif -#ifdef linux +#ifdef LINUX int sys_llseek (tcp) struct tcb *tcp; { if (entering(tcp)) { + /* + * This one call takes explicitly two 32-bit arguments hi, lo, + * rather than one 64-bit argument for which LONG_LONG works + * appropriate for the native byte order. + */ if (tcp->u_arg[4] == SEEK_SET) tprintf("%ld, %llu, ", tcp->u_arg[0], (((long long int) tcp->u_arg[1]) << 32 - | (unsigned long long) tcp->u_arg[2])); + | (unsigned long long) (unsigned) tcp->u_arg[2])); else tprintf("%ld, %lld, ", tcp->u_arg[0], (((long long int) tcp->u_arg[1]) << 32 - | (unsigned long long) tcp->u_arg[2])); + | (unsigned long long) (unsigned) tcp->u_arg[2])); } else { long long int off; @@ -409,41 +468,99 @@ struct tcb *tcp; } return 0; } + +int +sys_readahead (tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, %lld, %ld", tcp->u_arg[0], +# if defined IA64 || defined X86_64 || defined ALPHA + (long long int) tcp->u_arg[1], tcp->u_arg[2] +# else + LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]), tcp->u_arg[3] +# endif + ); + } + return 0; +} #endif +#if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T +int +sys_lseek64 (tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + long long offset; + ALIGN64 (tcp, 1); /* FreeBSD aligns off_t args */ + offset = LONG_LONG(tcp->u_arg [1], tcp->u_arg[2]); + if (tcp->u_arg[3] == SEEK_SET) + tprintf("%ld, %llu, ", tcp->u_arg[0], offset); + else + tprintf("%ld, %lld, ", tcp->u_arg[0], offset); + printxval(whence, tcp->u_arg[3], "SEEK_???"); + } + return RVAL_LUDECIMAL; +} +#endif + +#ifndef HAVE_LONG_LONG_OFF_T int sys_truncate(tcp) struct tcb *tcp; { if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); -#ifndef FREEBSD tprintf(", %lu", tcp->u_arg[1]); -#else - tprintf(", %llu", ((off_t) tcp->u_arg[1] << 32) + tcp->u_arg[2]); -#endif } return 0; } +#endif +#if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T +int +sys_truncate64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + ALIGN64 (tcp, 1); + printpath(tcp, tcp->u_arg[0]); + tprintf(", %llu", LONG_LONG(tcp->u_arg[1],tcp->u_arg[2])); + } + return 0; +} +#endif + +#ifndef HAVE_LONG_LONG_OFF_T int sys_ftruncate(tcp) struct tcb *tcp; { if (entering(tcp)) { -#ifndef FREEBSD tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]); -#else + } + return 0; +} +#endif + +#if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T +int +sys_ftruncate64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + ALIGN64 (tcp, 1); tprintf("%ld, %llu", tcp->u_arg[0], - ((off_t) tcp->u_arg[1] << 32) + tcp->u_arg[2]); -#endif + LONG_LONG(tcp->u_arg[1] ,tcp->u_arg[2])); } return 0; } +#endif /* several stats */ -static struct xlat modetypes[] = { +static const struct xlat modetypes[] = { { S_IFREG, "S_IFREG" }, { S_IFSOCK, "S_IFSOCK" }, { S_IFIFO, "S_IFIFO" }, @@ -454,12 +571,12 @@ static struct xlat modetypes[] = { { 0, NULL }, }; -static char * +static const char * sprintmode(mode) int mode; { static char buf[64]; - char *s; + const char *s; if ((mode & S_IFMT) == 0) s = ""; @@ -575,10 +692,69 @@ long addr; else tprintf("...}"); } + +#if defined (SPARC64) +static void +printstat_sparc64(tcp, addr) +struct tcb *tcp; +long addr; +{ + struct stat_sparc64 statbuf; + + if (!addr) { + tprintf("NULL"); + return; + } + if (syserror(tcp) || !verbose(tcp)) { + tprintf("%#lx", addr); + return; + } + if (umove(tcp, addr, &statbuf) < 0) { + tprintf("{...}"); + return; + } + + if (!abbrev(tcp)) { + tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ", + (unsigned long) major(statbuf.st_dev), + (unsigned long) minor(statbuf.st_dev), + (unsigned long) statbuf.st_ino, + sprintmode(statbuf.st_mode)); + tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ", + (unsigned long) statbuf.st_nlink, + (unsigned long) statbuf.st_uid, + (unsigned long) statbuf.st_gid); + tprintf("st_blksize=%lu, ", + (unsigned long) statbuf.st_blksize); + tprintf("st_blocks=%lu, ", + (unsigned long) statbuf.st_blocks); + } + else + tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode)); + switch (statbuf.st_mode & S_IFMT) { + case S_IFCHR: case S_IFBLK: + tprintf("st_rdev=makedev(%lu, %lu), ", + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; + default: + tprintf("st_size=%lu, ", statbuf.st_size); + break; + } + if (!abbrev(tcp)) { + tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime)); + tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime)); + tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime)); + tprintf("}"); + } + else + tprintf("...}"); +} +#endif /* SPARC64 */ #endif /* LINUXSPARC */ +const struct xlat fileflags[] = { #ifdef FREEBSD -static struct xlat fileflags[] = { { UF_NODUMP, "UF_NODUMP" }, { UF_IMMUTABLE, "UF_IMMUTABLE" }, { UF_APPEND, "UF_APPEND" }, @@ -588,9 +764,18 @@ static struct xlat fileflags[] = { { SF_IMMUTABLE, "SF_IMMUTABLE" }, { SF_APPEND, "SF_APPEND" }, { SF_NOUNLINK, "SF_NOUNLINK" }, +#elif UNIXWARE >= 2 +#ifdef _S_ISMLD + { _S_ISMLD, "_S_ISMLD" }, +#endif +#ifdef _S_ISMOUNTED + { _S_ISMOUNTED, "_S_ISMOUNTED" }, +#endif +#endif { 0, NULL }, }; +#ifdef FREEBSD int sys_chflags(tcp) struct tcb *tcp; @@ -598,10 +783,7 @@ struct tcb *tcp; if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); tprintf(", "); - if (tcp->u_arg[1]) - printflags(fileflags, tcp->u_arg[1]); - else - tprintf("0"); + printflags(fileflags, tcp->u_arg[1], "UF_???"); } return 0; } @@ -612,15 +794,13 @@ struct tcb *tcp; { if (entering(tcp)) { tprintf("%ld, ", tcp->u_arg[0]); - if (tcp->u_arg[1]) - printflags(fileflags, tcp->u_arg[1]); - else - tprintf("0"); + printflags(fileflags, tcp->u_arg[1], "UF_???"); } return 0; } #endif +#ifndef HAVE_LONG_LONG_OFF_T static void realprintstat(tcp, statbuf) struct tcb *tcp; @@ -636,26 +816,26 @@ struct stat *statbuf; (unsigned long) statbuf->st_nlink, (unsigned long) statbuf->st_uid, (unsigned long) statbuf->st_gid); -#ifdef HAVE_ST_BLKSIZE +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize); -#endif /* HAVE_ST_BLKSIZE */ -#ifdef HAVE_ST_BLOCKS +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks); -#endif /* HAVE_ST_BLOCKS */ +#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */ } else tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode)); switch (statbuf->st_mode & S_IFMT) { case S_IFCHR: case S_IFBLK: -#ifdef HAVE_ST_RDEV +#ifdef HAVE_STRUCT_STAT_ST_RDEV tprintf("st_rdev=makedev(%lu, %lu), ", (unsigned long) major(statbuf->st_rdev), (unsigned long) minor(statbuf->st_rdev)); -#else /* !HAVE_ST_RDEV */ +#else /* !HAVE_STRUCT_STAT_ST_RDEV */ tprintf("st_size=makedev(%lu, %lu), ", (unsigned long) major(statbuf->st_size), (unsigned long) minor(statbuf->st_size)); -#endif /* !HAVE_ST_RDEV */ +#endif /* !HAVE_STRUCT_STAT_ST_RDEV */ break; default: tprintf("st_size=%lu, ", statbuf->st_size); @@ -664,17 +844,25 @@ struct stat *statbuf; if (!abbrev(tcp)) { tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime)); tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime)); -#ifndef FREEBSD - tprintf("st_ctime=%s}", sprinttime(statbuf->st_ctime)); -#else /* FREEBSD */ - tprintf("st_ctime=%s, ", sprinttime(statbuf->st_ctime)); - tprintf("st_flags="); - if (statbuf->st_flags) { - printflags(fileflags, statbuf->st_flags); - } else - tprintf("0"); - tprintf(", st_gen=%u}", statbuf->st_gen); -#endif /* FREEBSD */ + tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime)); +#if HAVE_STRUCT_STAT_ST_FLAGS + tprintf(", st_flags="); + printflags(fileflags, statbuf->st_flags, "UF_???"); +#endif +#if HAVE_STRUCT_STAT_ST_ACLCNT + tprintf(", st_aclcnt=%d", statbuf->st_aclcnt); +#endif +#if HAVE_STRUCT_STAT_ST_LEVEL + tprintf(", st_level=%ld", statbuf->st_level); +#endif +#if HAVE_STRUCT_STAT_ST_FSTYPE + tprintf(", st_fstype=%.*s", + (int) sizeof statbuf->st_fstype, statbuf->st_fstype); +#endif +#if HAVE_STRUCT_STAT_ST_GEN + tprintf(", st_gen=%u", statbuf->st_gen); +#endif + tprintf("}"); } else tprintf("...}"); @@ -693,6 +881,12 @@ long addr; printstatsol(tcp, addr); return; } +#ifdef SPARC64 + else if (current_personality == 2) { + printstat_sparc64(tcp, addr); + return; + } +#endif #endif /* LINUXSPARC */ if (!addr) { @@ -710,6 +904,7 @@ long addr; realprintstat(tcp, &statbuf); } +#endif /* !HAVE_LONG_LONG_OFF_T */ #ifdef HAVE_STAT64 static void @@ -724,6 +919,12 @@ long addr; printstatsol(tcp, addr); return; } +#ifdef SPARC64 + else if (current_personality == 2) { + printstat_sparc64(tcp, addr); + return; + } +#endif #endif /* LINUXSPARC */ if (!addr) { @@ -757,27 +958,27 @@ long addr; (unsigned long) statbuf.st_nlink, (unsigned long) statbuf.st_uid, (unsigned long) statbuf.st_gid); -#ifdef HAVE_ST_BLKSIZE +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize); -#endif /* HAVE_ST_BLKSIZE */ -#ifdef HAVE_ST_BLOCKS +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks); -#endif /* HAVE_ST_BLOCKS */ +#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */ } else tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode)); switch (statbuf.st_mode & S_IFMT) { case S_IFCHR: case S_IFBLK: -#ifdef HAVE_ST_RDEV +#ifdef HAVE_STRUCT_STAT_ST_RDEV tprintf("st_rdev=makedev(%lu, %lu), ", (unsigned long) major(statbuf.st_rdev), (unsigned long) minor(statbuf.st_rdev)); -#else /* !HAVE_ST_RDEV */ +#else /* !HAVE_STRUCT_STAT_ST_RDEV */ tprintf("st_size=makedev(%lu, %lu), ", (unsigned long) major(statbuf.st_size), (unsigned long) minor(statbuf.st_size)); -#endif /* !HAVE_ST_RDEV */ +#endif /* !HAVE_STRUCT_STAT_ST_RDEV */ break; default: tprintf("st_size=%llu, ", statbuf.st_size); @@ -786,14 +987,32 @@ long addr; if (!abbrev(tcp)) { tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime)); tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime)); - tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime)); + tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime)); +#if HAVE_STRUCT_STAT_ST_FLAGS + tprintf(", st_flags="); + printflags(fileflags, statbuf.st_flags, "UF_???"); +#endif +#if HAVE_STRUCT_STAT_ST_ACLCNT + tprintf(", st_aclcnt=%d", statbuf.st_aclcnt); +#endif +#if HAVE_STRUCT_STAT_ST_LEVEL + tprintf(", st_level=%ld", statbuf.st_level); +#endif +#if HAVE_STRUCT_STAT_ST_FSTYPE + tprintf(", st_fstype=%.*s", + (int) sizeof statbuf.st_fstype, statbuf.st_fstype); +#endif +#if HAVE_STRUCT_STAT_ST_GEN + tprintf(", st_gen=%u", statbuf.st_gen); +#endif + tprintf("}"); } else tprintf("...}"); } #endif /* HAVE_STAT64 */ -#if defined(linux) && !defined(IA64) +#if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT) static void convertoldstat(oldbuf, newbuf) const struct __old_kernel_stat *oldbuf; @@ -846,9 +1065,9 @@ long addr; convertoldstat(&statbuf, &newstatbuf); realprintstat(tcp, &newstatbuf); } -#endif /* linux && !IA64 */ - +#endif /* LINUX && !IA64 && !HPPA && !X86_64 && !S390 && !S390X */ +#ifndef HAVE_LONG_LONG_OFF_T int sys_stat(tcp) struct tcb *tcp; @@ -861,8 +1080,8 @@ struct tcb *tcp; } return 0; } +#endif -#ifdef linux int sys_stat64(tcp) struct tcb *tcp; @@ -880,7 +1099,7 @@ struct tcb *tcp; #endif } -# if !defined(IA64) +#if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT) int sys_oldstat(tcp) struct tcb *tcp; @@ -893,9 +1112,9 @@ struct tcb *tcp; } return 0; } -# endif /* !IA64 */ -#endif /* linux */ +#endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */ +#ifndef HAVE_LONG_LONG_OFF_T int sys_fstat(tcp) struct tcb *tcp; @@ -907,8 +1126,8 @@ struct tcb *tcp; } return 0; } +#endif -#ifdef linux int sys_fstat64(tcp) struct tcb *tcp; @@ -925,7 +1144,7 @@ struct tcb *tcp; #endif } -# if !defined(IA64) +#if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT) int sys_oldfstat(tcp) struct tcb *tcp; @@ -937,9 +1156,9 @@ struct tcb *tcp; } return 0; } -# endif /* !IA64 */ -#endif +#endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */ +#ifndef HAVE_LONG_LONG_OFF_T int sys_lstat(tcp) struct tcb *tcp; @@ -952,8 +1171,8 @@ struct tcb *tcp; } return 0; } +#endif -#ifdef linux int sys_lstat64(tcp) struct tcb *tcp; @@ -971,7 +1190,7 @@ struct tcb *tcp; #endif } -# if !defined(IA64) +#if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT) int sys_oldlstat(tcp) struct tcb *tcp; @@ -984,8 +1203,7 @@ struct tcb *tcp; } return 0; } -# endif /* !IA64 */ -#endif +#endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */ #if defined(SVR4) || defined(LINUXSPARC) @@ -1061,11 +1279,11 @@ struct tcb *tcp; tprintf(", makedev(%lu, %lu)", (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff), (unsigned long) (tcp->u_arg[3] & 0x3ffff)); -#else +#else tprintf(", makedev(%lu, %lu)", (unsigned long) major(tcp->u_arg[3]), (unsigned long) minor(tcp->u_arg[3])); -#endif +#endif break; default: break; @@ -1078,7 +1296,7 @@ struct tcb *tcp; #include -struct xlat aclcmds[] = { +const struct xlat aclcmds[] = { #ifdef SETACL { SETACL, "SETACL" }, #endif @@ -1090,13 +1308,13 @@ struct xlat aclcmds[] = { #endif #ifdef ACL_GET { ACL_GET, "ACL_GET" }, -#endif +#endif #ifdef ACL_SET { ACL_SET, "ACL_SET" }, -#endif +#endif #ifdef ACL_CNT { ACL_CNT, "ACL_CNT" }, -#endif +#endif { 0, NULL }, }; @@ -1143,16 +1361,16 @@ struct tcb *tcp; } -struct xlat aclipc[] = { +const struct xlat aclipc[] = { #ifdef IPC_SHM { IPC_SHM, "IPC_SHM" }, -#endif +#endif #ifdef IPC_SEM { IPC_SEM, "IPC_SEM" }, -#endif +#endif #ifdef IPC_MSG { IPC_MSG, "IPC_MSG" }, -#endif +#endif { 0, NULL }, }; @@ -1184,9 +1402,9 @@ struct tcb *tcp; #endif /* SVR4 || LINUXSPARC */ -#ifdef linux +#ifdef LINUX -static struct xlat fsmagic[] = { +static const struct xlat fsmagic[] = { { 0x73757245, "CODA_SUPER_MAGIC" }, { 0x012ff7b7, "COH_SUPER_MAGIC" }, { 0x1373, "DEVFS_SUPER_MAGIC" }, @@ -1215,27 +1433,28 @@ static struct xlat fsmagic[] = { { 0x54190100, "UFS_CIGAM" }, { 0x012ff7b4, "XENIX_SUPER_MAGIC" }, { 0x012fd16d, "XIAFS_SUPER_MAGIC" }, + { 0x62656572, "SYSFS_MAGIC" }, { 0, NULL }, }; -#endif /* linux */ +#endif /* LINUX */ #ifndef SVR4 -static char * +static const char * sprintfstype(magic) int magic; { static char buf[32]; -#ifdef linux - char *s; +#ifdef LINUX + const char *s; s = xlookup(fsmagic, magic); if (s) { sprintf(buf, "\"%s\"", s); return buf; } -#endif /* linux */ +#endif /* LINUX */ sprintf(buf, "%#x", magic); return buf; } @@ -1260,21 +1479,28 @@ long addr; tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ", sprintfstype(statbuf.f_type), statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree); - tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_namelen=%u", - statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, statbuf.f_namelen); + tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u", + statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, + statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1], + statbuf.f_namelen); #else /* !ALPHA */ tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ", sprintfstype(statbuf.f_type), (unsigned long)statbuf.f_bsize, (unsigned long)statbuf.f_blocks, (unsigned long)statbuf.f_bfree); - tprintf("f_files=%lu, f_ffree=%lu", + tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}", + (unsigned long)statbuf.f_bavail, (unsigned long)statbuf.f_files, - (unsigned long)statbuf.f_ffree); -#ifdef linux + (unsigned long)statbuf.f_ffree, + statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]); +#ifdef LINUX tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen); -#endif /* linux */ +#endif /* LINUX */ #endif /* !ALPHA */ +#ifdef _STATFS_F_FRSIZE + tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize); +#endif tprintf("}"); } @@ -1303,7 +1529,83 @@ struct tcb *tcp; return 0; } -#if defined(linux) && defined(__alpha) +#ifdef LINUX +static void +printstatfs64(tcp, addr) +struct tcb *tcp; +long addr; +{ + struct statfs64 statbuf; + + if (syserror(tcp) || !verbose(tcp)) { + tprintf("%#lx", addr); + return; + } + if (umove(tcp, addr, &statbuf) < 0) { + tprintf("{...}"); + return; + } +#ifdef ALPHA + + tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ", + sprintfstype(statbuf.f_type), + statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree); + tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u", + statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, + statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1], + statbuf.f_namelen); +#else /* !ALPHA */ + tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ", + sprintfstype(statbuf.f_type), + (unsigned long)statbuf.f_bsize, + (unsigned long)statbuf.f_blocks, + (unsigned long)statbuf.f_bfree); + tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}", + (unsigned long)statbuf.f_bavail, + (unsigned long)statbuf.f_files, + (unsigned long)statbuf.f_ffree, + statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]); + tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen); +#endif /* !ALPHA */ +#ifdef _STATFS_F_FRSIZE + tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize); +#endif + tprintf("}"); +} + +int +sys_statfs64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %lu, ", tcp->u_arg[1]); + } else { + if (tcp->u_arg[1] == sizeof (struct statfs64)) + printstatfs64(tcp, tcp->u_arg[2]); + else + tprintf("{???}"); + } + return 0; +} + +int +sys_fstatfs64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); + } else { + if (tcp->u_arg[1] == sizeof (struct statfs64)) + printstatfs64(tcp, tcp->u_arg[2]); + else + tprintf("{???}"); + } + return 0; +} +#endif + +#if defined(LINUX) && defined(__alpha) int osf_statfs(tcp) @@ -1331,7 +1633,7 @@ struct tcb *tcp; } return 0; } -#endif /* linux && __alpha */ +#endif /* LINUX && __alpha */ #endif /* !SVR4 */ @@ -1513,7 +1815,8 @@ struct tcb *tcp; { if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); - tprintf(", %lu, %lu", tcp->u_arg[1], tcp->u_arg[2]); + printuid(", ", tcp->u_arg[1]); + printuid(", ", tcp->u_arg[2]); } return 0; } @@ -1523,8 +1826,9 @@ sys_fchown(tcp) struct tcb *tcp; { if (entering(tcp)) { - tprintf("%ld, %lu, %lu", - tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]); + tprintf("%ld", tcp->u_arg[0]); + printuid(", ", tcp->u_arg[1]); + printuid(", ", tcp->u_arg[2]); } return 0; } @@ -1617,7 +1921,7 @@ struct tcb *tcp; (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff), (unsigned long) (tcp->u_arg[2] & 0x3ffff)); else -#endif +#endif tprintf(", makedev(%lu, %lu)", (unsigned long) major(tcp->u_arg[2]), (unsigned long) minor(tcp->u_arg[2])); @@ -1650,7 +1954,7 @@ struct tcb *tcp; return 0; } -#ifdef linux +#ifdef LINUX static void printdir(tcp, addr) @@ -1691,10 +1995,11 @@ struct tcb *tcp; return 0; } -#endif /* linux */ +#endif /* LINUX */ -#ifdef FREEBSD -struct xlat direnttypes[] = { +#if defined FREEBSD || defined LINUX +const struct xlat direnttypes[] = { + { DT_UNKNOWN, "DT_UNKNOWN" }, { DT_FIFO, "DT_FIFO" }, { DT_CHR, "DT_CHR" }, { DT_DIR, "DT_DIR" }, @@ -1725,11 +2030,12 @@ struct tcb *tcp; } len = tcp->u_rval; if ((buf = malloc(len)) == NULL) { - tprintf("out of memory\n"); + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); + fprintf(stderr, "out of memory\n"); return 0; } if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) { - tprintf("{...}, %lu", tcp->u_arg[2]); + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); free(buf); return 0; } @@ -1737,18 +2043,20 @@ struct tcb *tcp; tprintf("{"); for (i = 0; i < len;) { struct kernel_dirent *d = (struct kernel_dirent *) &buf[i]; -#ifdef linux +#ifdef LINUX if (!abbrev(tcp)) { tprintf("%s{d_ino=%lu, d_off=%lu, ", i ? " " : "", d->d_ino, d->d_off); tprintf("d_reclen=%u, d_name=\"%s\"}", d->d_reclen, d->d_name); } -#endif /* linux */ +#endif /* LINUX */ #ifdef SVR4 if (!abbrev(tcp)) { tprintf("%s{d_ino=%lu, d_off=%lu, ", - i ? " " : "", d->d_ino, d->d_off); + i ? " " : "", + (unsigned long) d->d_ino, + (unsigned long) d->d_off); tprintf("d_reclen=%u, d_name=\"%s\"}", d->d_reclen, d->d_name); } @@ -1770,7 +2078,7 @@ struct tcb *tcp; tprintf(", d_namlen=%u, d_name=\"%.*s\"}", d->d_namlen, d->d_namlen, d->d_name); } -#endif /* FREEBSD */ +#endif /* FREEBSD */ if (!d->d_reclen) { tprintf("/* d_reclen == 0, problem here */"); break; @@ -1787,6 +2095,75 @@ struct tcb *tcp; return 0; } + +#if _LFS64_LARGEFILE +int +sys_getdents64(tcp) +struct tcb *tcp; +{ + int i, len, dents = 0; + char *buf; + + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + return 0; + } + if (syserror(tcp) || !verbose(tcp)) { + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); + return 0; + } + len = tcp->u_rval; + if ((buf = malloc(len)) == NULL) { + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); + fprintf(stderr, "out of memory\n"); + return 0; + } + if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) { + tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]); + free(buf); + return 0; + } + if (!abbrev(tcp)) + tprintf("{"); + for (i = 0; i < len;) { + struct dirent64 *d = (struct dirent64 *) &buf[i]; +#if defined(LINUX) || defined(SVR4) + if (!abbrev(tcp)) { + tprintf("%s{d_ino=%llu, d_off=%llu, ", + i ? " " : "", + d->d_ino, + d->d_off); +#ifdef LINUX + tprintf("d_type="); + printxval(direnttypes, d->d_type, "DT_???"); + tprintf(", "); +#endif + tprintf("d_reclen=%u, d_name=\"%s\"}", + d->d_reclen, d->d_name); + } +#endif /* LINUX || SVR4 */ +#ifdef SUNOS4 + if (!abbrev(tcp)) { + tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ", + i ? " " : "", d->d_off, d->d_fileno, + d->d_reclen); + tprintf("d_namlen=%u, d_name=\"%.*s\"}", + d->d_namlen, d->d_namlen, d->d_name); + } +#endif /* SUNOS4 */ + i += d->d_reclen; + dents++; + } + if (!abbrev(tcp)) + tprintf("}"); + else + tprintf("/* %u entries */", dents); + tprintf(", %lu", tcp->u_arg[2]); + free(buf); + return 0; +} +#endif + #ifdef FREEBSD int sys_getdirentries(tcp) @@ -1806,11 +2183,12 @@ struct tcb * tcp; } len = tcp->u_rval; if ((buf = malloc(len)) == NULL) { - tprintf("out of memory\n"); + tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]); + fprintf(stderr, "out of memory\n"); return 0; } if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) { - tprintf("{...}, %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]); + tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]); free(buf); return 0; } @@ -1842,7 +2220,7 @@ struct tcb * tcp; } #endif -#ifdef linux +#ifdef LINUX int sys_getcwd(tcp) struct tcb *tcp; @@ -1856,7 +2234,7 @@ struct tcb *tcp; } return 0; } -#endif /* linux */ +#endif /* LINUX */ #ifdef FREEBSD int @@ -1956,19 +2334,209 @@ struct tcb *tcp; #endif /* HAVE_SYS_ASYNCH_H */ -#if UNIXWARE >= 7 -int -sys_lseek64 (tcp) +const struct xlat xattrflags[] = { +#ifdef XATTR_CREATE + { XATTR_CREATE, "XATTR_CREATE" }, + { XATTR_REPLACE, "XATTR_REPLACE" }, +#endif + { 0, NULL } +}; + +static void +print_xattr_val(tcp, failed, arg, insize, size) struct tcb *tcp; +int failed; +unsigned long arg; +unsigned long insize, size; { - if (entering(tcp)) { - long long offset = * (long long *) & tcp->u_arg [1]; - if (tcp->u_arg[3] == SEEK_SET) - tprintf("%ld, %llu, ", tcp->u_arg[0], offset); - else - tprintf("%ld, %lld, ", tcp->u_arg[0], offset); - printxval(whence, tcp->u_arg[3], "SEEK_???"); + if (!failed) { + unsigned long capacity = 4 * size + 1; + unsigned char *buf = (capacity < size) ? NULL : malloc(capacity); + if (buf == NULL || /* probably a bogus size argument */ + umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) { + failed = 1; } - return RVAL_LDECIMAL; + else { + unsigned char *out = buf; + unsigned char *in = &buf[3 * size]; + size_t i; + for (i = 0; i < size; ++i) + if (isprint(in[i])) + *out++ = in[i]; + else { +#define tohex(n) "0123456789abcdef"[n] + *out++ = '\\'; + *out++ = 'x'; + *out++ = tohex(in[i] / 16); + *out++ = tohex(in[i] % 16); + } + /* Don't print terminating NUL if there is one. */ + if (in[i - 1] == '\0') + out -= 4; + *out = '\0'; + tprintf(", \"%s\", %ld", buf, insize); + } + free(buf); + } + if (failed) + tprintf(", 0x%lx, %ld", arg, insize); } + +int +sys_setxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printstr(tcp, tcp->u_arg[1], -1); + print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]); + tprintf(", "); + printflags(xattrflags, tcp->u_arg[4], "XATTR_???"); + } + return 0; +} + +int +sys_fsetxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printstr(tcp, tcp->u_arg[1], -1); + print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]); + tprintf(", "); + printflags(xattrflags, tcp->u_arg[4], "XATTR_???"); + } + return 0; +} + +int +sys_getxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printstr(tcp, tcp->u_arg[1], -1); + } else { + print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3], + tcp->u_rval); + } + return 0; +} + +int +sys_fgetxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printstr(tcp, tcp->u_arg[1], -1); + } else { + print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3], + tcp->u_rval); + } + return 0; +} + +int +sys_listxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + } else { + /* XXX Print value in format */ + tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]); + } + return 0; +} + +int +sys_flistxattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld", tcp->u_arg[0]); + } else { + /* XXX Print value in format */ + tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]); + } + return 0; +} + +int +sys_removexattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printstr(tcp, tcp->u_arg[1], -1); + } + return 0; +} + +int +sys_fremovexattr(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printstr(tcp, tcp->u_arg[1], -1); + } + return 0; +} + + +static const struct xlat advise[] = { + { POSIX_FADV_NORMAL, "POSIX_FADV_NORMAL" }, + { POSIX_FADV_RANDOM, "POSIX_FADV_RANDOM" }, + { POSIX_FADV_SEQUENTIAL, "POSIX_FADV_SEQUENTIAL" }, + { POSIX_FADV_WILLNEED, "POSIX_FADV_WILLNEED" }, + { POSIX_FADV_DONTNEED, "POSIX_FADV_DONTNEED" }, + { POSIX_FADV_NOREUSE, "POSIX_FADV_NOREUSE" }, + { 0, NULL } +}; + + +#ifdef LINUX +int +sys_fadvise64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, %lld, %ld, ", + tcp->u_arg[0], +# if defined IA64 || defined X86_64 || defined ALPHA + (long long int) tcp->u_arg[1], tcp->u_arg[2]); + printxval(advise, tcp->u_arg[3], "POSIX_FADV_???"); +#else + LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]), tcp->u_arg[3]); + printxval(advise, tcp->u_arg[4], "POSIX_FADV_???"); +#endif + } + return 0; +} +#endif + + +int +sys_fadvise64_64(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, %lld, %lld, ", + tcp->u_arg[0], +# if defined IA64 || defined X86_64 || defined ALPHA + (long long int) tcp->u_arg[1], (long long int) tcp->u_arg[2]); + printxval(advise, tcp->u_arg[3], "POSIX_FADV_???"); +#else + LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]), + LONG_LONG(tcp->u_arg[3], tcp->u_arg[4])); + printxval(advise, tcp->u_arg[5], "POSIX_FADV_???"); #endif + } + return 0; +}