summaryrefslogtreecommitdiffstats
path: root/usr.bin/truss
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2008-07-31 17:15:21 +0000
committerdes <des@FreeBSD.org>2008-07-31 17:15:21 +0000
commit99ec4c843d18fdc20a8ba8ec77c64558085c8794 (patch)
tree2b39415e5dd45710f70b33df72327339b82e8fff /usr.bin/truss
parent743d0edd9200e99955e096f8c7d04c3712e3c463 (diff)
downloadFreeBSD-src-99ec4c843d18fdc20a8ba8ec77c64558085c8794.zip
FreeBSD-src-99ec4c843d18fdc20a8ba8ec77c64558085c8794.tar.gz
Try to make this code slightly less painful to read.
Diffstat (limited to 'usr.bin/truss')
-rw-r--r--usr.bin/truss/syscall.h2
-rw-r--r--usr.bin/truss/syscalls.c1361
2 files changed, 673 insertions, 690 deletions
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h
index ccd83bb..39a796a 100644
--- a/usr.bin/truss/syscall.h
+++ b/usr.bin/truss/syscall.h
@@ -25,7 +25,7 @@
* Sigset -- a pointer to a sigset_t. Prints the signals that are set.
* Sigprocmask -- the first argument to sigprocmask(). Prints the name.
* Kevent -- a pointer to an array of struct kevents. Prints all elements.
- * Pathconf -- the 2nd argument of patchconf().
+ * Pathconf -- the 2nd argument of pathconf().
*
* In addition, the pointer types (String, Ptr) may have OUT masked in --
* this means that the data is set on *return* from the system call -- or
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 18f87fe..d1b390b 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -92,64 +92,62 @@ static const char rcsid[] =
struct syscall syscalls[] = {
{ "fcntl", 1, 3,
- { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 }}},
+ { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } },
{ "readlink", 1, 3,
- { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 }}},
+ { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 } } },
{ "lseek", 2, 3,
- { {Int, 0}, {Quad, 1 + QUAD_ALIGN},
- {Whence, 1 + QUAD_SLOTS + QUAD_ALIGN}}},
+ { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } },
{ "linux_lseek", 2, 3,
- { { Int, 0 }, {Int, 1 }, { Whence, 2 }}},
+ { { Int, 0 }, { Int, 1 }, { Whence, 2 } } },
{ "mmap", 2, 6,
- { {Ptr, 0}, {Int, 1}, {Mprot, 2}, {Mmapflags, 3}, {Int, 4},
- {Quad, 5 + QUAD_ALIGN}}},
+ { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } },
{ "mprotect", 1, 3,
- { { Ptr, 0 }, {Int, 1}, {Mprot, 2}}},
+ { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } },
{ "open", 1, 3,
- { { Name | IN, 0} , { Open, 1}, {Octal, 2}}},
+ { { Name | IN, 0 } , { Open, 1 }, { Octal, 2 } } },
{ "mkdir", 1, 2,
- { { Name, 0} , {Octal, 1}}},
+ { { Name, 0 } , { Octal, 1 } } },
{ "linux_open", 1, 3,
- { { Name, 0 }, { Hex, 1}, { Octal, 2 }}},
+ { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
{ "close", 1, 1,
{ { Int, 0 } } },
{ "link", 0, 2,
- { { Name, 0 }, { Name, 1 }}},
+ { { Name, 0 }, { Name, 1 } } },
{ "unlink", 0, 1,
- { { Name, 0 }}},
+ { { Name, 0 } } },
{ "chdir", 0, 1,
- { { Name, 0 }}},
+ { { Name, 0 } } },
{ "chroot", 0, 1,
- { { Name, 0 }}},
+ { { Name, 0 } } },
{ "mknod", 0, 3,
- { { Name, 0 }, { Octal, 1 }, { Int, 3 }}},
+ { { Name, 0 }, { Octal, 1 }, { Int, 3 } } },
{ "chmod", 0, 2,
- { { Name, 0 }, { Octal, 1 }}},
+ { { Name, 0 }, { Octal, 1 } } },
{ "chown", 0, 3,
- { { Name, 0 }, { Int, 1 }, { Int, 2 }}},
+ { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
{ "mount", 0, 4,
- { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 }}},
+ { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } },
{ "umount", 0, 2,
- { { Name, 0 }, { Int, 2 }}},
+ { { Name, 0 }, { Int, 2 } } },
{ "fstat", 1, 2,
- { { Int, 0}, { Stat | OUT , 1 }}},
+ { { Int, 0 }, { Stat | OUT , 1 } } },
{ "stat", 1, 2,
- { { Name | IN, 0 }, { Stat | OUT, 1 }}},
+ { { Name | IN, 0 }, { Stat | OUT, 1 } } },
{ "lstat", 1, 2,
- { { Name | IN, 0 }, { Stat | OUT, 1 }}},
+ { { Name | IN, 0 }, { Stat | OUT, 1 } } },
{ "linux_newstat", 1, 2,
- { { Name | IN, 0 }, { Ptr | OUT, 1 }}},
+ { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
{ "linux_newfstat", 1, 2,
- { { Int, 0 }, { Ptr | OUT, 1 }}},
+ { { Int, 0 }, { Ptr | OUT, 1 } } },
{ "write", 1, 3,
- { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }}},
+ { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 } } },
{ "ioctl", 1, 3,
- { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 }}},
- { "break", 1, 1, { { Ptr, 0 }}},
- { "exit", 0, 1, { { Hex, 0 }}},
- { "access", 1, 2, { { Name | IN, 0 }, { Int, 1 }}},
+ { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 } } },
+ { "break", 1, 1, { { Ptr, 0 } } },
+ { "exit", 0, 1, { { Hex, 0 } } },
+ { "access", 1, 2, { { Name | IN, 0 }, { Int, 1 } } },
{ "sigaction", 1, 3,
- { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 }}},
+ { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } },
{ "accept", 1, 3,
{ { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
{ "bind", 1, 3,
@@ -168,58 +166,58 @@ struct syscall syscalls[] = {
{ { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } },
{ "linux_execve", 1, 3,
{ { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } },
- { "kldload", 0, 1, { { Name | IN, 0 }}},
- { "kldunload", 0, 1, { { Int, 0 }}},
- { "kldfind", 0, 1, { { Name | IN, 0 }}},
- { "kldnext", 0, 1, { { Int, 0 }}},
- { "kldstat", 0, 2, { { Int, 0 }, { Ptr, 1 }}},
- { "kldfirstmod", 0, 1, { { Int, 0 }}},
- { "nanosleep", 0, 1, { { Timespec, 0 }}},
- { "select", 1, 5, { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, { Timeval, 4 }}},
- { "poll", 1, 3, { { Pollfd, 0 }, { Int, 1 }, { Int, 2 }}},
- { "gettimeofday", 1, 2, { { Timeval | OUT, 0 }, { Ptr, 1 }}},
- { "clock_gettime", 1, 2, { { Int, 0 }, { Timespec | OUT, 1 }}},
- { "getitimer", 1, 2, { { Int, 0 }, { Itimerval | OUT, 2 }}},
- { "setitimer", 1, 3, { { Int, 0 }, { Itimerval, 1} , { Itimerval | OUT, 2 }}},
- { "kse_release", 0, 1, { { Timespec, 0 }}},
- { "kevent", 0, 6, { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 }}},
- { "_umtx_lock", 0, 1, { { Umtx, 0 }}},
- { "_umtx_unlock", 0, 1, { { Umtx, 0 }}},
- { "sigprocmask", 0, 3, { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 }}},
- { "unmount", 1, 2, { { Name, 0 }, { Int, 1 }}},
- { "socket", 1, 3, { { Sockdomain, 0}, { Socktype, 1}, {Int, 2 }}},
- { "getrusage", 1, 2, { { Int, 0 }, { Rusage | OUT, 1 }}},
- { "__getcwd", 1, 2, { { Name | OUT, 0}, { Int, 1 }}},
- { "shutdown", 1, 2, { { Int, 0}, { Shutdown, 1}}},
- { "getrlimit", 1, 2, { { Resource, 0}, {Rlimit | OUT, 1}}},
- { "setrlimit", 1, 2, { { Resource, 0}, {Rlimit | IN, 1}}},
+ { "kldload", 0, 1, { { Name | IN, 0 } } },
+ { "kldunload", 0, 1, { { Int, 0 } } },
+ { "kldfind", 0, 1, { { Name | IN, 0 } } },
+ { "kldnext", 0, 1, { { Int, 0 } } },
+ { "kldstat", 0, 2, { { Int, 0 }, { Ptr, 1 } } },
+ { "kldfirstmod", 0, 1, { { Int, 0 } } },
+ { "nanosleep", 0, 1, { { Timespec, 0 } } },
+ { "select", 1, 5, { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, { Timeval, 4 } } },
+ { "poll", 1, 3, { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } },
+ { "gettimeofday", 1, 2, { { Timeval | OUT, 0 }, { Ptr, 1 } } },
+ { "clock_gettime", 1, 2, { { Int, 0 }, { Timespec | OUT, 1 } } },
+ { "getitimer", 1, 2, { { Int, 0 }, { Itimerval | OUT, 2 } } },
+ { "setitimer", 1, 3, { { Int, 0 }, { Itimerval, 1 } , { Itimerval | OUT, 2 } } },
+ { "kse_release", 0, 1, { { Timespec, 0 } } },
+ { "kevent", 0, 6, { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } },
+ { "_umtx_lock", 0, 1, { { Umtx, 0 } } },
+ { "_umtx_unlock", 0, 1, { { Umtx, 0 } } },
+ { "sigprocmask", 0, 3, { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
+ { "unmount", 1, 2, { { Name, 0 }, { Int, 1 } } },
+ { "socket", 1, 3, { { Sockdomain, 0 }, { Socktype, 1 }, { Int, 2 } } },
+ { "getrusage", 1, 2, { { Int, 0 }, { Rusage | OUT, 1 } } },
+ { "__getcwd", 1, 2, { { Name | OUT, 0 }, { Int, 1 } } },
+ { "shutdown", 1, 2, { { Int, 0 }, { Shutdown, 1 } } },
+ { "getrlimit", 1, 2, { { Resource, 0 }, { Rlimit | OUT, 1 } } },
+ { "setrlimit", 1, 2, { { Resource, 0 }, { Rlimit | IN, 1 } } },
{ "utimes", 1, 2,
- { { Name | IN, 0 }, { Timeval2 | IN, 1 }}},
+ { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
{ "lutimes", 1, 2,
- { { Name | IN, 0 }, { Timeval2 | IN, 1 }}},
+ { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
{ "futimes", 1, 2,
- { { Int, 0 }, { Timeval | IN, 1 }}},
+ { { Int, 0 }, { Timeval | IN, 1 } } },
{ "chflags", 1, 2,
- { { Name | IN, 0 }, { Hex, 1 }}},
+ { { Name | IN, 0 }, { Hex, 1 } } },
{ "lchflags", 1, 2,
- { { Name | IN, 0 }, { Hex, 1 }}},
+ { { Name | IN, 0 }, { Hex, 1 } } },
{ "pathconf", 1, 2,
- { { Name | IN, 0 }, { Pathconf, 1 }}},
+ { { Name | IN, 0 }, { Pathconf, 1 } } },
{ "truncate", 1, 3,
- { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 }}},
+ { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } },
{ "ftruncate", 1, 3,
- { { Int | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 }}},
+ { { Int | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } },
{ "kill", 1, 2,
- { { Int | IN, 0 }, { Signal | IN, 1}}},
+ { { Int | IN, 0 }, { Signal | IN, 1 } } },
{ "munmap", 1, 2,
- { { Ptr, 0 }, { Int, 1 }}},
+ { { Ptr, 0 }, { Int, 1 } } },
{ "read", 1, 3,
- { { Int, 0}, { BinString | OUT, 1}, { Int, 2}}},
+ { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } },
{ "rename", 1, 2,
- { { Name , 0} , { Name, 1}}},
+ { { Name , 0 } , { Name, 1 } } },
{ "symlink", 1, 2,
- { { Name , 0} , { Name, 1}}},
- { 0, 0, 0, { { 0, 0 }}},
+ { { Name , 0 } , { Name, 1 } } },
+ { 0, 0, 0, { { 0, 0 } } },
};
/* Xlat idea taken from strace */
@@ -331,15 +329,18 @@ static struct xlat pathconf_arg[] = {
#undef X
#undef XEND
-/* Searches an xlat array for a value, and returns it if found. Otherwise
- return a string representation. */
-static const char
-*lookup(struct xlat *xlat, int val, int base)
+/*
+ * Searches an xlat array for a value, and returns it if found. Otherwise
+ * return a string representation.
+ */
+static const char *
+lookup(struct xlat *xlat, int val, int base)
{
static char tmp[16];
+
for (; xlat->str != NULL; xlat++)
if (xlat->val == val)
- return xlat->str;
+ return (xlat->str);
switch (base) {
case 8:
sprintf(tmp, "0%o", val);
@@ -354,29 +355,28 @@ static const char
errx(1,"Unknown lookup base");
break;
}
- return tmp;
+ return (tmp);
}
static const char *
xlookup(struct xlat *xlat, int val)
{
- return lookup(xlat, val, 16);
+
+ return (lookup(xlat, val, 16));
}
/* Searches an xlat array containing bitfield values. Remaining bits
set after removing the known ones are printed at the end:
IN|0x400 */
-static char
-*xlookup_bits(struct xlat *xlat, int val)
+static char *
+xlookup_bits(struct xlat *xlat, int val)
{
static char str[512];
int len = 0;
int rem = val;
- for (; xlat->str != NULL; xlat++)
- {
- if ((xlat->val & rem) == xlat->val)
- {
+ for (; xlat->str != NULL; xlat++) {
+ if ((xlat->val & rem) == xlat->val) {
/* don't print the "all-bits-zero" string unless all
bits are really zero */
if (xlat->val == 0 && val != 0)
@@ -391,7 +391,7 @@ static char
if (len && str[len - 1] == '|')
len--;
str[len] = 0;
- return str;
+ return (str);
}
/*
@@ -400,17 +400,18 @@ static char
*/
struct syscall *
-get_syscall(const char *name) {
+get_syscall(const char *name)
+{
struct syscall *sc = syscalls;
if (name == NULL)
return (NULL);
while (sc->name) {
if (!strcmp(name, sc->name))
- return sc;
+ return (sc);
sc++;
}
- return NULL;
+ return (NULL);
}
/*
@@ -420,20 +421,21 @@ get_syscall(const char *name) {
*/
static int
-get_struct(int pid, void *offset, void *buf, int len) {
+get_struct(int pid, void *offset, void *buf, int len)
+{
struct ptrace_io_desc iorequest;
-
+
iorequest.piod_op = PIOD_READ_D;
iorequest.piod_offs = offset;
iorequest.piod_addr = buf;
iorequest.piod_len = len;
if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0)
- return -1;
- return 0;
+ return (-1);
+ return (0);
}
-#define MAXSIZE 4096
-#define BLOCKSIZE 1024
+#define MAXSIZE 4096
+#define BLOCKSIZE 1024
/*
* get_string
* Copy a string from the process. Note that it is
@@ -442,18 +444,19 @@ get_struct(int pid, void *offset, void *buf, int len) {
*/
static char *
-get_string(pid_t pid, void *offset, int max) {
+get_string(pid_t pid, void *offset, int max)
+{
char *buf;
struct ptrace_io_desc iorequest;
int totalsize, size;
int diff = 0;
int i;
-
- totalsize = size = max ? (max + 1) : BLOCKSIZE;
+
+ totalsize = size = max ? (max + 1) : BLOCKSIZE;
buf = malloc(totalsize);
if (buf == NULL)
- return NULL;
- for(;;) {
+ return (NULL);
+ for (;;) {
diff = totalsize - size;
iorequest.piod_op = PIOD_READ_D;
iorequest.piod_offs = (char *)offset + diff;
@@ -461,7 +464,7 @@ get_string(pid_t pid, void *offset, int max) {
iorequest.piod_len = size;
if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) {
free(buf);
- return NULL;
+ return (NULL);
}
for (i = 0 ; i < size; i++) {
if (buf[diff + i] == '\0')
@@ -471,10 +474,9 @@ get_string(pid_t pid, void *offset, int max) {
totalsize += BLOCKSIZE;
buf = realloc(buf, totalsize);
size = BLOCKSIZE;
- }
- else {
+ } else {
buf[totalsize] = '\0';
- return buf;
+ return (buf);
}
}
}
@@ -491,562 +493,541 @@ get_string(pid_t pid, void *offset, int max) {
*/
char *
-print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo) {
- char *tmp = NULL;
- int pid = trussinfo->pid;
- switch (sc->type & ARG_MASK) {
- case Hex:
- asprintf(&tmp, "0x%x", (int)args[sc->offset]);
- break;
- case Octal:
- asprintf(&tmp, "0%o", (int)args[sc->offset]);
- break;
- case Int:
- asprintf(&tmp, "%d", (int)args[sc->offset]);
- break;
- case Name:
- {
- /* NULL-terminated string. */
- char *tmp2;
- tmp2 = get_string(pid, (void*)args[sc->offset], 0);
- asprintf(&tmp, "\"%s\"", tmp2);
- free(tmp2);
- }
- break;
- case BinString:
- {
- /* Binary block of data that might have printable characters.
- XXX If type|OUT, assume that the length is the syscall's
- return value. Otherwise, assume that the length of the block
- is in the next syscall argument. */
- int max_string = trussinfo->strsize;
- char tmp2[max_string+1], *tmp3;
- int len;
- int truncated = 0;
-
- if (sc->type & OUT)
- len = retval;
- else
- len = args[sc->offset + 1];
-
- /* Don't print more than max_string characters, to avoid word
- wrap. If we have to truncate put some ... after the string.
- */
- if (len > max_string) {
- len = max_string;
- truncated = 1;
- }
- if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) != -1) {
- tmp3 = malloc(len * 4 + 1);
- while (len) {
- if (strvisx(tmp3, tmp2, len, VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
- break;
- len--;
- truncated = 1;
- };
- asprintf(&tmp, "\"%s\"%s", tmp3, truncated?"...":"");
- free(tmp3);
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case StringArray:
- {
- int num, size, i;
- char *tmp2;
- char *string;
- char *strarray[100]; /* XXX This is ugly. */
-
- if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray,
- sizeof(strarray)) == -1) {
- err(1, "get_struct %p", (void *)args[sc->offset]);
- }
- num = 0;
- size = 0;
-
- /* Find out how large of a buffer we'll need. */
- while (strarray[num] != NULL) {
- string = get_string(pid, (void*)strarray[num], 0);
- size += strlen(string);
- free(string);
- num++;
- }
- size += 4 + (num * 4);
- tmp = (char *)malloc(size);
- tmp2 = tmp;
-
- tmp2 += sprintf(tmp2, " [");
- for (i = 0; i < num; i++) {
- string = get_string(pid, (void*)strarray[i], 0);
- tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i+1 == num) ? ' ' : ',');
- free(string);
- }
- tmp2 += sprintf(tmp2, "]");
- }
- break;
+print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo)
+{
+ char *tmp = NULL;
+ int pid = trussinfo->pid;
+
+ switch (sc->type & ARG_MASK) {
+ case Hex:
+ asprintf(&tmp, "0x%x", (int)args[sc->offset]);
+ break;
+ case Octal:
+ asprintf(&tmp, "0%o", (int)args[sc->offset]);
+ break;
+ case Int:
+ asprintf(&tmp, "%d", (int)args[sc->offset]);
+ break;
+ case Name: {
+ /* NULL-terminated string. */
+ char *tmp2;
+ tmp2 = get_string(pid, (void*)args[sc->offset], 0);
+ asprintf(&tmp, "\"%s\"", tmp2);
+ free(tmp2);
+ break;
+ }
+ case BinString: {
+ /* Binary block of data that might have printable characters.
+ XXX If type|OUT, assume that the length is the syscall's
+ return value. Otherwise, assume that the length of the block
+ is in the next syscall argument. */
+ int max_string = trussinfo->strsize;
+ char tmp2[max_string+1], *tmp3;
+ int len;
+ int truncated = 0;
+
+ if (sc->type & OUT)
+ len = retval;
+ else
+ len = args[sc->offset + 1];
+
+ /* Don't print more than max_string characters, to avoid word
+ wrap. If we have to truncate put some ... after the string.
+ */
+ if (len > max_string) {
+ len = max_string;
+ truncated = 1;
+ }
+ if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) != -1) {
+ tmp3 = malloc(len * 4 + 1);
+ while (len) {
+ if (strvisx(tmp3, tmp2, len, VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
+ break;
+ len--;
+ truncated = 1;
+ };
+ asprintf(&tmp, "\"%s\"%s", tmp3, truncated?"...":"");
+ free(tmp3);
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ break;
+ }
+ case StringArray: {
+ int num, size, i;
+ char *tmp2;
+ char *string;
+ char *strarray[100]; /* XXX This is ugly. */
+
+ if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray,
+ sizeof(strarray)) == -1) {
+ err(1, "get_struct %p", (void *)args[sc->offset]);
+ }
+ num = 0;
+ size = 0;
+
+ /* Find out how large of a buffer we'll need. */
+ while (strarray[num] != NULL) {
+ string = get_string(pid, (void*)strarray[num], 0);
+ size += strlen(string);
+ free(string);
+ num++;
+ }
+ size += 4 + (num * 4);
+ tmp = (char *)malloc(size);
+ tmp2 = tmp;
+
+ tmp2 += sprintf(tmp2, " [");
+ for (i = 0; i < num; i++) {
+ string = get_string(pid, (void*)strarray[i], 0);
+ tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i+1 == num) ? ' ' : ',');
+ free(string);
+ }
+ tmp2 += sprintf(tmp2, "]");
+ break;
+ }
#ifdef __LP64__
- case Quad:
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- break;
+ case Quad:
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
#else
- case Quad:
- {
- unsigned long long ll;
- ll = *(unsigned long long *)(args + sc->offset);
- asprintf(&tmp, "0x%llx", ll);
- break;
- }
+ case Quad: {
+ unsigned long long ll;
+ ll = *(unsigned long long *)(args + sc->offset);
+ asprintf(&tmp, "0x%llx", ll);
+ break;
+ }
#endif
- case Ptr:
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- break;
- case Readlinkres:
- {
- char *tmp2;
- if (retval == -1) {
- tmp = strdup("");
- break;
- }
- tmp2 = get_string(pid, (void*)args[sc->offset], retval);
- asprintf(&tmp, "\"%s\"", tmp2);
- free(tmp2);
- }
- break;
- case Ioctl:
- {
- const char *temp = ioctlname(args[sc->offset]);
- if (temp)
- tmp = strdup(temp);
- else
- {
- unsigned long arg = args[sc->offset];
- asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu}", arg,
- arg&IOC_OUT?"R":"", arg&IOC_IN?"W":"",
- IOCGROUP(arg), isprint(IOCGROUP(arg))?(char)IOCGROUP(arg):'?',
- arg & 0xFF, IOCPARM_LEN(arg));
- }
- }
- break;
- case Umtx:
- {
- struct umtx umtx;
- if (get_struct(pid, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1)
- asprintf(&tmp, "{0x%lx}", (long)umtx.u_owner);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Timespec:
- {
- struct timespec ts;
- if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1)
- asprintf(&tmp, "{%ld.%09ld}", (long)ts.tv_sec, ts.tv_nsec);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Timeval:
- {
- struct timeval tv;
- if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1)
- asprintf(&tmp, "{%ld.%06ld}", (long)tv.tv_sec, tv.tv_usec);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Timeval2:
- {
- struct timeval tv[2];
- if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1)
- asprintf(&tmp, "{%ld.%06ld, %ld.%06ld}",
- (long)tv[0].tv_sec, tv[0].tv_usec,
- (long)tv[1].tv_sec, tv[1].tv_usec);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Itimerval:
- {
- struct itimerval itv;
- if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1)
- asprintf(&tmp, "{%ld.%06ld, %ld.%06ld}",
- (long)itv.it_interval.tv_sec,
- itv.it_interval.tv_usec,
- (long)itv.it_value.tv_sec,
- itv.it_value.tv_usec);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Pollfd:
- {
- /*
- * XXX: A Pollfd argument expects the /next/ syscall argument to be
- * the number of fds in the array. This matches the poll syscall.
- */
- struct pollfd *pfd;
- int numfds = args[sc->offset+1];
- int bytes = sizeof(struct pollfd) * numfds;
- int i, tmpsize, u, used;
- const int per_fd = 100;
-
- if ((pfd = malloc(bytes)) == NULL)
- err(1, "Cannot malloc %d bytes for pollfd array", bytes);
- if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) {
-
- used = 0;
- tmpsize = 1 + per_fd * numfds + 2;
- if ((tmp = malloc(tmpsize)) == NULL)
- err(1, "Cannot alloc %d bytes for poll output", tmpsize);
-
- tmp[used++] = '{';
- for (i = 0; i < numfds; i++) {
-
- u = snprintf(tmp + used, per_fd,
- "%s%d/%s",
- i > 0 ? " " : "",
- pfd[i].fd,
- xlookup_bits(poll_flags, pfd[i].events) );
- if (u > 0)
- used += u < per_fd ? u : per_fd;
+ case Ptr:
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ case Readlinkres: {
+ char *tmp2;
+ if (retval == -1) {
+ tmp = strdup("");
+ break;
+ }
+ tmp2 = get_string(pid, (void*)args[sc->offset], retval);
+ asprintf(&tmp, "\"%s\"", tmp2);
+ free(tmp2);
+ break;
+ }
+ case Ioctl: {
+ const char *temp = ioctlname(args[sc->offset]);
+ if (temp) {
+ tmp = strdup(temp);
+ } else {
+ unsigned long arg = args[sc->offset];
+ asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", arg,
+ arg&IOC_OUT?"R":"", arg&IOC_IN?"W":"",
+ IOCGROUP(arg), isprint(IOCGROUP(arg))?(char)IOCGROUP(arg):'?',
+ arg & 0xFF, IOCPARM_LEN(arg));
+ }
+ break;
}
- tmp[used++] = '}';
- tmp[used++] = '\0';
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- free(pfd);
- }
- break;
- case Fd_set:
- {
- /*
- * XXX: A Fd_set argument expects the /first/ syscall argument to be
- * the number of fds in the array. This matches the select syscall.
- */
- fd_set *fds;
- int numfds = args[0];
- int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
- int i, tmpsize, u, used;
- const int per_fd = 20;
-
- if ((fds = malloc(bytes)) == NULL)
- err(1, "Cannot malloc %d bytes for fd_set array", bytes);
- if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) {
- used = 0;
- tmpsize = 1 + numfds * per_fd + 2;
- if ((tmp = malloc(tmpsize)) == NULL)
- err(1, "Cannot alloc %d bytes for fd_set output", tmpsize);
-
- tmp[used++] = '{';
- for (i = 0; i < numfds; i++) {
- if (FD_ISSET(i, fds)) {
- u = snprintf(tmp + used, per_fd, "%d ", i);
- if (u > 0)
- used += u < per_fd ? u : per_fd;
- }
+ case Umtx: {
+ struct umtx umtx;
+ if (get_struct(pid, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1)
+ asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner);
+ else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
}
- if (tmp[used-1] == ' ')
- used--;
- tmp[used++] = '}';
- tmp[used++] = '\0';
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- free(fds);
- }
- break;
- case Signal:
- {
- long sig;
-
- sig = args[sc->offset];
- tmp = strsig(sig);
- if (tmp == NULL)
- asprintf(&tmp, "%ld", sig);
- }
- break;
- case Sigset:
- {
- long sig;
- sigset_t ss;
- int i, used;
-
- sig = args[sc->offset];
- if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
- sizeof(ss)) == -1)
- {
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- break;
- }
- tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
- used = 0;
- for (i = 1; i < sys_nsig; i++)
- {
- if (sigismember(&ss, i))
- {
- used += sprintf(tmp + used, "%s|", strsig(i));
- }
- }
- if(used)
- tmp[used-1] = 0;
- else
- strcpy(tmp, "0x0");
- }
- break;
- case Sigprocmask:
- {
- switch (args[sc->offset]) {
+ case Timespec: {
+ struct timespec ts;
+ if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1)
+ asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, ts.tv_nsec);
+ else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ case Timeval: {
+ struct timeval tv;
+ if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1)
+ asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, tv.tv_usec);
+ else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ case Timeval2: {
+ struct timeval tv[2];
+ if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1)
+ asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
+ (long)tv[0].tv_sec, tv[0].tv_usec,
+ (long)tv[1].tv_sec, tv[1].tv_usec);
+ else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ case Itimerval: {
+ struct itimerval itv;
+ if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1)
+ asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
+ (long)itv.it_interval.tv_sec,
+ itv.it_interval.tv_usec,
+ (long)itv.it_value.tv_sec,
+ itv.it_value.tv_usec);
+ else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ case Pollfd: {
+ /*
+ * XXX: A Pollfd argument expects the /next/ syscall argument to be
+ * the number of fds in the array. This matches the poll syscall.
+ */
+ struct pollfd *pfd;
+ int numfds = args[sc->offset+1];
+ int bytes = sizeof(struct pollfd) * numfds;
+ int i, tmpsize, u, used;
+ const int per_fd = 100;
+
+ if ((pfd = malloc(bytes)) == NULL)
+ err(1, "Cannot malloc %d bytes for pollfd array", bytes);
+ if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) {
+
+ used = 0;
+ tmpsize = 1 + per_fd * numfds + 2;
+ if ((tmp = malloc(tmpsize)) == NULL)
+ err(1, "Cannot alloc %d bytes for poll output", tmpsize);
+
+ tmp[used++] = '{';
+ for (i = 0; i < numfds; i++) {
+
+ u = snprintf(tmp + used, per_fd,
+ "%s%d/%s",
+ i > 0 ? " " : "",
+ pfd[i].fd,
+ xlookup_bits(poll_flags, pfd[i].events) );
+ if (u > 0)
+ used += u < per_fd ? u : per_fd;
+ }
+ tmp[used++] = '}';
+ tmp[used++] = '\0';
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ free(pfd);
+ break;
+ }
+ case Fd_set: {
+ /*
+ * XXX: A Fd_set argument expects the /first/ syscall argument to be
+ * the number of fds in the array. This matches the select syscall.
+ */
+ fd_set *fds;
+ int numfds = args[0];
+ int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
+ int i, tmpsize, u, used;
+ const int per_fd = 20;
+
+ if ((fds = malloc(bytes)) == NULL)
+ err(1, "Cannot malloc %d bytes for fd_set array", bytes);
+ if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) {
+ used = 0;
+ tmpsize = 1 + numfds * per_fd + 2;
+ if ((tmp = malloc(tmpsize)) == NULL)
+ err(1, "Cannot alloc %d bytes for fd_set output", tmpsize);
+
+ tmp[used++] = '{';
+ for (i = 0; i < numfds; i++) {
+ if (FD_ISSET(i, fds)) {
+ u = snprintf(tmp + used, per_fd, "%d ", i);
+ if (u > 0)
+ used += u < per_fd ? u : per_fd;
+ }
+ }
+ if (tmp[used-1] == ' ')
+ used--;
+ tmp[used++] = '}';
+ tmp[used++] = '\0';
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ free(fds);
+ break;
+ }
+ case Signal: {
+ long sig;
+
+ sig = args[sc->offset];
+ tmp = strsig(sig);
+ if (tmp == NULL)
+ asprintf(&tmp, "%ld", sig);
+ break;
+ }
+ case Sigset: {
+ long sig;
+ sigset_t ss;
+ int i, used;
+
+ sig = args[sc->offset];
+ if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss)) == -1) {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
+ used = 0;
+ for (i = 1; i < sys_nsig; i++) {
+ if (sigismember(&ss, i)) {
+ used += sprintf(tmp + used, "%s|", strsig(i));
+ }
+ }
+ if (used)
+ tmp[used-1] = 0;
+ else
+ strcpy(tmp, "0x0");
+ break;
+ }
+ case Sigprocmask: {
+ switch (args[sc->offset]) {
#define S(a) case a: tmp = strdup(#a); break;
- S(SIG_BLOCK);
- S(SIG_UNBLOCK);
- S(SIG_SETMASK);
+ S(SIG_BLOCK);
+ S(SIG_UNBLOCK);
+ S(SIG_SETMASK);
#undef S
+ }
+ if (tmp == NULL)
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ case Fcntlflag: {
+ /* XXX output depends on the value of the previous argument */
+ switch (args[sc->offset-1]) {
+ case F_SETFD:
+ tmp = strdup(xlookup_bits(fcntlfd_arg, args[sc->offset]));
+ break;
+ case F_SETFL:
+ tmp = strdup(xlookup_bits(fcntlfl_arg, args[sc->offset]));
+ break;
+ case F_GETFD:
+ case F_GETFL:
+ case F_GETOWN:
+ tmp = strdup("");
+ break;
+ default:
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ break;
+ }
+ break;
+ }
+ case Open:
+ tmp = strdup(xlookup_bits(open_flags, args[sc->offset]));
+ break;
+ case Fcntl:
+ tmp = strdup(xlookup(fcntl_arg, args[sc->offset]));
+ break;
+ case Mprot:
+ tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset]));
+ break;
+ case Mmapflags:
+ tmp = strdup(xlookup_bits(mmap_flags, args[sc->offset]));
+ break;
+ case Whence:
+ tmp = strdup(xlookup(whence_arg, args[sc->offset]));
+ break;
+ case Sockdomain:
+ tmp = strdup(xlookup(sockdomain_arg, args[sc->offset]));
+ break;
+ case Socktype:
+ tmp = strdup(xlookup(socktype_arg, args[sc->offset]));
+ break;
+ case Shutdown:
+ tmp = strdup(xlookup(shutdown_arg, args[sc->offset]));
+ break;
+ case Resource:
+ tmp = strdup(xlookup(resource_arg, args[sc->offset]));
+ break;
+ case Pathconf:
+ tmp = strdup(xlookup(pathconf_arg, args[sc->offset]));
+ break;
+ case Sockaddr: {
+ struct sockaddr_storage ss;
+ char addr[64];
+ struct sockaddr_in *lsin;
+ struct sockaddr_in6 *lsin6;
+ struct sockaddr_un *sun;
+ struct sockaddr *sa;
+ char *p;
+ u_char *q;
+ int i;
+
+ if (args[sc->offset] == 0) {
+ asprintf(&tmp, "NULL");
+ break;
+ }
+
+ /* yuck: get ss_len */
+ if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
+ sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
+ err(1, "get_struct %p", (void *)args[sc->offset]);
+ /*
+ * If ss_len is 0, then try to guess from the sockaddr type.
+ * AF_UNIX may be initialized incorrectly, so always frob
+ * it by using the "right" size.
+ */
+ if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) {
+ switch (ss.ss_family) {
+ case AF_INET:
+ ss.ss_len = sizeof(*lsin);
+ break;
+ case AF_UNIX:
+ ss.ss_len = sizeof(*sun);
+ break;
+ default:
+ /* hurrrr */
+ break;
+ }
+ }
+ if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len)
+ == -1) {
+ err(2, "get_struct %p", (void *)args[sc->offset]);
+ }
+
+ switch (ss.ss_family) {
+ case AF_INET:
+ lsin = (struct sockaddr_in *)&ss;
+ inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr);
+ asprintf(&tmp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port));
+ break;
+ case AF_INET6:
+ lsin6 = (struct sockaddr_in6 *)&ss;
+ inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof addr);
+ asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port));
+ break;
+ case AF_UNIX:
+ sun = (struct sockaddr_un *)&ss;
+ asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
+ break;
+ default:
+ sa = (struct sockaddr *)&ss;
+ asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data = {%n%*s } }",
+ (int)sa->sa_len, (int)sa->sa_family, &i,
+ 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), "");
+ if (tmp != NULL) {
+ p = tmp + i;
+ for (q = (u_char *)&sa->sa_data; q < (u_char *)sa + sa->sa_len; q++)
+ p += sprintf(p, " %#02x,", *q);
+ }
+ }
+ break;
}
- if (tmp == NULL)
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
-
- case Fcntlflag:
- {
- /* XXX output depends on the value of the previous argument */
- switch (args[sc->offset-1]) {
- case F_SETFD:
- tmp = strdup(xlookup_bits(fcntlfd_arg, args[sc->offset]));
- break;
- case F_SETFL:
- tmp = strdup(xlookup_bits(fcntlfl_arg, args[sc->offset]));
- break;
- case F_GETFD:
- case F_GETFL:
- case F_GETOWN:
- tmp = strdup("");
- break;
- default:
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- break;
- }
- }
- break;
- case Open:
- tmp = strdup(xlookup_bits(open_flags, args[sc->offset]));
- break;
- case Fcntl:
- tmp = strdup(xlookup(fcntl_arg, args[sc->offset]));
- break;
- case Mprot:
- tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset]));
- break;
- case Mmapflags:
- tmp = strdup(xlookup_bits(mmap_flags, args[sc->offset]));
- break;
- case Whence:
- tmp = strdup(xlookup(whence_arg, args[sc->offset]));
- break;
- case Sockdomain:
- tmp = strdup(xlookup(sockdomain_arg, args[sc->offset]));
- break;
- case Socktype:
- tmp = strdup(xlookup(socktype_arg, args[sc->offset]));
- break;
- case Shutdown:
- tmp = strdup(xlookup(shutdown_arg, args[sc->offset]));
- break;
- case Resource:
- tmp = strdup(xlookup(resource_arg, args[sc->offset]));
- break;
- case Pathconf:
- tmp = strdup(xlookup(pathconf_arg, args[sc->offset]));
- break;
- case Sockaddr:
- {
- struct sockaddr_storage ss;
- char addr[64];
- struct sockaddr_in *lsin;
- struct sockaddr_in6 *lsin6;
- struct sockaddr_un *sun;
- struct sockaddr *sa;
- char *p;
- u_char *q;
- int i;
-
- if (args[sc->offset] == 0) {
- asprintf(&tmp, "NULL");
- break;
- }
-
- /* yuck: get ss_len */
- if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
- sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
- err(1, "get_struct %p", (void *)args[sc->offset]);
- /*
- * If ss_len is 0, then try to guess from the sockaddr type.
- * AF_UNIX may be initialized incorrectly, so always frob
- * it by using the "right" size.
- */
- if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) {
- switch (ss.ss_family) {
- case AF_INET:
- ss.ss_len = sizeof(*lsin);
- break;
- case AF_UNIX:
- ss.ss_len = sizeof(*sun);
- break;
- default:
- /* hurrrr */
- break;
- }
- }
- if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len)
- == -1) {
- err(2, "get_struct %p", (void *)args[sc->offset]);
- }
-
- switch (ss.ss_family) {
- case AF_INET:
- lsin = (struct sockaddr_in *)&ss;
- inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr);
- asprintf(&tmp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port));
- break;
- case AF_INET6:
- lsin6 = (struct sockaddr_in6 *)&ss;
- inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof addr);
- asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port));
- break;
- case AF_UNIX:
- sun = (struct sockaddr_un *)&ss;
- asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
- break;
- default:
- sa = (struct sockaddr *)&ss;
- asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data = {%n%*s } }",
- (int)sa->sa_len, (int)sa->sa_family, &i,
- 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), "");
- if (tmp != NULL) {
- p = tmp + i;
- for (q = (u_char *)&sa->sa_data; q < (u_char *)sa + sa->sa_len; q++)
- p += sprintf(p, " %#02x,", *q);
+ case Sigaction: {
+ struct sigaction sa;
+ char *hand;
+ const char *h;
+
+ if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) {
+
+ asprintf(&hand, "%p", sa.sa_handler);
+ if (sa.sa_handler == SIG_DFL)
+ h = "SIG_DFL";
+ else if (sa.sa_handler == SIG_IGN)
+ h = "SIG_IGN";
+ else
+ h = hand;
+
+ asprintf(&tmp, "{ %s %s ss_t }",
+ h,
+ xlookup_bits(sigaction_flags, sa.sa_flags));
+ free(hand);
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ break;
}
- }
- }
- break;
- case Sigaction:
- {
- struct sigaction sa;
- char *hand;
- const char *h;
-
- if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) {
-
- asprintf(&hand, "%p", sa.sa_handler);
- if (sa.sa_handler == SIG_DFL)
- h = "SIG_DFL";
- else if (sa.sa_handler == SIG_IGN)
- h = "SIG_IGN";
- else
- h = hand;
-
- asprintf(&tmp, "{ %s %s ss_t }",
- h,
- xlookup_bits(sigaction_flags, sa.sa_flags));
- free(hand);
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
-
- }
- break;
- case Kevent:
- {
- /*
- * XXX XXX: the size of the array is determined by either the
- * next syscall argument, or by the syscall returnvalue,
- * depending on which argument number we are. This matches the
- * kevent syscall, but luckily that's the only syscall that uses
- * them.
- */
- struct kevent *ke;
- int numevents = -1;
- int bytes = 0;
- int i, tmpsize, u, used;
- const int per_ke = 100;
-
- if (sc->offset == 1)
- numevents = args[sc->offset+1];
- else if (sc->offset == 3 && retval != -1)
- numevents = retval;
-
- if (numevents >= 0)
- bytes = sizeof(struct kevent) * numevents;
- if ((ke = malloc(bytes)) == NULL)
- err(1, "Cannot malloc %d bytes for kevent array", bytes);
- if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], ke, bytes) != -1) {
- used = 0;
- tmpsize = 1 + per_ke * numevents + 2;
- if ((tmp = malloc(tmpsize)) == NULL)
- err(1, "Cannot alloc %d bytes for kevent output", tmpsize);
-
- tmp[used++] = '{';
- for (i = 0; i < numevents; i++) {
- u = snprintf(tmp + used, per_ke,
- "%s%p,%s,%s,%d,%p,%p",
- i > 0 ? " " : "",
- (void *)ke[i].ident,
- xlookup(kevent_filters, ke[i].filter),
- xlookup_bits(kevent_flags, ke[i].flags),
- ke[i].fflags,
- (void *)ke[i].data,
- (void *)ke[i].udata);
- if (u > 0)
- used += u < per_ke ? u : per_ke;
+ case Kevent: {
+ /*
+ * XXX XXX: the size of the array is determined by either the
+ * next syscall argument, or by the syscall returnvalue,
+ * depending on which argument number we are. This matches the
+ * kevent syscall, but luckily that's the only syscall that uses
+ * them.
+ */
+ struct kevent *ke;
+ int numevents = -1;
+ int bytes = 0;
+ int i, tmpsize, u, used;
+ const int per_ke = 100;
+
+ if (sc->offset == 1)
+ numevents = args[sc->offset+1];
+ else if (sc->offset == 3 && retval != -1)
+ numevents = retval;
+
+ if (numevents >= 0)
+ bytes = sizeof(struct kevent) * numevents;
+ if ((ke = malloc(bytes)) == NULL)
+ err(1, "Cannot malloc %d bytes for kevent array", bytes);
+ if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], ke, bytes) != -1) {
+ used = 0;
+ tmpsize = 1 + per_ke * numevents + 2;
+ if ((tmp = malloc(tmpsize)) == NULL)
+ err(1, "Cannot alloc %d bytes for kevent output", tmpsize);
+
+ tmp[used++] = '{';
+ for (i = 0; i < numevents; i++) {
+ u = snprintf(tmp + used, per_ke,
+ "%s%p,%s,%s,%d,%p,%p",
+ i > 0 ? " " : "",
+ (void *)ke[i].ident,
+ xlookup(kevent_filters, ke[i].filter),
+ xlookup_bits(kevent_flags, ke[i].flags),
+ ke[i].fflags,
+ (void *)ke[i].data,
+ (void *)ke[i].udata);
+ if (u > 0)
+ used += u < per_ke ? u : per_ke;
+ }
+ tmp[used++] = '}';
+ tmp[used++] = '\0';
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ free(ke);
+ break;
+ }
+ case Stat: {
+ struct stat st;
+ if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) != -1) {
+ char mode[12];
+ strmode(st.st_mode, mode);
+ asprintf(&tmp, "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }",
+ mode,
+ (intmax_t)st.st_ino,(intmax_t)st.st_size,(long)st.st_blksize);
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ break;
}
- tmp[used++] = '}';
- tmp[used++] = '\0';
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- free(ke);
- }
- break;
- case Stat:
- {
- struct stat st;
- if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) != -1) {
- char mode[12];
- strmode(st.st_mode, mode);
- asprintf(&tmp, "{mode=%s,inode=%jd,size=%jd,blksize=%ld}",
- mode,
- (intmax_t)st.st_ino,(intmax_t)st.st_size,(long)st.st_blksize);
- } else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Rusage:
- {
- struct rusage ru;
- if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1)
- asprintf(&tmp, "{u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld}",
- (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
- (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
- ru.ru_inblock, ru.ru_oublock);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- case Rlimit:
- {
- struct rlimit rl;
- if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) != -1)
- asprintf(&tmp, "{cur=%ju,max=%ju}",
- rl.rlim_cur, rl.rlim_max);
- else
- asprintf(&tmp, "0x%lx", args[sc->offset]);
- }
- break;
- default:
- errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
- }
- return tmp;
+ case Rusage: {
+ struct rusage ru;
+ if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) {
+ asprintf(&tmp, "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }",
+ (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
+ (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
+ ru.ru_inblock, ru.ru_oublock);
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ break;
+ }
+ case Rlimit: {
+ struct rlimit rl;
+ if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) != -1) {
+ asprintf(&tmp, "{ cur=%ju,max=%ju }",
+ rl.rlim_cur, rl.rlim_max);
+ } else {
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ }
+ break;
+ }
+ default:
+ errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
+ }
+ return (tmp);
}
-
/*
* print_syscall
* Print (to outfile) the system call and its arguments. Note that
@@ -1055,53 +1036,55 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus
*/
void
-print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args) {
- int i;
- int len = 0;
- struct timespec timediff;
-
- if (trussinfo->flags & FOLLOWFORKS)
- len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid);
-
- if (name != NULL && (!strcmp(name, "execve") || !strcmp(name, "exit"))) {
- clock_gettime(CLOCK_REALTIME, &trussinfo->after);
- }
-
- if (trussinfo->flags & ABSOLUTETIMESTAMPS) {
- timespecsubt(&trussinfo->after, &trussinfo->start_time, &timediff);
- len += fprintf(trussinfo->outfile, "%ld.%09ld ",
- (long)timediff.tv_sec, timediff.tv_nsec);
- }
-
- if (trussinfo->flags & RELATIVETIMESTAMPS) {
- timespecsubt(&trussinfo->after, &trussinfo->before, &timediff);
- len += fprintf(trussinfo->outfile, "%ld.%09ld ",
- (long)timediff.tv_sec, timediff.tv_nsec);
- }
-
- len += fprintf(trussinfo->outfile, "%s(", name);
-
- for (i = 0; i < nargs; i++) {
- if (s_args[i])
- len += fprintf(trussinfo->outfile, "%s", s_args[i]);
- else
- len += fprintf(trussinfo->outfile, "<missing argument>");
- len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? "," : "");
- }
- len += fprintf(trussinfo->outfile, ")");
- for (i = 0; i < 6 - (len / 8); i++)
- fprintf(trussinfo->outfile, "\t");
+print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args)
+{
+ int i;
+ int len = 0;
+ struct timespec timediff;
+
+ if (trussinfo->flags & FOLLOWFORKS)
+ len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid);
+
+ if (name != NULL && (!strcmp(name, "execve") || !strcmp(name, "exit"))) {
+ clock_gettime(CLOCK_REALTIME, &trussinfo->after);
+ }
+
+ if (trussinfo->flags & ABSOLUTETIMESTAMPS) {
+ timespecsubt(&trussinfo->after, &trussinfo->start_time, &timediff);
+ len += fprintf(trussinfo->outfile, "%ld.%09ld ",
+ (long)timediff.tv_sec, timediff.tv_nsec);
+ }
+
+ if (trussinfo->flags & RELATIVETIMESTAMPS) {
+ timespecsubt(&trussinfo->after, &trussinfo->before, &timediff);
+ len += fprintf(trussinfo->outfile, "%ld.%09ld ",
+ (long)timediff.tv_sec, timediff.tv_nsec);
+ }
+
+ len += fprintf(trussinfo->outfile, "%s(", name);
+
+ for (i = 0; i < nargs; i++) {
+ if (s_args[i])
+ len += fprintf(trussinfo->outfile, "%s", s_args[i]);
+ else
+ len += fprintf(trussinfo->outfile, "<missing argument>");
+ len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? "," : "");
+ }
+ len += fprintf(trussinfo->outfile, ")");
+ for (i = 0; i < 6 - (len / 8); i++)
+ fprintf(trussinfo->outfile, "\t");
}
void
print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs,
char **s_args, int errorp, long retval)
{
- print_syscall(trussinfo, name, nargs, s_args);
- fflush(trussinfo->outfile);
- if (errorp) {
- fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, strerror(retval));
- } else {
- fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval);
- }
+
+ print_syscall(trussinfo, name, nargs, s_args);
+ fflush(trussinfo->outfile);
+ if (errorp) {
+ fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, strerror(retval));
+ } else {
+ fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval);
+ }
}
OpenPOWER on IntegriCloud