Home | History | Annotate | Download | only in strace
      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