blob: 974f50cd5284d9ec033535d3c79c18f51c9bfda8 [file] [log] [blame]
Dmitry V. Levin964d80a2014-12-06 03:53:16 +00001#include "defs.h"
2
3#include <fcntl.h>
4
5#ifdef O_LARGEFILE
6# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
7# undef O_LARGEFILE
8# ifdef SPARC64
9# define O_LARGEFILE 0x40000
10# elif defined X86_64 || defined S390X
11# define O_LARGEFILE 0100000
12# endif
13# endif
14#endif
15
16#include "xlat/open_access_modes.h"
17#include "xlat/open_mode_flags.h"
18
19#ifndef AT_FDCWD
20# define AT_FDCWD -100
21#endif
22
23/* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
24 * extension to get the right value. We do this by declaring fd as int here.
25 */
26void
27print_dirfd(struct tcb *tcp, int fd)
28{
29 if (fd == AT_FDCWD)
30 tprints("AT_FDCWD, ");
31 else {
32 printfd(tcp, fd);
33 tprints(", ");
34 }
35}
36
37/*
38 * low bits of the open(2) flags define access mode,
39 * other bits are real flags.
40 */
41const char *
42sprint_open_modes(int flags)
43{
44 static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
45 char *p;
46 char sep;
47 const char *str;
48 const struct xlat *x;
49
50 sep = ' ';
51 p = stpcpy(outstr, "flags");
52 str = xlookup(open_access_modes, flags & 3);
53 if (str) {
54 *p++ = sep;
55 p = stpcpy(p, str);
56 flags &= ~3;
57 if (!flags)
58 return outstr;
59 sep = '|';
60 }
61
62 for (x = open_mode_flags; x->str; x++) {
63 if ((flags & x->val) == x->val) {
64 *p++ = sep;
65 p = stpcpy(p, x->str);
66 flags &= ~x->val;
67 if (!flags)
68 return outstr;
69 sep = '|';
70 }
71 }
72 /* flags is still nonzero */
73 *p++ = sep;
74 sprintf(p, "%#x", flags);
75 return outstr;
76}
77
78void
79tprint_open_modes(int flags)
80{
81 tprints(sprint_open_modes(flags) + sizeof("flags"));
82}
83
84static int
85decode_open(struct tcb *tcp, int offset)
86{
Dmitry V. Levind62d8fd2015-07-17 22:03:29 +000087 printpath(tcp, tcp->u_arg[offset]);
88 tprints(", ");
89 /* flags */
90 tprint_open_modes(tcp->u_arg[offset + 1]);
91 if (tcp->u_arg[offset + 1] & O_CREAT) {
92 /* mode */
93 tprintf(", %#lo", tcp->u_arg[offset + 2]);
Dmitry V. Levin964d80a2014-12-06 03:53:16 +000094 }
Dmitry V. Levind62d8fd2015-07-17 22:03:29 +000095
96 return RVAL_DECODED | RVAL_FD;
Dmitry V. Levin964d80a2014-12-06 03:53:16 +000097}
98
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000099SYS_FUNC(open)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000100{
101 return decode_open(tcp, 0);
102}
103
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000104SYS_FUNC(openat)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000105{
Dmitry V. Levin57ae04e2015-07-17 22:03:29 +0000106 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000107 return decode_open(tcp, 1);
108}
109
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000110SYS_FUNC(creat)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000111{
Dmitry V. Levind62d8fd2015-07-17 22:03:29 +0000112 printpath(tcp, tcp->u_arg[0]);
113 tprintf(", %#lo", tcp->u_arg[1]);
114
115 return RVAL_DECODED | RVAL_FD;
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000116}