blob: e97be426fd450f1a7dc4b4b16ba82707e02e3deb [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{
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
100int
101sys_open(struct tcb *tcp)
102{
103 return decode_open(tcp, 0);
104}
105
106int
107sys_openat(struct tcb *tcp)
108{
109 if (entering(tcp))
110 print_dirfd(tcp, tcp->u_arg[0]);
111 return decode_open(tcp, 1);
112}
113
114int
115sys_creat(struct tcb *tcp)
116{
117 if (entering(tcp)) {
118 printpath(tcp, tcp->u_arg[0]);
119 tprintf(", %#lo", tcp->u_arg[1]);
120 }
121 return RVAL_FD;
122}
123
124#if defined(SPARC) || defined(SPARC64)
125# include "xlat/openmodessol.h"
126
127int
128solaris_open(struct tcb *tcp)
129{
130 if (entering(tcp)) {
131 printpath(tcp, tcp->u_arg[0]);
132 tprints(", ");
133 /* flags */
134 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
135 if (tcp->u_arg[1] & 0x100) {
136 /* mode */
137 tprintf(", %#lo", tcp->u_arg[2]);
138 }
139 }
140 return 0;
141}
142
143#endif /* SPARC || SPARC64 */