Dmitry V. Levin
b93d52fe3d
strace is now provided under the terms of the GNU Lesser General Public License version 2.1 or later, see COPYING for more details. strace test suite is now provided under the terms of the GNU General Public License version 2 or later, see tests/COPYING for more details.
135 lines
2.8 KiB
C
135 lines
2.8 KiB
C
/*
|
|
* 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>
|
|
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
|
|
* Copyright (c) 2005-2007 Roland McGrath <roland@redhat.com>
|
|
* Copyright (c) 2006-2007 Ulrich Drepper <drepper@redhat.com>
|
|
* Copyright (c) 2009-2013 Denys Vlasenko <dvlasenk@redhat.com>
|
|
* Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
|
|
* Copyright (c) 2014-2018 The strace developers.
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include "xstring.h"
|
|
|
|
#include <asm/fcntl.h>
|
|
|
|
/* some libcs are guilty of messing up with O_ACCMODE */
|
|
#undef O_ACCMODE
|
|
#define O_ACCMODE 03
|
|
|
|
#ifdef O_LARGEFILE
|
|
# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
|
|
# undef O_LARGEFILE
|
|
# endif
|
|
#endif
|
|
|
|
#include "xlat/open_access_modes.h"
|
|
#include "xlat/open_mode_flags.h"
|
|
|
|
#ifndef AT_FDCWD
|
|
# define AT_FDCWD -100
|
|
#endif
|
|
|
|
/* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
|
|
* extension to get the right value. We do this by declaring fd as int here.
|
|
*/
|
|
void
|
|
print_dirfd(struct tcb *tcp, int fd)
|
|
{
|
|
if (fd == AT_FDCWD)
|
|
print_xlat_d(AT_FDCWD);
|
|
else
|
|
printfd(tcp, fd);
|
|
|
|
tprints(", ");
|
|
}
|
|
|
|
/*
|
|
* low bits of the open(2) flags define access mode,
|
|
* other bits are real flags.
|
|
*/
|
|
const char *
|
|
sprint_open_modes(unsigned int flags)
|
|
{
|
|
static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
|
|
char *p;
|
|
char sep;
|
|
const char *str;
|
|
const struct xlat *x;
|
|
|
|
sep = ' ';
|
|
p = stpcpy(outstr, "flags");
|
|
str = xlookup(open_access_modes, flags & 3);
|
|
if (str) {
|
|
*p++ = sep;
|
|
p = stpcpy(p, str);
|
|
flags &= ~3;
|
|
if (!flags)
|
|
return outstr;
|
|
sep = '|';
|
|
}
|
|
|
|
for (x = open_mode_flags; x->str; x++) {
|
|
if ((flags & x->val) == x->val) {
|
|
*p++ = sep;
|
|
p = stpcpy(p, x->str);
|
|
flags &= ~x->val;
|
|
if (!flags)
|
|
return outstr;
|
|
sep = '|';
|
|
}
|
|
}
|
|
/* flags is still nonzero */
|
|
*p++ = sep;
|
|
p = xappendstr(outstr, p, "%#x", flags);
|
|
return outstr;
|
|
}
|
|
|
|
void
|
|
tprint_open_modes(unsigned int flags)
|
|
{
|
|
print_xlat_ex(flags, sprint_open_modes(flags) + sizeof("flags"),
|
|
XLAT_STYLE_DEFAULT);
|
|
}
|
|
|
|
static int
|
|
decode_open(struct tcb *tcp, int offset)
|
|
{
|
|
printpath(tcp, tcp->u_arg[offset]);
|
|
tprints(", ");
|
|
/* flags */
|
|
tprint_open_modes(tcp->u_arg[offset + 1]);
|
|
if (tcp->u_arg[offset + 1] & (O_CREAT | __O_TMPFILE)) {
|
|
/* mode */
|
|
tprints(", ");
|
|
print_numeric_umode_t(tcp->u_arg[offset + 2]);
|
|
}
|
|
|
|
return RVAL_DECODED | RVAL_FD;
|
|
}
|
|
|
|
SYS_FUNC(open)
|
|
{
|
|
return decode_open(tcp, 0);
|
|
}
|
|
|
|
SYS_FUNC(openat)
|
|
{
|
|
print_dirfd(tcp, tcp->u_arg[0]);
|
|
return decode_open(tcp, 1);
|
|
}
|
|
|
|
SYS_FUNC(creat)
|
|
{
|
|
printpath(tcp, tcp->u_arg[0]);
|
|
tprints(", ");
|
|
print_numeric_umode_t(tcp->u_arg[1]);
|
|
|
|
return RVAL_DECODED | RVAL_FD;
|
|
}
|