Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xattr.c 3.3KB

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