]> granicus.if.org Git - strace/blob - file_handle.c
2c0e42c60886bda2f23c3c3bdecc89d77caeaa3c
[strace] / file_handle.c
1 /*
2  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3  * Copyright (c) 2015-2017 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
31                 /* pathname */
32                 printpath(tcp, tcp->u_arg[1]);
33                 tprints(", ");
34
35                 /* handle */
36                 if (umove_or_printaddr(tcp, addr, &h)) {
37                         tprints(", ");
38
39                         /* mount_id */
40                         printaddr(tcp->u_arg[3]);
41                         tprints(", ");
42
43                         /* flags */
44                         printflags(name_to_handle_at_flags, tcp->u_arg[4],
45                                    "AT_???");
46
47                         return RVAL_DECODED;
48                 }
49                 tprintf("{handle_bytes=%u", h.handle_bytes);
50
51                 set_tcb_priv_ulong(tcp, h.handle_bytes);
52
53                 return 0;
54         } else {
55                 unsigned int i = get_tcb_priv_ulong(tcp);
56
57                 if ((!syserror(tcp) || EOVERFLOW == tcp->u_error)
58                     && !umove(tcp, addr, &h)) {
59                         unsigned char f_handle[MAX_HANDLE_SZ];
60
61                         if (i != h.handle_bytes)
62                                 tprintf(" => %u", h.handle_bytes);
63                         if (!syserror(tcp)) {
64                                 tprintf(", handle_type=%d", h.handle_type);
65                                 if (h.handle_bytes > MAX_HANDLE_SZ)
66                                         h.handle_bytes = MAX_HANDLE_SZ;
67                                 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes,
68                                             f_handle)) {
69                                         tprints(", f_handle=0x");
70                                         for (i = 0; i < h.handle_bytes; ++i)
71                                                 tprintf("%02x", f_handle[i]);
72                                 }
73                         }
74                 }
75                 tprints("}, ");
76
77                 /* mount_id */
78                 printnum_int(tcp, tcp->u_arg[3], "%d");
79                 tprints(", ");
80
81                 /* flags */
82                 printflags(name_to_handle_at_flags, tcp->u_arg[4], "AT_???");
83         }
84         return 0;
85 }
86
87 SYS_FUNC(open_by_handle_at)
88 {
89         file_handle_header h;
90         const kernel_ulong_t addr = tcp->u_arg[1];
91
92         /* mount_fd */
93         printfd(tcp, tcp->u_arg[0]);
94         tprints(", ");
95
96         /* handle */
97         if (!umove_or_printaddr(tcp, addr, &h)) {
98                 unsigned char f_handle[MAX_HANDLE_SZ];
99
100                 tprintf("{handle_bytes=%u, handle_type=%d",
101                         h.handle_bytes, h.handle_type);
102                 if (h.handle_bytes > MAX_HANDLE_SZ)
103                         h.handle_bytes = MAX_HANDLE_SZ;
104                 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
105                         unsigned int i;
106
107                         tprints(", f_handle=0x");
108                         for (i = 0; i < h.handle_bytes; ++i)
109                                 tprintf("%02x", f_handle[i]);
110                 }
111                 tprints("}");
112         }
113         tprints(", ");
114
115         /* flags */
116         tprint_open_modes(tcp->u_arg[2]);
117
118         return RVAL_DECODED;
119 }