]> granicus.if.org Git - strace/blob - xattr.c
Fix printing of negative offsets in splice syscall
[strace] / xattr.c
1 /*
2  * Copyright (c) 2002-2005 Roland McGrath <roland@redhat.com>
3  * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
4  * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "defs.h"
31
32 #ifdef HAVE_SYS_XATTR_H
33 # include <sys/xattr.h>
34 #endif
35
36 #include "xlat/xattrflags.h"
37
38 static void
39 print_xattr_val(struct tcb *tcp,
40                 unsigned long addr,
41                 unsigned long insize,
42                 unsigned long size)
43 {
44         char *buf = NULL;
45         unsigned int len;
46
47         tprints(", ");
48
49         if (insize == 0)
50                 goto done;
51
52         len = size;
53         if (size != (unsigned long) len)
54                 goto done;
55
56         if (!len) {
57                 tprintf("\"\", %ld", insize);
58                 return;
59         }
60
61         if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
62                 goto done;
63
64         buf = malloc(len);
65         if (!buf)
66                 goto done;
67
68         if (umoven(tcp, addr, len, buf) < 0) {
69                 free(buf);
70                 buf = NULL;
71                 goto done;
72         }
73
74         /* Don't print terminating NUL if there is one. */
75         if (buf[len - 1] == '\0')
76                 --len;
77
78 done:
79         if (buf) {
80                 print_quoted_string(buf, len, 0);
81                 free(buf);
82         } else {
83                 printaddr(addr);
84         }
85         tprintf(", %ld", insize);
86 }
87
88 SYS_FUNC(setxattr)
89 {
90         printpath(tcp, tcp->u_arg[0]);
91         tprints(", ");
92         printstr(tcp, tcp->u_arg[1], -1);
93         print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
94         tprints(", ");
95         printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
96         return RVAL_DECODED;
97 }
98
99 SYS_FUNC(fsetxattr)
100 {
101         printfd(tcp, tcp->u_arg[0]);
102         tprints(", ");
103         printstr(tcp, tcp->u_arg[1], -1);
104         print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
105         tprints(", ");
106         printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
107         return RVAL_DECODED;
108 }
109
110 SYS_FUNC(getxattr)
111 {
112         if (entering(tcp)) {
113                 printpath(tcp, tcp->u_arg[0]);
114                 tprints(", ");
115                 printstr(tcp, tcp->u_arg[1], -1);
116         } else {
117                 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval);
118         }
119         return 0;
120 }
121
122 SYS_FUNC(fgetxattr)
123 {
124         if (entering(tcp)) {
125                 printfd(tcp, tcp->u_arg[0]);
126                 tprints(", ");
127                 printstr(tcp, tcp->u_arg[1], -1);
128         } else {
129                 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval);
130         }
131         return 0;
132 }
133
134 static void
135 print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size)
136 {
137         if (syserror(tcp)) {
138                 printaddr(addr);
139         } else {
140                 unsigned long len =
141                         (size < (unsigned long) tcp->u_rval) ?
142                                 size : (unsigned long) tcp->u_rval;
143                 printstr(tcp, addr, len);
144         }
145         tprintf(", %lu", size);
146 }
147
148 SYS_FUNC(listxattr)
149 {
150         if (entering(tcp)) {
151                 printpath(tcp, tcp->u_arg[0]);
152                 tprints(", ");
153         } else {
154                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
155         }
156         return 0;
157 }
158
159 SYS_FUNC(flistxattr)
160 {
161         if (entering(tcp)) {
162                 printfd(tcp, tcp->u_arg[0]);
163                 tprints(", ");
164         } else {
165                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
166         }
167         return 0;
168 }
169
170 SYS_FUNC(removexattr)
171 {
172         printpath(tcp, tcp->u_arg[0]);
173         tprints(", ");
174         printstr(tcp, tcp->u_arg[1], -1);
175         return RVAL_DECODED;
176 }
177
178 SYS_FUNC(fremovexattr)
179 {
180         printfd(tcp, tcp->u_arg[0]);
181         tprints(", ");
182         printstr(tcp, tcp->u_arg[1], -1);
183         return RVAL_DECODED;
184 }