From: Denys Vlasenko Date: Tue, 10 Mar 2009 20:41:58 +0000 (+0000) Subject: Decode fcntl's F_{GET,SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC. X-Git-Tag: v4.5.19~66 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eedaac768dcb55346292495440f1201bd7b2b1b4;p=strace Decode fcntl's F_{GET,SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC. By Mike Frysinger (vapier AT gentoo.org) * desc.c: Add F_SETLEASE, F_GETLEASE, F_NOTIFY, F_DUPFD_CLOEXEC to fcntlcmds[]. Create notifyflags[] array. (sys_fcntl): Handle new flags. Optimize printing of open modes. * defs.h: Declare sprint_open_modes(), remove unused parameter in tprint_open_modes(). * desc.c (sprint_open_modes): Move fuction definition from here... * file.c (sprint_open_modes): To here. (tprint_open_modes): Use sprint_open_modes(), it already generates needed string. * ipc.c: Remove unused parameter from calls to tprint_open_modes(). --- diff --git a/ChangeLog b/ChangeLog index eb8026a4..ce685802 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2009-03-10 Denys Vlasenko + + Decode fcntl's F_{GET,SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC. + By Mike Frysinger (vapier AT gentoo.org) + * desc.c: Add F_SETLEASE, F_GETLEASE, F_NOTIFY, + F_DUPFD_CLOEXEC to fcntlcmds[]. Create notifyflags[] array. + (sys_fcntl): Handle new flags. + + Optimize printing of open modes. + * defs.h: Declare sprint_open_modes(), + remove unused parameter in tprint_open_modes(). + * desc.c (sprint_open_modes): Move fuction definition from here... + * file.c (sprint_open_modes): To here. + (tprint_open_modes): Use sprint_open_modes(), it already + generates needed string. + * ipc.c: Remove unused parameter from calls + to tprint_open_modes(). + 2009-02-27 Denys Vlasenko AVR32 support by Hans-Christian Egtvedt diff --git a/defs.h b/defs.h index 9eb81626..2f5683be 100644 --- a/defs.h +++ b/defs.h @@ -534,7 +534,8 @@ extern void printtrailer P((void)); extern void tabto P((int)); extern void call_summary P((FILE *)); extern void tprint_iov P((struct tcb *, unsigned long, unsigned long)); -extern void tprint_open_modes P((struct tcb *, mode_t)); +extern void tprint_open_modes P((mode_t)); +extern const char *sprint_open_modes P((mode_t)); extern int is_restart_error P((struct tcb *)); extern int change_syscall P((struct tcb *, int)); diff --git a/desc.c b/desc.c index cd6259a1..3aae9908 100644 --- a/desc.c +++ b/desc.c @@ -147,6 +147,18 @@ static const struct xlat fcntlcmds[] = { #endif #ifdef F_UNSHARE { F_UNSHARE, "F_UNSHARE" }, +#endif +#ifdef F_SETLEASE + { F_SETLEASE, "F_SETLEASE" }, +#endif +#ifdef F_GETLEASE + { F_GETLEASE, "F_GETLEASE" }, +#endif +#ifdef F_NOTIFY + { F_NOTIFY, "F_NOTIFY" }, +#endif +#ifdef F_DUPFD_CLOEXEC + { F_DUPFD_CLOEXEC,"F_DUPFD_CLOEXEC"}, #endif { 0, NULL }, }; @@ -183,6 +195,33 @@ static const struct xlat lockfcmds[] = { { 0, NULL }, }; +#ifdef F_NOTIFY +static const struct xlat notifyflags[] = { +#ifdef DN_ACCESS + { DN_ACCESS, "DN_ACCESS" }, +#endif +#ifdef DN_MODIFY + { DN_MODIFY, "DN_MODIFY" }, +#endif +#ifdef DN_CREATE + { DN_CREATE, "DN_CREATE" }, +#endif +#ifdef DN_DELETE + { DN_DELETE, "DN_DELETE" }, +#endif +#ifdef DN_RENAME + { DN_RENAME, "DN_RENAME" }, +#endif +#ifdef DN_ATTRIB + { DN_ATTRIB, "DN_ATTRIB" }, +#endif +#ifdef DN_MULTISHOT + { DN_MULTISHOT, "DN_MULTISHOT" }, +#endif + { 0, NULL }, +}; +#endif + static const struct xlat whence[] = { { SEEK_SET, "SEEK_SET" }, { SEEK_CUR, "SEEK_CUR" }, @@ -261,40 +300,6 @@ printflock64(struct tcb *tcp, long addr, int getlk) } #endif -/* - * low bits of the open(2) flags define access mode, - * other bits are real flags. - */ -static const char * -sprint_open_modes(mode_t flags) -{ - static char outstr[1024]; - const char *str = xlookup(open_access_modes, flags & 3); - const char *sep = ""; - const struct xlat *x; - - strcpy(outstr, "flags "); - if (str) { - strcat(outstr, str); - flags &= ~3; - if (!flags) - return outstr; - strcat(outstr, "|"); - } - - for (x = open_mode_flags; x->str; x++) { - if ((flags & x->val) == x->val) { - sprintf(outstr + strlen(outstr), - "%s%s", sep, x->str); - sep = "|"; - flags &= ~x->val; - } - } - if (flags) - sprintf(outstr + strlen(outstr), "%s%#x", sep, flags); - return outstr; -} - int sys_fcntl(struct tcb *tcp) { @@ -307,11 +312,14 @@ sys_fcntl(struct tcb *tcp) printflags(fdflags, tcp->u_arg[2], "FD_???"); break; case F_SETOWN: case F_DUPFD: +#ifdef F_DUPFD_CLOEXEC + case F_DUPFD_CLOEXEC: +#endif tprintf(", %ld", tcp->u_arg[2]); break; case F_SETFL: tprintf(", "); - tprint_open_modes(tcp, tcp->u_arg[2]); + tprint_open_modes(tcp->u_arg[2]); break; case F_SETLK: case F_SETLKW: #ifdef F_FREESP @@ -326,30 +334,50 @@ sys_fcntl(struct tcb *tcp) #endif /* Linux glibc defines SETLK64 as SETLK, even though the kernel has different values - as does Solaris. */ -#if defined(F_SETLK64) && F_SETLK64+0!=F_SETLK +#if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK case F_SETLK64: #endif -#if defined(F_SETLKW64) && F_SETLKW64+0!=F_SETLKW +#if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW case F_SETLKW64: #endif tprintf(", "); printflock64(tcp, tcp->u_arg[2], 0); break; +#endif +#ifdef F_NOTIFY + case F_NOTIFY: + tprintf(", "); + printflags(notifyflags, tcp->u_arg[2], "DN_???"); + break; +#endif +#ifdef F_SETLEASE + case F_SETLEASE: + tprintf(", "); + printxval(lockfcmds, tcp->u_arg[2], "F_???"); + break; #endif } } else { switch (tcp->u_arg[1]) { case F_DUPFD: +#ifdef F_DUPFD_CLOEXEC + case F_DUPFD_CLOEXEC: +#endif case F_SETFD: case F_SETFL: case F_SETLK: case F_SETLKW: case F_SETOWN: case F_GETOWN: +#ifdef F_NOTIFY + case F_NOTIFY: +#endif +#ifdef F_SETLEASE + case F_SETLEASE: +#endif break; case F_GETFD: if (syserror(tcp) || tcp->u_rval == 0) return 0; - tcp->auxstr = - sprintflags("flags ", fdflags, tcp->u_rval); + tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval); return RVAL_HEX|RVAL_STR; case F_GETFL: if (syserror(tcp)) @@ -367,6 +395,13 @@ sys_fcntl(struct tcb *tcp) tprintf(", "); printflock64(tcp, tcp->u_arg[2], 1); break; +#endif +#ifdef F_GETLEASE + case F_GETLEASE: + if (syserror(tcp)) + return 0; + tcp->auxstr = xlookup(lockfcmds, tcp->u_rval); + return RVAL_HEX|RVAL_STR; #endif default: tprintf(", %#lx", tcp->u_arg[2]); diff --git a/file.c b/file.c index 3496bb23..f283a352 100644 --- a/file.c +++ b/file.c @@ -239,7 +239,7 @@ const struct xlat open_mode_flags[] = { #ifdef O_RSYNC { O_RSYNC, "O_RSYNC" }, #endif -#ifdef O_NDELAY +#if defined(O_NDELAY) && (O_NDELAY != O_NONBLOCK) { O_NDELAY, "O_NDELAY" }, #endif #ifdef O_PRIV @@ -339,23 +339,61 @@ print_dirfd(long fd) #endif /* - * low bits of the open(2) flags define access mode, - * other bits are real flags. + * Pity stpcpy() is not standardized... */ -void -tprint_open_modes(struct tcb *tcp, mode_t flags) +static char * +str_append(char *dst, const char *src) { - const char *str = xlookup(open_access_modes, flags & 3); + while ((*dst = *src++) != '\0') + dst++; + return dst; +} - if (str) - { - tprintf("%s", str); +/* + * low bits of the open(2) flags define access mode, + * other bits are real flags. + */ +const char * +sprint_open_modes(mode_t flags) +{ + static char outstr[1024]; + char *p; + char sep = 0; + const char *str; + const struct xlat *x; + + p = str_append(outstr, "flags "); + str = xlookup(open_access_modes, flags & 3); + if (str) { + p = str_append(p, str); flags &= ~3; if (!flags) - return; - tprintf("|"); + return outstr; + sep = '|'; + } + + for (x = open_mode_flags; x->str; x++) { + if ((flags & x->val) == x->val) { + if (sep) + *p++ = sep; + p = str_append(p, x->str); + flags &= ~x->val; + if (!flags) + return outstr; + sep = '|'; + } } - printflags(open_mode_flags, flags, "O_???"); + /* flags is still nonzero */ + if (sep) + *p++ = sep; + sprintf(p, "%#x", flags); + return outstr; +} + +void +tprint_open_modes(mode_t flags) +{ + tprintf(sprint_open_modes(flags) + sizeof("flags")); } static int @@ -365,7 +403,7 @@ decode_open(struct tcb *tcp, int offset) printpath(tcp, tcp->u_arg[offset]); tprintf(", "); /* flags */ - tprint_open_modes(tcp, tcp->u_arg[offset + 1]); + tprint_open_modes(tcp->u_arg[offset + 1]); if (tcp->u_arg[offset + 1] & O_CREAT) { /* mode */ tprintf(", %#lo", tcp->u_arg[offset + 2]); diff --git a/ipc.c b/ipc.c index 548d2e1a..ab294128 100644 --- a/ipc.c +++ b/ipc.c @@ -420,7 +420,7 @@ sys_mq_open(struct tcb *tcp) printpath(tcp, tcp->u_arg[0]); tprintf(", "); /* flags */ - tprint_open_modes(tcp, tcp->u_arg[1]); + tprint_open_modes(tcp->u_arg[1]); if (tcp->u_arg[1] & O_CREAT) { # ifndef HAVE_MQUEUE_H tprintf(", %lx", tcp->u_arg[2]); @@ -489,7 +489,7 @@ printmqattr(struct tcb *tcp, long addr) return; } tprintf("{mq_flags="); - tprint_open_modes(tcp, attr.mq_flags); + tprint_open_modes(attr.mq_flags); tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); # endif