]> granicus.if.org Git - strace/blob - open.c
xlat: provide fallback definitions for XDP_FLAGS_* constants
[strace] / open.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 2005-2007 Roland McGrath <roland@redhat.com>
7  * Copyright (c) 2006-2007 Ulrich Drepper <drepper@redhat.com>
8  * Copyright (c) 2009-2013 Denys Vlasenko <dvlasenk@redhat.com>
9  * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
10  * Copyright (c) 2014-2019 The strace developers.
11  * All rights reserved.
12  *
13  * SPDX-License-Identifier: LGPL-2.1-or-later
14  */
15
16 #include "defs.h"
17 #include "xstring.h"
18
19 #include <asm/fcntl.h>
20
21 /* some libcs are guilty of messing up with O_ACCMODE */
22 #undef O_ACCMODE
23 #define O_ACCMODE 03
24
25 #ifdef O_LARGEFILE
26 # if O_LARGEFILE == 0           /* biarch platforms in 64-bit mode */
27 #  undef O_LARGEFILE
28 # endif
29 #endif
30
31 #include "xlat/open_access_modes.h"
32 #include "xlat/open_mode_flags.h"
33
34 #ifndef AT_FDCWD
35 # define AT_FDCWD       -100
36 #endif
37
38 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
39  * extension to get the right value.  We do this by declaring fd as int here.
40  */
41 void
42 print_dirfd(struct tcb *tcp, int fd)
43 {
44         if (fd == AT_FDCWD)
45                 print_xlat_d(AT_FDCWD);
46         else
47                 printfd(tcp, fd);
48 }
49
50 /*
51  * low bits of the open(2) flags define access mode,
52  * other bits are real flags.
53  */
54 const char *
55 sprint_open_modes(unsigned int flags)
56 {
57         static char outstr[sizeof("flags O_ACCMODE")];
58         char *p;
59         char sep;
60         const char *str;
61
62         sep = ' ';
63         p = stpcpy(outstr, "flags");
64         str = xlookup(open_access_modes, flags & 3);
65         if (str) {
66                 *p++ = sep;
67                 p = stpcpy(p, str);
68                 flags &= ~3;
69                 if (!flags)
70                         return outstr;
71                 sep = '|';
72         }
73         *p = '\0';
74
75         return sprintflags_ex(outstr, open_mode_flags, flags, sep,
76                               XLAT_STYLE_ABBREV) ?: outstr;
77 }
78
79 void
80 tprint_open_modes(unsigned int flags)
81 {
82         print_xlat_ex(flags, sprint_open_modes(flags) + sizeof("flags"),
83                       XLAT_STYLE_DEFAULT);
84 }
85
86 static int
87 decode_open(struct tcb *tcp, int offset)
88 {
89         printpath(tcp, tcp->u_arg[offset]);
90         tprints(", ");
91         /* flags */
92         tprint_open_modes(tcp->u_arg[offset + 1]);
93         if (tcp->u_arg[offset + 1] & (O_CREAT | __O_TMPFILE)) {
94                 /* mode */
95                 tprints(", ");
96                 print_numeric_umode_t(tcp->u_arg[offset + 2]);
97         }
98
99         return RVAL_DECODED | RVAL_FD;
100 }
101
102 SYS_FUNC(open)
103 {
104         return decode_open(tcp, 0);
105 }
106
107 SYS_FUNC(openat)
108 {
109         print_dirfd(tcp, tcp->u_arg[0]);
110         tprints(", ");
111         return decode_open(tcp, 1);
112 }
113
114 SYS_FUNC(creat)
115 {
116         printpath(tcp, tcp->u_arg[0]);
117         tprints(", ");
118         print_numeric_umode_t(tcp->u_arg[1]);
119
120         return RVAL_DECODED | RVAL_FD;
121 }