]> granicus.if.org Git - strace/commitdiff
Decode fcntl's F_{GET,SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC.
authorDenys Vlasenko <dvlasenk@redhat.com>
Tue, 10 Mar 2009 20:41:58 +0000 (20:41 +0000)
committerDenys Vlasenko <dvlasenk@redhat.com>
Tue, 10 Mar 2009 20:41:58 +0000 (20:41 +0000)
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().

ChangeLog
defs.h
desc.c
file.c
ipc.c

index eb8026a4ea733c77a9f8f0585af035e9d975d39d..ce685802b5174de770180abaf57c40e62fefb714 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2009-03-10  Denys Vlasenko  <dvlasenk@redhat.com>
+
+       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  <dvlasenk@redhat.com>
 
        AVR32 support by Hans-Christian Egtvedt
diff --git a/defs.h b/defs.h
index 9eb81626da2bb4951ba847b70ca579ec1c1e9573..2f5683be4352fb30f83f108e540fd3043d57d270 100644 (file)
--- 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 cd6259a173fc12a870980c95ed502f3578f92e5b..3aae9908472037c3ca75ade6dd1412324d04db3c 100644 (file)
--- 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 3496bb23a09f194a9fd0c88c1e40613848d080bf..f283a352831052f336ab7caa437c8ecf13d16f82 100644 (file)
--- 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 548d2e1a3818339ade827dbfefd8c8337c165888..ab294128d223b014e4ac9916d63e8f8aaffea699 100644 (file)
--- 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