diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2014-03-03 23:09:47 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2014-03-03 23:30:04 +0000 |
commit | 54cabefc753cc72417bb610cb9f7873f4389e9f5 (patch) | |
tree | 9ae20bb2e5a8467c69d9d30bbf0b10db1564104d | |
parent | ec21e07441030009a53786905ccbeaaed5e0ee9c (diff) | |
download | strace-54cabefc753cc72417bb610cb9f7873f4389e9f5.tar.gz strace-54cabefc753cc72417bb610cb9f7873f4389e9f5.tar.bz2 strace-54cabefc753cc72417bb610cb9f7873f4389e9f5.tar.xz |
Fix fcntl decoding
Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined or
not defined altogether.
Do not assume that sizeof(off_t) < sizeof(long long) when F_SETLK64 is
undefined.
This change fixes build with musl libc on x86.
* configure.ac: Define SIZEOF_OFF_T.
* desc.c (USE_PRINTFLOCK64): New macro.
(struct flock64, printflock64): Do not define on X32.
(printflock): Replace X32 specific workaround with SIZEOF_OFF_T check.
Fix printing off_t members of struct flock.
(sys_fcntl): Use USE_PRINTFLOCK64.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | desc.c | 84 |
2 files changed, 34 insertions, 51 deletions
diff --git a/configure.ac b/configure.ac index caa5aed..682f54e 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,7 @@ AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64], AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([off_t],,[#include <sys/types.h>]) AC_CHECK_SIZEOF([rlim_t],,[#include <sys/resource.h>]) AC_CACHE_CHECK([for SA_RESTORER], [st_cv_sa_restorer], @@ -214,35 +214,26 @@ static const struct xlat perf_event_open_flags[] = { XLAT_END }; +/* + * Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined + * or not defined altogether. + */ #if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK -# define HAVE_F_SETLK64 1 -#else -# define HAVE_F_SETLK64 0 -#endif - -#if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW -# define HAVE_F_SETLKW64 1 -#else -# define HAVE_F_SETLKW64 0 -#endif - -#if defined(F_GETLK64) && F_GETLK64+0 != F_GETLK -# define HAVE_F_GETLK64 1 +# define USE_PRINTFLOCK64 1 #else -# define HAVE_F_GETLK64 0 +# define USE_PRINTFLOCK64 0 #endif -#if defined(X32) || HAVE_F_SETLK64 || HAVE_F_SETLKW64 || HAVE_F_GETLK64 +#if USE_PRINTFLOCK64 -#ifndef HAVE_STRUCT_FLOCK64 +# ifndef HAVE_STRUCT_FLOCK64 struct flock64 { short int l_type, l_whence; int64_t l_start, l_len; int l_pid; }; -#endif +# endif -/* fcntl/lockf */ static void printflock64(struct tcb *tcp, long addr, int getlk) { @@ -262,22 +253,20 @@ printflock64(struct tcb *tcp, long addr, int getlk) else tprints("}"); } -#endif +#endif /* USE_PRINTFLOCK64 */ -/* fcntl/lockf */ static void printflock(struct tcb *tcp, long addr, int getlk) { struct flock fl; + int r; #if SUPPORTED_PERSONALITIES > 1 -# ifdef X32 - if (current_personality == 0) { - printflock64(tcp, addr, getlk); - return; - } -# endif - if (current_wordsize != sizeof(fl.l_start)) { + if ( +# if SIZEOF_OFF_T > SIZEOF_LONG + current_personality > 0 && +#endif + current_wordsize != sizeof(fl.l_start)) { if (current_wordsize == 4) { /* 32-bit x86 app on x86_64 and similar cases */ struct { @@ -287,15 +276,14 @@ printflock(struct tcb *tcp, long addr, int getlk) int32_t l_len; /* off_t */ int32_t l_pid; /* pid_t */ } fl32; - if (umove(tcp, addr, &fl32) < 0) { - tprints("{...}"); - return; + r = umove(tcp, addr, &fl32); + if (r >= 0) { + fl.l_type = fl32.l_type; + fl.l_whence = fl32.l_whence; + fl.l_start = fl32.l_start; + fl.l_len = fl32.l_len; + fl.l_pid = fl32.l_pid; } - fl.l_type = fl32.l_type; - fl.l_whence = fl32.l_whence; - fl.l_start = fl32.l_start; - fl.l_len = fl32.l_len; - fl.l_pid = fl32.l_pid; } else { /* let people know we have a problem here */ tprintf("<decode error: unsupported wordsize %d>", @@ -305,16 +293,17 @@ printflock(struct tcb *tcp, long addr, int getlk) } else #endif { - if (umove(tcp, addr, &fl) < 0) { - tprints("{...}"); - return; - } + r = umove(tcp, addr, &fl); + } + if (r < 0) { + tprints("{...}"); + return; } tprints("{type="); printxval(lockfcmds, fl.l_type, "F_???"); tprints(", whence="); printxval(whence_codes, fl.l_whence, "SEEK_???"); -#ifdef X32 +#if SIZEOF_OFF_T > SIZEOF_LONG tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len); #else tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len); @@ -351,19 +340,12 @@ sys_fcntl(struct tcb *tcp) tprints(", "); printflock(tcp, tcp->u_arg[2], 0); break; -#if HAVE_F_SETLK64 || HAVE_F_SETLKW64 - /* Linux glibc defines SETLK64 as SETLK, - even though the kernel has different values - as does Solaris. */ -#if HAVE_F_SETLK64 - case F_SETLK64: -#endif -#if HAVE_F_SETLKW64 - case F_SETLKW64: -#endif +#if USE_PRINTFLOCK64 + case F_SETLK64: case F_SETLKW64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 0); break; -#endif /* HAVE_F_SETLK64 || HAVE_F_SETLKW64 */ +#endif /* USE_PRINTFLOCK64 */ #ifdef F_NOTIFY case F_NOTIFY: tprints(", "); @@ -408,7 +390,7 @@ sys_fcntl(struct tcb *tcp) tprints(", "); printflock(tcp, tcp->u_arg[2], 1); break; -#if HAVE_F_GETLK64 +#if USE_PRINTFLOCK64 case F_GETLK64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 1); |