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.

open.c 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  3. * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4. * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 2005-2007 Roland McGrath <roland@redhat.com>
  7. * Copyright (c) 2006-2007 Ulrich Drepper <drepper@redhat.com>
  8. * Copyright (c) 2009-2013 Denys Vlasenko <dvlasenk@redhat.com>
  9. * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
  10. * Copyright (c) 2014-2018 The strace developers.
  11. * All rights reserved.
  12. *
  13. * SPDX-License-Identifier: LGPL-2.1-or-later
  14. */
  15. #include "defs.h"
  16. #include "xstring.h"
  17. #include <asm/fcntl.h>
  18. /* some libcs are guilty of messing up with O_ACCMODE */
  19. #undef O_ACCMODE
  20. #define O_ACCMODE 03
  21. #ifdef O_LARGEFILE
  22. # if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
  23. # undef O_LARGEFILE
  24. # endif
  25. #endif
  26. #include "xlat/open_access_modes.h"
  27. #include "xlat/open_mode_flags.h"
  28. #ifndef AT_FDCWD
  29. # define AT_FDCWD -100
  30. #endif
  31. /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
  32. * extension to get the right value. We do this by declaring fd as int here.
  33. */
  34. void
  35. print_dirfd(struct tcb *tcp, int fd)
  36. {
  37. if (fd == AT_FDCWD)
  38. print_xlat_d(AT_FDCWD);
  39. else
  40. printfd(tcp, fd);
  41. tprints(", ");
  42. }
  43. /*
  44. * low bits of the open(2) flags define access mode,
  45. * other bits are real flags.
  46. */
  47. const char *
  48. sprint_open_modes(unsigned int flags)
  49. {
  50. static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
  51. char *p;
  52. char sep;
  53. const char *str;
  54. const struct xlat *x;
  55. sep = ' ';
  56. p = stpcpy(outstr, "flags");
  57. str = xlookup(open_access_modes, flags & 3);
  58. if (str) {
  59. *p++ = sep;
  60. p = stpcpy(p, str);
  61. flags &= ~3;
  62. if (!flags)
  63. return outstr;
  64. sep = '|';
  65. }
  66. for (x = open_mode_flags; x->str; x++) {
  67. if ((flags & x->val) == x->val) {
  68. *p++ = sep;
  69. p = stpcpy(p, x->str);
  70. flags &= ~x->val;
  71. if (!flags)
  72. return outstr;
  73. sep = '|';
  74. }
  75. }
  76. /* flags is still nonzero */
  77. *p++ = sep;
  78. p = xappendstr(outstr, p, "%#x", flags);
  79. return outstr;
  80. }
  81. void
  82. tprint_open_modes(unsigned int flags)
  83. {
  84. print_xlat_ex(flags, sprint_open_modes(flags) + sizeof("flags"),
  85. XLAT_STYLE_DEFAULT);
  86. }
  87. static int
  88. decode_open(struct tcb *tcp, int offset)
  89. {
  90. printpath(tcp, tcp->u_arg[offset]);
  91. tprints(", ");
  92. /* flags */
  93. tprint_open_modes(tcp->u_arg[offset + 1]);
  94. if (tcp->u_arg[offset + 1] & (O_CREAT | __O_TMPFILE)) {
  95. /* mode */
  96. tprints(", ");
  97. print_numeric_umode_t(tcp->u_arg[offset + 2]);
  98. }
  99. return RVAL_DECODED | RVAL_FD;
  100. }
  101. SYS_FUNC(open)
  102. {
  103. return decode_open(tcp, 0);
  104. }
  105. SYS_FUNC(openat)
  106. {
  107. print_dirfd(tcp, tcp->u_arg[0]);
  108. return decode_open(tcp, 1);
  109. }
  110. SYS_FUNC(creat)
  111. {
  112. printpath(tcp, tcp->u_arg[0]);
  113. tprints(", ");
  114. print_numeric_umode_t(tcp->u_arg[1]);
  115. return RVAL_DECODED | RVAL_FD;
  116. }