1 #include "defs.h" 2 3 #include <fcntl.h> 4 5 #ifdef O_LARGEFILE 6 # if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */ 7 # undef O_LARGEFILE 8 # ifdef SPARC64 9 # define O_LARGEFILE 0x40000 10 # elif defined X86_64 || defined S390X 11 # define O_LARGEFILE 0100000 12 # endif 13 # endif 14 #endif 15 16 #include "xlat/open_access_modes.h" 17 #include "xlat/open_mode_flags.h" 18 19 #ifndef AT_FDCWD 20 # define AT_FDCWD -100 21 #endif 22 23 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign 24 * extension to get the right value. We do this by declaring fd as int here. 25 */ 26 void 27 print_dirfd(struct tcb *tcp, int fd) 28 { 29 if (fd == AT_FDCWD) 30 tprints("AT_FDCWD, "); 31 else { 32 printfd(tcp, fd); 33 tprints(", "); 34 } 35 } 36 37 /* 38 * low bits of the open(2) flags define access mode, 39 * other bits are real flags. 40 */ 41 const char * 42 sprint_open_modes(int flags) 43 { 44 static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")]; 45 char *p; 46 char sep; 47 const char *str; 48 const struct xlat *x; 49 50 sep = ' '; 51 p = stpcpy(outstr, "flags"); 52 str = xlookup(open_access_modes, flags & 3); 53 if (str) { 54 *p++ = sep; 55 p = stpcpy(p, str); 56 flags &= ~3; 57 if (!flags) 58 return outstr; 59 sep = '|'; 60 } 61 62 for (x = open_mode_flags; x->str; x++) { 63 if ((flags & x->val) == x->val) { 64 *p++ = sep; 65 p = stpcpy(p, x->str); 66 flags &= ~x->val; 67 if (!flags) 68 return outstr; 69 sep = '|'; 70 } 71 } 72 /* flags is still nonzero */ 73 *p++ = sep; 74 sprintf(p, "%#x", flags); 75 return outstr; 76 } 77 78 void 79 tprint_open_modes(int flags) 80 { 81 tprints(sprint_open_modes(flags) + sizeof("flags")); 82 } 83 84 static int 85 decode_open(struct tcb *tcp, int offset) 86 { 87 if (entering(tcp)) { 88 printpath(tcp, tcp->u_arg[offset]); 89 tprints(", "); 90 /* flags */ 91 tprint_open_modes(tcp->u_arg[offset + 1]); 92 if (tcp->u_arg[offset + 1] & O_CREAT) { 93 /* mode */ 94 tprintf(", %#lo", tcp->u_arg[offset + 2]); 95 } 96 } 97 return RVAL_FD; 98 } 99 100 SYS_FUNC(open) 101 { 102 return decode_open(tcp, 0); 103 } 104 105 SYS_FUNC(openat) 106 { 107 if (entering(tcp)) 108 print_dirfd(tcp, tcp->u_arg[0]); 109 return decode_open(tcp, 1); 110 } 111 112 SYS_FUNC(creat) 113 { 114 if (entering(tcp)) { 115 printpath(tcp, tcp->u_arg[0]); 116 tprintf(", %#lo", tcp->u_arg[1]); 117 } 118 return RVAL_FD; 119 } 120