syscall-dump: add lseek/lseek64 wrappers, add log write loop, keep errno
This commit is contained in:
		@@ -11,6 +11,7 @@ Usage:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _LARGEFILE64_SOURCE
 | 
				
			||||||
#include <dlfcn.h>
 | 
					#include <dlfcn.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
@@ -37,6 +38,8 @@ static int (*real_open64)(const char *pathname, int flags, ...);
 | 
				
			|||||||
static int (*real_ioctl)(int fd, unsigned long request, ...);
 | 
					static int (*real_ioctl)(int fd, unsigned long request, ...);
 | 
				
			||||||
static ssize_t (*real_write)(int fd, const void *buf, size_t len);
 | 
					static ssize_t (*real_write)(int fd, const void *buf, size_t len);
 | 
				
			||||||
static ssize_t (*real_read)(int fd, void *buf, size_t len);
 | 
					static ssize_t (*real_read)(int fd, void *buf, size_t len);
 | 
				
			||||||
 | 
					static off_t (*real_lseek)(int fd, off_t offset, int whence);
 | 
				
			||||||
 | 
					static off64_t (*real_lseek64)(int fd, off64_t offset, int whence);
 | 
				
			||||||
static int (*real_close)(int fd);
 | 
					static int (*real_close)(int fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REDIR(realptr, symname) do { \
 | 
					#define REDIR(realptr, symname) do { \
 | 
				
			||||||
@@ -51,8 +54,11 @@ static int (*real_close)(int fd);
 | 
				
			|||||||
/* log function */
 | 
					/* log function */
 | 
				
			||||||
static void dlog(const char *fmt, ...)
 | 
					static void dlog(const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  char buf[2048];
 | 
					  char buf[2048], *b;
 | 
				
			||||||
  va_list ap;
 | 
					  va_list ap;
 | 
				
			||||||
 | 
					  size_t len;
 | 
				
			||||||
 | 
					  ssize_t r;
 | 
				
			||||||
 | 
					  int keep_errno = errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (dlog_fd < 0) {
 | 
					  if (dlog_fd < 0) {
 | 
				
			||||||
    const char *f = getenv("SYSCALL_DUMP_LOG");
 | 
					    const char *f = getenv("SYSCALL_DUMP_LOG");
 | 
				
			||||||
@@ -64,13 +70,25 @@ static void dlog(const char *fmt, ...)
 | 
				
			|||||||
  vsnprintf(buf, sizeof(buf), fmt, ap);
 | 
					  vsnprintf(buf, sizeof(buf), fmt, ap);
 | 
				
			||||||
  va_end(ap);
 | 
					  va_end(ap);
 | 
				
			||||||
  REDIR(real_write, "write");
 | 
					  REDIR(real_write, "write");
 | 
				
			||||||
  real_write(dlog_fd, buf, strlen(buf));
 | 
					  len = strlen(b = buf);
 | 
				
			||||||
 | 
					  while (len > 0) {
 | 
				
			||||||
 | 
					    r = real_write(dlog_fd, b, len);
 | 
				
			||||||
 | 
					    if (r < 0) {
 | 
				
			||||||
 | 
					      if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK)
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      len -= r;
 | 
				
			||||||
 | 
					      b += r;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  errno = keep_errno;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dlog_hexa(const char *prefix, void *buf, size_t len)
 | 
					static void dlog_hexa(const char *prefix, void *buf, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  char b[128];
 | 
					  char b[128];
 | 
				
			||||||
  size_t i, l;
 | 
					  size_t i, l;
 | 
				
			||||||
 | 
					  int keep_errno = errno;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  while (len > 0) {
 | 
					  while (len > 0) {
 | 
				
			||||||
    for (i = l = 0; i < 16 && len > 0; i++, len--, buf++)
 | 
					    for (i = l = 0; i < 16 && len > 0; i++, len--, buf++)
 | 
				
			||||||
@@ -79,6 +97,7 @@ static void dlog_hexa(const char *prefix, void *buf, size_t len)
 | 
				
			|||||||
    b[l+1] = '\0';
 | 
					    b[l+1] = '\0';
 | 
				
			||||||
    dlog("%s %s", prefix, b);
 | 
					    dlog("%s %s", prefix, b);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  errno = keep_errno;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* open() wrapper */
 | 
					/* open() wrapper */
 | 
				
			||||||
@@ -149,7 +168,12 @@ ssize_t write(int fd, const void *buf, size_t len)
 | 
				
			|||||||
  REDIR(real_write, "write");
 | 
					  REDIR(real_write, "write");
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  r = real_write(fd, buf, len);
 | 
					  r = real_write(fd, buf, len);
 | 
				
			||||||
 | 
					  if (r > 0) {
 | 
				
			||||||
 | 
					    dlog_hexa("write:", (void *)buf, r);
 | 
				
			||||||
    dlog("  write(%d, %p, %zd) = %d (%d)\n", fd, buf, len, r, E(r));
 | 
					    dlog("  write(%d, %p, %zd) = %d (%d)\n", fd, buf, len, r, E(r));
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    dlog("write(%d, %p, %zd) = %d (%d)\n", fd, buf, len, r, E(r));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return r;
 | 
					  return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -167,6 +191,32 @@ ssize_t read(int fd, void *buf, size_t len)
 | 
				
			|||||||
  return r;
 | 
					  return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lseek() wrapper */
 | 
				
			||||||
 | 
					off_t lseek(int fd, off_t offset, int whence)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  REDIR(real_lseek, "lseek");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  r = real_lseek(fd, offset, whence);
 | 
				
			||||||
 | 
					  dlog("lseek(%d, %lx, %d) = %d (%d)\n", fd, (long)offset, whence, r, E(r));
 | 
				
			||||||
 | 
					  return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lseek64() wrapper */
 | 
				
			||||||
 | 
					off64_t lseek64(int fd, off64_t offset, int whence)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  REDIR(real_lseek64, "lseek64");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  r = real_lseek64(fd, offset, whence);
 | 
				
			||||||
 | 
					  dlog("lseek(%d, %llx, %d) = %d (%d)\n", fd, (long long)offset, whence, r, E(r));
 | 
				
			||||||
 | 
					  return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ioctl() wrapper */
 | 
					/* ioctl() wrapper */
 | 
				
			||||||
int ioctl(int fd, unsigned long request, ...)
 | 
					int ioctl(int fd, unsigned long request, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user