]> granicus.if.org Git - strace/blob - xattr.c
process.c: move sched_* parsers to a separate file
[strace] / xattr.c
1 #include "defs.h"
2
3 #ifdef HAVE_LINUX_XATTR_H
4 # include <linux/xattr.h>
5 #else
6 # define XATTR_CREATE 1
7 # define XATTR_REPLACE 2
8 #endif
9
10 #include "xlat/xattrflags.h"
11
12 static void
13 print_xattr_val(struct tcb *tcp, int failed,
14                 unsigned long arg,
15                 unsigned long insize,
16                 unsigned long size)
17 {
18         if (insize == 0)
19                 failed = 1;
20         if (!failed) {
21                 unsigned long capacity = 4 * size + 1;
22                 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
23                 if (buf == NULL || /* probably a bogus size argument */
24                         umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
25                         failed = 1;
26                 }
27                 else {
28                         unsigned char *out = buf;
29                         unsigned char *in = &buf[3 * size];
30                         size_t i;
31                         for (i = 0; i < size; ++i) {
32                                 if (in[i] >= ' ' && in[i] <= 0x7e)
33                                         *out++ = in[i];
34                                 else {
35 #define tohex(n) "0123456789abcdef"[n]
36                                         *out++ = '\\';
37                                         *out++ = 'x';
38                                         *out++ = tohex(in[i] / 16);
39                                         *out++ = tohex(in[i] % 16);
40                                 }
41                         }
42                         /* Don't print terminating NUL if there is one.  */
43                         if (i > 0 && in[i - 1] == '\0')
44                                 out -= 4;
45                         *out = '\0';
46                         tprintf(", \"%s\", %ld", buf, insize);
47                 }
48                 free(buf);
49         }
50         if (failed)
51                 tprintf(", 0x%lx, %ld", arg, insize);
52 }
53
54 int
55 sys_setxattr(struct tcb *tcp)
56 {
57         if (entering(tcp)) {
58                 printpath(tcp, tcp->u_arg[0]);
59                 tprints(", ");
60                 printstr(tcp, tcp->u_arg[1], -1);
61                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
62                 tprints(", ");
63                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
64         }
65         return 0;
66 }
67
68 int
69 sys_fsetxattr(struct tcb *tcp)
70 {
71         if (entering(tcp)) {
72                 printfd(tcp, tcp->u_arg[0]);
73                 tprints(", ");
74                 printstr(tcp, tcp->u_arg[1], -1);
75                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
76                 tprints(", ");
77                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
78         }
79         return 0;
80 }
81
82 int
83 sys_getxattr(struct tcb *tcp)
84 {
85         if (entering(tcp)) {
86                 printpath(tcp, tcp->u_arg[0]);
87                 tprints(", ");
88                 printstr(tcp, tcp->u_arg[1], -1);
89         } else {
90                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
91                                 tcp->u_rval);
92         }
93         return 0;
94 }
95
96 int
97 sys_fgetxattr(struct tcb *tcp)
98 {
99         if (entering(tcp)) {
100                 printfd(tcp, tcp->u_arg[0]);
101                 tprints(", ");
102                 printstr(tcp, tcp->u_arg[1], -1);
103         } else {
104                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
105                                 tcp->u_rval);
106         }
107         return 0;
108 }
109
110 static void
111 print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size)
112 {
113         if (syserror(tcp)) {
114                 tprintf("%#lx", addr);
115         } else {
116                 if (!addr) {
117                         tprints("NULL");
118                 } else {
119                         unsigned long len =
120                                 (size < (unsigned long) tcp->u_rval) ?
121                                         size : (unsigned long) tcp->u_rval;
122                         printstr(tcp, addr, len);
123                 }
124         }
125         tprintf(", %lu", size);
126 }
127
128 int
129 sys_listxattr(struct tcb *tcp)
130 {
131         if (entering(tcp)) {
132                 printpath(tcp, tcp->u_arg[0]);
133                 tprints(", ");
134         } else {
135                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
136         }
137         return 0;
138 }
139
140 int
141 sys_flistxattr(struct tcb *tcp)
142 {
143         if (entering(tcp)) {
144                 printfd(tcp, tcp->u_arg[0]);
145                 tprints(", ");
146         } else {
147                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
148         }
149         return 0;
150 }
151
152 int
153 sys_removexattr(struct tcb *tcp)
154 {
155         if (entering(tcp)) {
156                 printpath(tcp, tcp->u_arg[0]);
157                 tprints(", ");
158                 printstr(tcp, tcp->u_arg[1], -1);
159         }
160         return 0;
161 }
162
163 int
164 sys_fremovexattr(struct tcb *tcp)
165 {
166         if (entering(tcp)) {
167                 printfd(tcp, tcp->u_arg[0]);
168                 tprints(", ");
169                 printstr(tcp, tcp->u_arg[1], -1);
170         }
171         return 0;
172 }