]> granicus.if.org Git - strace/blob - file_handle.c
tests: workaround systemd-nspawn habit of disabling unimplemented syscalls
[strace] / file_handle.c
1 /*
2  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3  * Copyright (c) 2015-2019 The strace developers.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: LGPL-2.1-or-later
7  */
8
9 #include "defs.h"
10
11 #include "xlat/name_to_handle_at_flags.h"
12
13 #ifndef MAX_HANDLE_SZ
14 # define MAX_HANDLE_SZ 128
15 #endif
16
17 typedef struct {
18         unsigned int handle_bytes;
19         int handle_type;
20 } file_handle_header;
21
22 SYS_FUNC(name_to_handle_at)
23 {
24         file_handle_header h;
25         const kernel_ulong_t addr = tcp->u_arg[2];
26
27         if (entering(tcp)) {
28                 /* dirfd */
29                 print_dirfd(tcp, tcp->u_arg[0]);
30                 tprints(", ");
31
32                 /* pathname */
33                 printpath(tcp, tcp->u_arg[1]);
34                 tprints(", ");
35
36                 /* handle */
37                 if (umove_or_printaddr(tcp, addr, &h)) {
38                         tprints(", ");
39
40                         /* mount_id */
41                         printaddr(tcp->u_arg[3]);
42                         tprints(", ");
43
44                         /* flags */
45                         printflags(name_to_handle_at_flags, tcp->u_arg[4],
46                                    "AT_???");
47
48                         return RVAL_DECODED;
49                 }
50                 tprintf("{handle_bytes=%u", h.handle_bytes);
51
52                 set_tcb_priv_ulong(tcp, h.handle_bytes);
53
54                 return 0;
55         } else {
56                 unsigned int i = get_tcb_priv_ulong(tcp);
57
58                 if ((!syserror(tcp) || EOVERFLOW == tcp->u_error)
59                     && !umove(tcp, addr, &h)) {
60                         unsigned char f_handle[MAX_HANDLE_SZ];
61
62                         if (i != h.handle_bytes)
63                                 tprintf(" => %u", h.handle_bytes);
64                         if (!syserror(tcp)) {
65                                 tprintf(", handle_type=%d", h.handle_type);
66                                 if (h.handle_bytes > MAX_HANDLE_SZ)
67                                         h.handle_bytes = MAX_HANDLE_SZ;
68                                 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes,
69                                             f_handle)) {
70                                         tprints(", f_handle=0x");
71                                         for (i = 0; i < h.handle_bytes; ++i)
72                                                 tprintf("%02x", f_handle[i]);
73                                 }
74                         }
75                 }
76                 tprints("}, ");
77
78                 /* mount_id */
79                 printnum_int(tcp, tcp->u_arg[3], "%d");
80                 tprints(", ");
81
82                 /* flags */
83                 printflags(name_to_handle_at_flags, tcp->u_arg[4], "AT_???");
84         }
85         return 0;
86 }
87
88 SYS_FUNC(open_by_handle_at)
89 {
90         file_handle_header h;
91         const kernel_ulong_t addr = tcp->u_arg[1];
92
93         /* mount_fd */
94         printfd(tcp, tcp->u_arg[0]);
95         tprints(", ");
96
97         /* handle */
98         if (!umove_or_printaddr(tcp, addr, &h)) {
99                 unsigned char f_handle[MAX_HANDLE_SZ];
100
101                 tprintf("{handle_bytes=%u, handle_type=%d",
102                         h.handle_bytes, h.handle_type);
103                 if (h.handle_bytes > MAX_HANDLE_SZ)
104                         h.handle_bytes = MAX_HANDLE_SZ;
105                 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
106                         unsigned int i;
107
108                         tprints(", f_handle=0x");
109                         for (i = 0; i < h.handle_bytes; ++i)
110                                 tprintf("%02x", f_handle[i]);
111                 }
112                 tprints("}");
113         }
114         tprints(", ");
115
116         /* flags */
117         tprint_open_modes(tcp->u_arg[2]);
118
119         return RVAL_DECODED;
120 }