1 #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 */
26 void
print_dirfd(struct tcb * tcp,int fd)27 print_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 */
41 const char *
sprint_open_modes(int flags)42 sprint_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
78 void
tprint_open_modes(int flags)79 tprint_open_modes(int flags)
80 {
81 tprints(sprint_open_modes(flags) + sizeof("flags"));
82 }
83
84 static int
decode_open(struct tcb * tcp,int offset)85 decode_open(struct tcb *tcp, int offset)
86 {
87 if (entering(tcp)) {
88 printpath(tcp, tcp->u_arg[offset]);
89 tprints(", ");
90 /* flags */
91 tprint_open_modes(tcp->u_arg[offset + 1]);
92 if (tcp->u_arg[offset + 1] & O_CREAT) {
93 /* mode */
94 tprintf(", %#lo", tcp->u_arg[offset + 2]);
95 }
96 }
97 return RVAL_FD;
98 }
99
SYS_FUNC(open)100 SYS_FUNC(open)
101 {
102 return decode_open(tcp, 0);
103 }
104
SYS_FUNC(openat)105 SYS_FUNC(openat)
106 {
107 if (entering(tcp))
108 print_dirfd(tcp, tcp->u_arg[0]);
109 return decode_open(tcp, 1);
110 }
111
SYS_FUNC(creat)112 SYS_FUNC(creat)
113 {
114 if (entering(tcp)) {
115 printpath(tcp, tcp->u_arg[0]);
116 tprintf(", %#lo", tcp->u_arg[1]);
117 }
118 return RVAL_FD;
119 }
120