Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2002-2005 Roland McGrath <roland (at) redhat.com>
      3  * Copyright (c) 2004 Ulrich Drepper <drepper (at) redhat.com>
      4  * Copyright (c) 2005-2015 Dmitry V. Levin <ldv (at) 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 }
    185