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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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-2019 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. }
  42. /*
  43. * low bits of the open(2) flags define access mode,
  44. * other bits are real flags.
  45. */
  46. const char *
  47. sprint_open_modes(unsigned int flags)
  48. {
  49. static char outstr[sizeof("flags O_ACCMODE")];
  50. char *p;
  51. char sep;
  52. const char *str;
  53. sep = ' ';
  54. p = stpcpy(outstr, "flags");
  55. str = xlookup(open_access_modes, flags & 3);
  56. if (str) {
  57. *p++ = sep;
  58. p = stpcpy(p, str);
  59. flags &= ~3;
  60. if (!flags)
  61. return outstr;
  62. sep = '|';
  63. }
  64. *p = '\0';
  65. return sprintflags_ex(outstr, open_mode_flags, flags, sep,
  66. XLAT_STYLE_ABBREV) ?: outstr;
  67. }
  68. void
  69. tprint_open_modes(unsigned int flags)
  70. {
  71. print_xlat_ex(flags, sprint_open_modes(flags) + sizeof("flags"),
  72. XLAT_STYLE_DEFAULT);
  73. }
  74. static int
  75. decode_open(struct tcb *tcp, int offset)
  76. {
  77. printpath(tcp, tcp->u_arg[offset]);
  78. tprints(", ");
  79. /* flags */
  80. tprint_open_modes(tcp->u_arg[offset + 1]);
  81. if (tcp->u_arg[offset + 1] & (O_CREAT | __O_TMPFILE)) {
  82. /* mode */
  83. tprints(", ");
  84. print_numeric_umode_t(tcp->u_arg[offset + 2]);
  85. }
  86. return RVAL_DECODED | RVAL_FD;
  87. }
  88. SYS_FUNC(open)
  89. {
  90. return decode_open(tcp, 0);
  91. }
  92. SYS_FUNC(openat)
  93. {
  94. print_dirfd(tcp, tcp->u_arg[0]);
  95. tprints(", ");
  96. return decode_open(tcp, 1);
  97. }
  98. SYS_FUNC(creat)
  99. {
  100. printpath(tcp, tcp->u_arg[0]);
  101. tprints(", ");
  102. print_numeric_umode_t(tcp->u_arg[1]);
  103. return RVAL_DECODED | RVAL_FD;
  104. }