blob: 4a70d89c780d14b002960f853d35f8c8c2b26ea2 [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
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000100SYS_FUNC(open)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000101{
102 return decode_open(tcp, 0);
103}
104
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000105SYS_FUNC(openat)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000106{
107 if (entering(tcp))
108 print_dirfd(tcp, tcp->u_arg[0]);
109 return decode_open(tcp, 1);
110}
111
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000112SYS_FUNC(creat)
Dmitry V. Levin964d80a2014-12-06 03:53:16 +0000113{
114 if (entering(tcp)) {
115 printpath(tcp, tcp->u_arg[0]);
116 tprintf(", %#lo", tcp->u_arg[1]);
117 }
118 return RVAL_FD;
119}