file.c: move open, openat, and creat parsers to a separate file

* open.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* file.c: Move sys_open, sys_openat, sys_creat, and related code
to open.c.
This commit is contained in:
Дмитрий Левин 2014-12-06 03:53:16 +00:00
parent 304cd81e46
commit 964d80a0f7
3 changed files with 145 additions and 141 deletions

View File

@ -50,6 +50,7 @@ strace_SOURCES = \
mount.c \
mtd.c \
net.c \
open.c \
or1k_atomic.c \
pathtrace.c \
personality.c \

142
file.c
View File

@ -189,146 +189,6 @@ struct __old_kernel_stat {
# include <sys/mkdev.h>
#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
#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)
tprints("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(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;
sprintf(p, "%#x", flags);
return outstr;
}
void
tprint_open_modes(int flags)
{
tprints(sprint_open_modes(flags) + sizeof("flags"));
}
static int
decode_open(struct tcb *tcp, int offset)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[offset]);
tprints(", ");
/* flags */
tprint_open_modes(tcp->u_arg[offset + 1]);
if (tcp->u_arg[offset + 1] & O_CREAT) {
/* mode */
tprintf(", %#lo", tcp->u_arg[offset + 2]);
}
}
return RVAL_FD;
}
int
sys_open(struct tcb *tcp)
{
return decode_open(tcp, 0);
}
int
sys_openat(struct tcb *tcp)
{
if (entering(tcp))
print_dirfd(tcp, tcp->u_arg[0]);
return decode_open(tcp, 1);
}
#if defined(SPARC) || defined(SPARC64)
#include "xlat/openmodessol.h"
int
solaris_open(struct tcb *tcp)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprints(", ");
/* flags */
printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
if (tcp->u_arg[1] & 0x100) {
/* mode */
tprintf(", %#lo", tcp->u_arg[2]);
}
}
return 0;
}
#endif
int
sys_creat(struct tcb *tcp)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprintf(", %#lo", tcp->u_arg[1]);
}
return RVAL_FD;
}
/* several stats */
#if defined(SPARC) || defined(SPARC64)
@ -1065,4 +925,4 @@ sys_lxstat(struct tcb *tcp)
return 0;
}
#endif /* SPARC[64] */
#endif /* SPARC || SPARC64 */

143
open.c Normal file
View File

@ -0,0 +1,143 @@
#include "defs.h"
#include <fcntl.h>
#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
#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)
tprints("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(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;
sprintf(p, "%#x", flags);
return outstr;
}
void
tprint_open_modes(int flags)
{
tprints(sprint_open_modes(flags) + sizeof("flags"));
}
static int
decode_open(struct tcb *tcp, int offset)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[offset]);
tprints(", ");
/* flags */
tprint_open_modes(tcp->u_arg[offset + 1]);
if (tcp->u_arg[offset + 1] & O_CREAT) {
/* mode */
tprintf(", %#lo", tcp->u_arg[offset + 2]);
}
}
return RVAL_FD;
}
int
sys_open(struct tcb *tcp)
{
return decode_open(tcp, 0);
}
int
sys_openat(struct tcb *tcp)
{
if (entering(tcp))
print_dirfd(tcp, tcp->u_arg[0]);
return decode_open(tcp, 1);
}
int
sys_creat(struct tcb *tcp)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprintf(", %#lo", tcp->u_arg[1]);
}
return RVAL_FD;
}
#if defined(SPARC) || defined(SPARC64)
# include "xlat/openmodessol.h"
int
solaris_open(struct tcb *tcp)
{
if (entering(tcp)) {
printpath(tcp, tcp->u_arg[0]);
tprints(", ");
/* flags */
printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
if (tcp->u_arg[1] & 0x100) {
/* mode */
tprintf(", %#lo", tcp->u_arg[2]);
}
}
return 0;
}
#endif /* SPARC || SPARC64 */