diff options
author | Wichert Akkerman <wichert@deephackmode.org> | 1999-02-19 00:21:36 +0000 |
---|---|---|
committer | Wichert Akkerman <wichert@deephackmode.org> | 1999-02-19 00:21:36 +0000 |
commit | 76baf7c9f6dd61a15524ad43c1b690c252cf5b7c (patch) | |
tree | c54cba971a5ca31d262dbf292fdae19601b7833d /file.c | |
download | strace-76baf7c9f6dd61a15524ad43c1b690c252cf5b7c.tar.gz strace-76baf7c9f6dd61a15524ad43c1b690c252cf5b7c.tar.bz2 strace-76baf7c9f6dd61a15524ad43c1b690c252cf5b7c.tar.xz |
Initial revision
Diffstat (limited to 'file.c')
-rw-r--r-- | file.c | 1302 |
1 files changed, 1302 insertions, 0 deletions
@@ -0,0 +1,1302 @@ +/* + * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> + * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> + * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include "defs.h" + +#include <dirent.h> + +#include <sys/stat.h> +#include <fcntl.h> + +#ifdef SVR4 +# include <sys/cred.h> +#endif /* SVR4 */ + +#include <sys/vfs.h> + +#ifdef MAJOR_IN_SYSMACROS +#include <sys/sysmacros.h> +#endif + +#ifdef MAJOR_IN_MKDEV +#include <sys/mkdev.h> +#endif + +#ifdef HAVE_SYS_ASYNCH_H +#include <sys/asynch.h> +#endif + +#ifdef SUNOS4 +#include <ustat.h> +#endif + +/* + * This is a really dirty trick but it should always work. Traditional + * 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[] = { + { O_RDWR+1, "O_RDWR" }, + { O_RDONLY+1, "O_RDONLY" }, + { O_WRONLY+1, "O_WRONLY" }, + { O_NONBLOCK, "O_NONBLOCK" }, + { O_APPEND, "O_APPEND" }, + { O_CREAT, "O_CREAT" }, + { O_TRUNC, "O_TRUNC" }, + { O_EXCL, "O_EXCL" }, + { O_NOCTTY, "O_NOCTTY" }, +#ifdef O_SYNC + { O_SYNC, "O_SYNC" }, +#endif +#ifdef O_ASYNC + { O_ASYNC, "O_ASYNC" }, +#endif +#ifdef O_DSYNC + { O_DSYNC, "O_DSYNC" }, +#endif +#ifdef O_RSYNC + { O_RSYNC, "O_RSYNC" }, +#endif +#ifdef O_NDELAY + { O_NDELAY, "O_NDELAY" }, +#endif +#ifdef O_PRIV + { O_PRIV, "O_PRIV" }, +#endif +#ifdef O_DIRECT + { O_DIRECT, "O_DIRECT" }, +#endif +#ifdef O_LARGEFILE + { O_LARGEFILE, "O_LARGEFILE" }, +#endif +#ifdef O_DIRECTORY + { O_DIRECTORY, "O_DIRECTORY" }, +#endif + +#ifdef FNDELAY + { FNDELAY, "FNDELAY" }, +#endif +#ifdef FAPPEND + { FAPPEND, "FAPPEND" }, +#endif +#ifdef FMARK + { FMARK, "FMARK" }, +#endif +#ifdef FDEFER + { FDEFER, "FDEFER" }, +#endif +#ifdef FASYNC + { FASYNC, "FASYNC" }, +#endif +#ifdef FSHLOCK + { FSHLOCK, "FSHLOCK" }, +#endif +#ifdef FEXLOCK + { FEXLOCK, "FEXLOCK" }, +#endif +#ifdef FCREAT + { FCREAT, "FCREAT" }, +#endif +#ifdef FTRUNC + { FTRUNC, "FTRUNC" }, +#endif +#ifdef FEXCL + { FEXCL, "FEXCL" }, +#endif +#ifdef FNBIO + { FNBIO, "FNBIO" }, +#endif +#ifdef FSYNC + { FSYNC, "FSYNC" }, +#endif +#ifdef FNOCTTY + { FNOCTTY, "FNOCTTY" }, +#endif + { 0, NULL }, +}; + +int +sys_open(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + /* flags */ + printflags(openmodes, tcp->u_arg[1] + 1); + if (tcp->u_arg[1] & O_CREAT) { + /* mode */ + tprintf(", %#lo", tcp->u_arg[2]); + } + } + return 0; +} + +#ifdef LINUXSPARC +struct xlat openmodessol[] = { + { 0, "O_RDWR" }, + { 1, "O_RDONLY" }, + { 2, "O_WRONLY" }, + { 0x80, "O_NONBLOCK" }, + { 8, "O_APPEND" }, + { 0x100, "O_CREAT" }, + { 0x200, "O_TRUNC" }, + { 0x400, "O_EXCL" }, + { 0x800, "O_NOCTTY" }, + { 0x10, "O_SYNC" }, + { 0x40, "O_DSYNC" }, + { 0x8000, "O_RSYNC" }, + { 4, "O_NDELAY" }, + { 0x1000, "O_PRIV" }, + { 0, NULL }, +}; + +int +solaris_open(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + /* flags */ + printflags(openmodessol, tcp->u_arg[1] + 1); + if (tcp->u_arg[1] & 0x100) { + /* mode */ + tprintf(", %#lo", tcp->u_arg[2]); + } + } + return 0; +} + +#endif + +int +sys_creat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %#lo", tcp->u_arg[1]); + } + return 0; +} + +static struct xlat access_flags[] = { + { F_OK, "F_OK", }, + { R_OK, "R_OK" }, + { W_OK, "W_OK" }, + { X_OK, "X_OK" }, +#ifdef EFF_ONLY_OK + { EFF_ONLY_OK, "EFF_ONLY_OK" }, +#endif +#ifdef EX_OK + { EX_OK, "EX_OK" }, +#endif + { 0, NULL }, +}; + +int +sys_access(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printflags(access_flags, tcp->u_arg[1]); + } + return 0; +} + +int +sys_umask(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%#lo", tcp->u_arg[0]); + } + return RVAL_OCTAL; +} + +static struct xlat whence[] = { + { SEEK_SET, "SEEK_SET" }, + { SEEK_CUR, "SEEK_CUR" }, + { SEEK_END, "SEEK_END" }, + { 0, NULL }, +}; + +int +sys_lseek(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + if (tcp->u_arg[2] == SEEK_SET) + tprintf("%lu, ", tcp->u_arg[1]); + else + tprintf("%ld, ", tcp->u_arg[1]); + printxval(whence, tcp->u_arg[2], "SEEK_???"); + } + return RVAL_UDECIMAL; +} + +#ifdef LINUX +int +sys_llseek (tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + if (tcp->u_arg[4] == SEEK_SET) + tprintf("%ld, %llu, ", tcp->u_arg[0], + (((unsigned long long int) tcp->u_arg[1]) << 32 + | (unsigned long) tcp->u_arg[2])); + else + tprintf("%ld, %lld, ", tcp->u_arg[0], + (((long long int) tcp->u_arg[1]) << 32 + | (unsigned long) tcp->u_arg[2])); + } + else { + if (syserror(tcp)) + tprintf("%#lx, ", tcp->u_arg[3]); + else { + long long int off; + umove(tcp, tcp->u_arg[3], &off); + tprintf("{%lld}, ", off); + } + printxval(whence, tcp->u_arg[4], "SEEK_???"); + } + return 0; +} +#endif + +int +sys_truncate(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %lu", tcp->u_arg[1]); + } + return 0; +} + +int +sys_ftruncate(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]); + } + return 0; +} + +/* several stats */ + +static struct xlat modetypes[] = { + { S_IFREG, "S_IFREG" }, + { S_IFSOCK, "S_IFSOCK" }, + { S_IFIFO, "S_IFIFO" }, + { S_IFLNK, "S_IFLNK" }, + { S_IFDIR, "S_IFDIR" }, + { S_IFBLK, "S_IFBLK" }, + { S_IFCHR, "S_IFCHR" }, + { 0, NULL }, +}; + +static char * +sprintmode(mode) +int mode; +{ + static char buf[64]; + char *s; + + if ((mode & S_IFMT) == 0) + s = ""; + else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) { + sprintf(buf, "%#o", mode); + return buf; + } + sprintf(buf, "%s%s%s%s", s, + (mode & S_ISUID) ? "|S_ISUID" : "", + (mode & S_ISGID) ? "|S_ISGID" : "", + (mode & S_ISVTX) ? "|S_ISVTX" : ""); + mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX); + if (mode) + sprintf(buf + strlen(buf), "|%#o", mode); + s = (*buf == '|') ? buf + 1 : buf; + return *s ? s : "0"; +} + +static char * +sprinttime(t) +time_t t; +{ + struct tm *tmp; + static char buf[32]; + + if (t == 0) { + sprintf(buf, "0"); + return buf; + } + tmp = localtime(&t); + sprintf(buf, "%02d/%02d/%02d-%02d:%02d:%02d", + tmp->tm_year, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + return buf; +} + +#ifdef LINUXSPARC +typedef struct { + int tv_sec; + int tv_nsec; +} timestruct_t; + +struct solstat { + unsigned st_dev; + int st_pad1[3]; /* network id */ + unsigned st_ino; + unsigned st_mode; + unsigned st_nlink; + unsigned st_uid; + unsigned st_gid; + unsigned st_rdev; + int st_pad2[2]; + int st_size; + int st_pad3; /* st_size, off_t expansion */ + timestruct_t st_atime; + timestruct_t st_mtime; + timestruct_t st_ctime; + int st_blksize; + int st_blocks; + char st_fstype[16]; + int st_pad4[8]; /* expansion area */ +}; + +static void +printstatsol(tcp, addr) +struct tcb *tcp; +int addr; +{ + struct solstat statbuf; + + if (!addr) { + tprintf("NULL"); + return; + } + if (syserror(tcp) || !verbose(tcp)) { + tprintf("%#x", 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) ((statbuf.st_dev >> 18) & 0x3fff), + (unsigned long) (statbuf.st_dev & 0x3ffff), + (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) ((statbuf.st_rdev >> 18) & 0x3fff), + (unsigned long) (statbuf.st_rdev & 0x3ffff)); + break; + default: + tprintf("st_size=%u, ", 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)); + } + else + tprintf("...}"); +} +#endif + +#ifdef LINUXSPARC +/* Ugly, bug GLIBC makes this necessary. */ +struct kernel_stat +{ + unsigned short int st_dev; + unsigned long int st_ino; + unsigned short int st_mode; + short int st_nlink; + unsigned short int st_uid; + unsigned short int st_gid; + unsigned short int st_rdev; + long int st_size; + long int st_atime; + unsigned long int __unused1; + long int st_mtime; + unsigned long int __unused2; + long int st_ctime; + unsigned long int __unused3; + long int st_blksize; + long int st_blocks; + unsigned long int __unused4; + unsigned long int __unused5; +}; +#endif +static void +printstat(tcp, addr) +struct tcb *tcp; +int addr; +{ + struct stat statbuf; + +#ifdef LINUXSPARC + if (current_personality == 1) { + printstatsol(tcp, addr); + return; + } +#endif /* LINUXSPARC */ + + if (!addr) { + tprintf("NULL"); + return; + } + if (syserror(tcp) || !verbose(tcp)) { + tprintf("%#x", 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); +#ifdef HAVE_ST_BLKSIZE + tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize); +#endif /* HAVE_ST_BLKSIZE */ +#ifdef HAVE_ST_BLOCKS + tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks); +#endif /* HAVE_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 + tprintf("st_rdev=makedev(%lu, %lu), ", + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); +#else /* !HAVE_ST_RDEV */ + tprintf("st_size=makedev(%lu, %lu), ", + (unsigned long) major(statbuf.st_size), + (unsigned long) minor(statbuf.st_size)); +#endif /* !HAVE_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)); + } + else + tprintf("...}"); +} + +int +sys_stat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + printstat(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_fstat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) + tprintf("%ld, ", tcp->u_arg[0]); + else { + printstat(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_lstat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + printstat(tcp, tcp->u_arg[1]); + } + return 0; +} + +#if defined(SVR4) || defined(LINUXSPARC) + +int +sys_xstat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printpath(tcp, tcp->u_arg[1]); + tprintf(", "); + } else { + printstat(tcp, tcp->u_arg[2]); + } + return 0; +} + +int +sys_fxstat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) + tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]); + else { + printstat(tcp, tcp->u_arg[2]); + } + return 0; +} + +int +sys_lxstat(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printpath(tcp, tcp->u_arg[1]); + tprintf(", "); + } else { + printstat(tcp, tcp->u_arg[2]); + } + return 0; +} + +int +sys_xmknod(tcp) +struct tcb *tcp; +{ + int mode = tcp->u_arg[2]; + + if (entering(tcp)) { + tprintf("%ld, ", tcp->u_arg[0]); + printpath(tcp, tcp->u_arg[1]); + tprintf(", %s", sprintmode(mode)); + switch (mode & S_IFMT) { + case S_IFCHR: case S_IFBLK: +#ifdef LINUXSPARC + tprintf(", makedev(%lu, %lu)", + (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff), + (unsigned long) (tcp->u_arg[3] & 0x3ffff)); +#else + tprintf(", makedev(%lu, %lu)", + (unsigned long) major(tcp->u_arg[3]), + (unsigned long) minor(tcp->u_arg[3])); +#endif + break; + default: + break; + } + } + return 0; +} + +#endif /* SVR4 || LINUXSPARC */ + +#ifdef LINUX + +static struct xlat fsmagic[] = { + { 0xef51, "EXT2_OLD_SUPER_MAGIC" }, + { 0xef53, "EXT2_SUPER_MAGIC" }, + { 0x137d, "EXT_SUPER_MAGIC" }, + { 0x9660, "ISOFS_SUPER_MAGIC" }, + { 0x137f, "MINIX_SUPER_MAGIC" }, + { 0x138f, "MINIX_SUPER_MAGIC2" }, + { 0x2468, "NEW_MINIX_SUPER_MAGIC" }, + { 0x4d44, "MSDOS_SUPER_MAGIC" }, + { 0x6969, "NFS_SUPER_MAGIC" }, + { 0x9fa0, "PROC_SUPER_MAGIC" }, + { 0x012fd16d, "XIAFS_SUPER_MAGIC" }, + { 0, NULL }, +}; + +#endif /* LINUX */ + +#ifndef SVR4 + +static char * +sprintfstype(magic) +int magic; +{ + static char buf[32]; +#ifdef LINUX + char *s; + + s = xlookup(fsmagic, magic); + if (s) { + sprintf(buf, "\"%s\"", s); + return buf; + } +#endif /* LINUX */ + sprintf(buf, "%#x", magic); + return buf; +} + +static void +printstatfs(tcp, addr) +struct tcb *tcp; +long addr; +{ + struct statfs 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_namelen=%u}", + statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, statbuf.f_namelen); +#else /* !ALPHA */ + tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ", + sprintfstype(statbuf.f_type), + statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree); + tprintf("f_files=%lu, f_ffree=%lu", + statbuf.f_files, statbuf.f_ffree); +#ifdef LINUX + tprintf(", f_namelen=%lu}", statbuf.f_namelen); +#endif /* LINUX */ +#endif /* !ALPHA */ + tprintf("}"); +} + +int +sys_statfs(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + printstatfs(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_fstatfs(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + } else { + printstatfs(tcp, tcp->u_arg[1]); + } + return 0; +} + +#ifdef LINUX +#ifdef ALPHA + +int +osf_statfs(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + printstatfs(tcp, tcp->u_arg[1]); + tprintf(", %lu", tcp->u_arg[2]); + } + return 0; +} + +int +osf_fstatfs(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + } else { + printstatfs(tcp, tcp->u_arg[1]); + tprintf(", %lu", tcp->u_arg[2]); + } + return 0; +} +#endif /* ALPHA */ +#endif /* LINUX */ + +#endif /* !SVR4 */ + +#ifdef SUNOS4 + +int +sys_ustat(tcp) +struct tcb *tcp; +{ + struct ustat statbuf; + + if (entering(tcp)) { + tprintf("makedev(%lu, %lu), ", + (long) major(tcp->u_arg[0]), + (long) minor(tcp->u_arg[0])); + } + else { + if (syserror(tcp) || !verbose(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0) + tprintf("{...}"); + else { + tprintf("{f_tfree=%lu, f_tinode=%lu, ", + statbuf.f_tfree, statbuf.f_tinode); + tprintf("f_fname=\"%.*s\", ", + (int) sizeof(statbuf.f_fname), + statbuf.f_fname); + tprintf("f_fpack=\"%.*s\"}", + (int) sizeof(statbuf.f_fpack), + statbuf.f_fpack); + } + } + return 0; +} + +#endif /* SUNOS4 */ + +/* directory */ +int +sys_chdir(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + } + return 0; +} + +int +sys_mkdir(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %#lo", tcp->u_arg[1]); + } + return 0; +} + +int +sys_rmdir(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + } + return 0; +} + +int +sys_fchdir(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld", tcp->u_arg[0]); + } + return 0; +} + +int +sys_chroot(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + } + return 0; +} + +int +sys_fchroot(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld", tcp->u_arg[0]); + } + return 0; +} + +int +sys_link(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printpath(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_unlink(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + } + return 0; +} + +int +sys_symlink(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printpath(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_readlink(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + } else { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else + printpathn(tcp, tcp->u_arg[1], tcp->u_rval); + tprintf(", %lu", tcp->u_arg[2]); + } + return 0; +} + +int +sys_rename(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printpath(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_chown(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %lu, %lu", tcp->u_arg[1], tcp->u_arg[2]); + } + return 0; +} + +int +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]); + } + return 0; +} + +int +sys_chmod(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %#lo", tcp->u_arg[1]); + } + return 0; +} + +int +sys_fchmod(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld, %#lo", tcp->u_arg[0], tcp->u_arg[1]); + } + return 0; +} + +int +sys_utimes(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + printtv(tcp, tcp->u_arg[1]); + } + return 0; +} + +int +sys_utime(tcp) +struct tcb *tcp; +{ + long ut[2]; + + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", "); + if (!tcp->u_arg[1]) + tprintf("NULL"); + else if (!verbose(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else if (umoven(tcp, tcp->u_arg[1], sizeof ut, + (char *) ut) < 0) + tprintf("[?, ?]"); + else { + tprintf("[%s,", sprinttime(ut[0])); + tprintf(" %s]", sprinttime(ut[1])); + } + } + return 0; +} + +int +sys_mknod(tcp) +struct tcb *tcp; +{ + int mode = tcp->u_arg[1]; + + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %s", sprintmode(mode)); + switch (mode & S_IFMT) { + case S_IFCHR: case S_IFBLK: +#ifdef LINUXSPARC + if (current_personality == 1) + tprintf(", makedev(%lu, %lu)", + (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff), + (unsigned long) (tcp->u_arg[2] & 0x3ffff)); + else +#endif + tprintf(", makedev(%lu, %lu)", + (unsigned long) major(tcp->u_arg[2]), + (unsigned long) minor(tcp->u_arg[2])); + break; + default: + break; + } + } + return 0; +} + +int +sys_mkfifo(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + printpath(tcp, tcp->u_arg[0]); + tprintf(", %#lo", tcp->u_arg[1]); + } + return 0; +} + +int +sys_fsync(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%ld", tcp->u_arg[0]); + } + return 0; +} + +#ifdef LINUX + +static void +printdir(tcp, addr) +struct tcb *tcp; +long addr; +{ + struct dirent d; + + if (!verbose(tcp)) { + tprintf("%#lx", addr); + return; + } + if (umove(tcp, addr, &d) < 0) { + tprintf("{...}"); + return; + } + tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino); +#ifndef LINUX + /* This contains garbage under Linux. */ + tprintf("d_off=%d, ", d.d_off); +#endif /* !LINUX */ +#ifndef LINUX + /* No point in printing this out since the syscall returns it. */ + tprintf("d_reclen=%u, ", d.d_reclen); +#endif /* !LINUX */ + tprintf("d_name="); + printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen); + tprintf("}"); +} + +int +sys_readdir(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + } else { + if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else + printdir(tcp, tcp->u_arg[1]); + /* Not much point in printing this out, it is always 1. */ + if (tcp->u_arg[2] != 1) + tprintf(", %lu", tcp->u_arg[2]); + } + return 0; +} + +#endif /* LINUX */ + +int +sys_getdents(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; + } +#ifdef linux +#ifdef __sparc__ + tprintf (" = Unknown value\n"); + return 0; +#endif +#endif + len = tcp->u_rval; + if ((buf = malloc(len)) == NULL) { + tprintf("out of memory\n"); + return 0; + } + if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) { + tprintf("{...}, %lu", tcp->u_arg[2]); + free(buf); + return 0; + } + if (!abbrev(tcp)) + tprintf("{"); + for (i = 0; i < len;) { + struct dirent *d = (struct dirent *) &buf[i]; +#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 */ +#ifdef SVR4 + 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 /* 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; +} + +#ifdef LINUX + +int +sys_getcwd(tcp) +struct tcb *tcp; +{ + if (exiting(tcp)) { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[0]); + else + printstr(tcp, tcp->u_arg[0], tcp->u_arg[1]); + tprintf(", %lu", tcp->u_arg[1]); + } + return 0; +} +#endif /* LINUX */ + +#ifdef HAVE_SYS_ASYNCH_H + +int +sys_aioread(tcp) +struct tcb *tcp; +{ + struct aio_result_t res; + + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + } else { + if (syserror(tcp)) + tprintf("%#lx", tcp->u_arg[1]); + else + printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); + tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]); + printxval(whence, tcp->u_arg[4], "L_???"); + if (syserror(tcp) || tcp->u_arg[5] == 0 + || umove(tcp, tcp->u_arg[5], &res) < 0) + tprintf(", %#lx", tcp->u_arg[5]); + else + tprintf(", {aio_return %d aio_errno %d}", + res.aio_return, res.aio_errno); + } + return 0; +} + +int +sys_aiowrite(tcp) +struct tcb *tcp; +{ + struct aio_result_t res; + + if (entering(tcp)) { + tprintf("%lu, ", tcp->u_arg[0]); + printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); + tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]); + printxval(whence, tcp->u_arg[4], "L_???"); + } + else { + if (tcp->u_arg[5] == 0) + tprintf(", NULL"); + else if (syserror(tcp) + || umove(tcp, tcp->u_arg[5], &res) < 0) + tprintf(", %#lx", tcp->u_arg[5]); + else + tprintf(", {aio_return %d aio_errno %d}", + res.aio_return, res.aio_errno); + } + return 0; +} + +int +sys_aiowait(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) + printtv(tcp, tcp->u_arg[0]); + return 0; +} + +int +sys_aiocancel(tcp) +struct tcb *tcp; +{ + struct aio_result_t res; + + if (exiting(tcp)) { + if (tcp->u_arg[0] == 0) + tprintf("NULL"); + else if (syserror(tcp) + || umove(tcp, tcp->u_arg[0], &res) < 0) + tprintf("%#lx", tcp->u_arg[0]); + else + tprintf("{aio_return %d aio_errno %d}", + res.aio_return, res.aio_errno); + } + return 0; +} + +#endif /* HAVE_SYS_ASYNCH_H */ |