strace/file.c

1510 lines
28 KiB
C
Raw Normal View History

1999-02-19 03:21:36 +03:00
/*
* 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>
1999-05-26 03:11:18 +04:00
#ifdef linux
#define dirent kernel_dirent
#include <linux/types.h>
#include <linux/dirent.h>
#undef dirent
#else
#define kernel_dirent dirent
#endif
1999-02-19 03:21:36 +03:00
1999-04-21 19:57:38 +04:00
#ifdef linux
1999-06-03 18:21:07 +04:00
# ifdef LINUXSPARC
struct stat {
unsigned short st_dev;
unsigned int st_ino;
unsigned short st_mode;
short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned int st_size;
int st_atime;
unsigned int __unused1;
int st_mtime;
unsigned int __unused2;
int st_ctime;
unsigned int __unused3;
int st_blksize;
int st_blocks;
unsigned int __unused4[2];
};
# define stat kernel_stat
# include <asm/stat.h>
# undef stat
# else
# undef dev_t
# undef ino_t
# undef mode_t
# undef nlink_t
# undef uid_t
# undef gid_t
# undef off_t
# undef loff_t
# define dev_t __kernel_dev_t
# define ino_t __kernel_ino_t
# define mode_t __kernel_mode_t
# define nlink_t __kernel_nlink_t
# define uid_t __kernel_uid_t
# define gid_t __kernel_gid_t
# define off_t __kernel_off_t
# define loff_t __kernel_loff_t
1999-06-03 18:21:07 +04:00
# include <asm/stat.h>
# undef dev_t
# undef ino_t
# undef mode_t
# undef nlink_t
# undef uid_t
# undef gid_t
# undef off_t
# undef loff_t
# define dev_t dev_t
# define ino_t ino_t
# define mode_t mode_t
# define nlink_t nlink_t
# define uid_t uid_t
# define gid_t gid_t
# define off_t off_t
# define loff_t loff_t
1999-06-03 18:21:07 +04:00
# endif
# define stat libc_stat
# include <sys/stat.h>
# undef stat
#else
# include <sys/stat.h>
#endif
1999-02-19 03:21:36 +03:00
#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
1999-02-19 03:21:36 +03:00
int
sys_llseek (tcp)
struct tcb *tcp;
{
if (entering(tcp)) {
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]));
1999-02-19 03:21:36 +03:00
else
tprintf("%ld, %lld, ", tcp->u_arg[0],
(((long long int) tcp->u_arg[1]) << 32
| (unsigned long long) tcp->u_arg[2]));
1999-02-19 03:21:36 +03:00
}
else {
long long int off;
if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
1999-02-19 03:21:36 +03:00
tprintf("%#lx, ", tcp->u_arg[3]);
else
tprintf("[%llu], ", off);
1999-02-19 03:21:36 +03:00
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 /* LINUXSPARC */
1999-02-19 03:21:36 +03:00
static void
realprintstat(tcp, statbuf)
struct tcb *tcp;
struct stat *statbuf;
{
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("...}");
}
1999-02-19 03:21:36 +03:00
static void
printstat(tcp, addr)
struct tcb *tcp;
int addr;
{
struct stat statbuf;
1999-02-19 03:21:36 +03:00
#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;
}
realprintstat(tcp, &statbuf);
}
#ifdef linux
static void
convertoldstat(oldbuf, newbuf)
const struct __old_kernel_stat *oldbuf;
struct stat *newbuf;
{
newbuf->st_dev=oldbuf->st_dev;
newbuf->st_ino=oldbuf->st_ino;
newbuf->st_mode=oldbuf->st_mode;
newbuf->st_nlink=oldbuf->st_nlink;
newbuf->st_uid=oldbuf->st_uid;
newbuf->st_gid=oldbuf->st_gid;
newbuf->st_rdev=oldbuf->st_rdev;
newbuf->st_size=oldbuf->st_size;
newbuf->st_atime=oldbuf->st_atime;
newbuf->st_mtime=oldbuf->st_mtime;
newbuf->st_ctime=oldbuf->st_ctime;
newbuf->st_blksize=0; /* not supported in old_stat */
newbuf->st_blocks=0; /* not supported in old_stat */
}
#endif
#ifdef linux
static void
printoldstat(tcp, addr)
struct tcb *tcp;
int addr;
{
struct __old_kernel_stat statbuf;
struct stat newstatbuf;
#ifdef LINUXSPARC
if (current_personality == 1) {
printstatsol(tcp, addr);
return;
}
#endif /* LINUXSPARC */
if (!addr) {
tprintf("NULL");
return;
1999-02-19 03:21:36 +03:00
}
if (syserror(tcp) || !verbose(tcp)) {
tprintf("%#x", addr);
return;
1999-02-19 03:21:36 +03:00
}
if (umove(tcp, addr, &statbuf) < 0) {
tprintf("{...}");
return;
1999-02-19 03:21:36 +03:00
}
convertoldstat(&statbuf, &newstatbuf);
realprintstat(tcp, &newstatbuf);
1999-02-19 03:21:36 +03:00
}
#endif
1999-02-19 03:21:36 +03:00
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;
}
#ifdef linux
int
sys_oldstat(tcp)
struct tcb *tcp;
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprintf(", ");
} else {
printoldstat(tcp, tcp->u_arg[1]);
}
return 0;
}
#endif
1999-02-19 03:21:36 +03:00
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;
}
#ifdef linux
int
sys_oldfstat(tcp)
struct tcb *tcp;
{
if (entering(tcp))
tprintf("%ld, ", tcp->u_arg[0]);
else {
printoldstat(tcp, tcp->u_arg[1]);
}
return 0;
}
#endif
1999-02-19 03:21:36 +03:00
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;
}
#ifdef linux
int
sys_oldlstat(tcp)
struct tcb *tcp;
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprintf(", ");
} else {
printoldstat(tcp, tcp->u_arg[1]);
}
return 0;
}
#endif
1999-02-19 03:21:36 +03:00
#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;
}
#ifdef HAVE_SYS_ACL_H
#include <sys/acl.h>
struct xlat aclcmds[] = {
{ SETACL, "SETACL" },
{ GETACL, "GETACL" },
{ GETACLCNT, "GETACLCNT" },
{ 0, NULL },
};
int
sys_acl(tcp)
struct tcb *tcp;
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprintf(", ");
printxval(aclcmds, tcp->u_arg[1], "???ACL???");
tprintf(", %ld", tcp->u_arg[2]);
/*
* FIXME - dump out the list of aclent_t's pointed to
* by "tcp->u_arg[3]" if it's not NULL.
*/
if (tcp->u_arg[3])
tprintf(", %#lx", tcp->u_arg[3]);
else
tprintf(", NULL");
}
return 0;
}
int
sys_facl(tcp)
struct tcb *tcp;
{
if (entering(tcp)) {
tprintf("%ld, ", tcp->u_arg[0]);
printxval(aclcmds, tcp->u_arg[1], "???ACL???");
tprintf(", %ld", tcp->u_arg[2]);
/*
* FIXME - dump out the list of aclent_t's pointed to
* by "tcp->u_arg[3]" if it's not NULL.
*/
if (tcp->u_arg[3])
tprintf(", %#lx", tcp->u_arg[3]);
else
tprintf(", NULL");
}
return 0;
}
#endif /* HAVE_SYS_ACL_H */
1999-02-19 03:21:36 +03:00
#endif /* SVR4 || LINUXSPARC */
#ifdef linux
1999-02-19 03:21:36 +03:00
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, "MINIX2_SUPER_MAGIC" },
{ 0x2478, "MINIX2_SUPER_MAGIC2" },
1999-02-19 03:21:36 +03:00
{ 0x4d44, "MSDOS_SUPER_MAGIC" },
{ 0x6969, "NFS_SUPER_MAGIC" },
{ 0x9fa0, "PROC_SUPER_MAGIC" },
{ 0x012fd16d, "XIAFS_SUPER_MAGIC" },
{ 0, NULL },
};
#endif /* linux */
1999-02-19 03:21:36 +03:00
#ifndef SVR4
static char *
sprintfstype(magic)
int magic;
{
static char buf[32];
#ifdef linux
1999-02-19 03:21:36 +03:00
char *s;
s = xlookup(fsmagic, magic);
if (s) {
sprintf(buf, "\"%s\"", s);
return buf;
}
#endif /* linux */
1999-02-19 03:21:36 +03:00
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",
1999-02-19 03:21:36 +03:00
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),
1999-04-06 05:37:51 +04:00
(unsigned long)statbuf.f_bsize,
(unsigned long)statbuf.f_blocks,
(unsigned long)statbuf.f_bfree);
1999-02-19 03:21:36 +03:00
tprintf("f_files=%lu, f_ffree=%lu",
1999-04-06 05:37:51 +04:00
(unsigned long)statbuf.f_files,
(unsigned long)statbuf.f_ffree);
#ifdef linux
tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
#endif /* linux */
1999-02-19 03:21:36 +03:00
#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;
}
#if defined(linux) && defined(__alpha)
1999-02-19 03:21:36 +03:00
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 /* linux && __alpha */
1999-02-19 03:21:36 +03:00
#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
1999-02-19 03:21:36 +03:00
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);
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 */
1999-02-19 03:21:36 +03:00
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;
}
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;) {
1999-05-26 03:11:18 +04:00
struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
#ifdef linux
1999-02-19 03:21:36 +03:00
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 */
1999-02-19 03:21:36 +03:00
#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
1999-02-19 03:21:36 +03:00
int
sys_getcwd(tcp)
struct tcb *tcp;
{
if (exiting(tcp)) {
if (syserror(tcp))
tprintf("%#lx", tcp->u_arg[0]);
else
printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
1999-02-19 03:21:36 +03:00
tprintf(", %lu", tcp->u_arg[1]);
}
return 0;
}
#endif /* linux */
1999-02-19 03:21:36 +03:00
#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 */