aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2003-11-13 09:04:24 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2003-11-13 09:04:24 +0000
commit4e92419dcd0d7cb8db7f588e3efc16275592b920 (patch)
treeb1005aa978fff4c1dad930981a7efec08a65a862 /usr.bin
parentb70d5d25f237389f1e137f3dc8cc51037a476985 (diff)
downloadsrc-4e92419dcd0d7cb8db7f588e3efc16275592b920.tar.gz
src-4e92419dcd0d7cb8db7f588e3efc16275592b920.zip
Do not ignore any possible errors that fseeko() may have. The fact
is that fseeko() fails in very predictable and frequent ways on ia64. This is because the offset is actually an address in the process' address space, which on ia64 can be larger than long (for lseek) or off_t (for fseeko). The crux is the signedness. The register stack and memory stack are in region 4 on ia64. This means that the sign bit is 1. The large positive virtual address is wrongly interpreted as a negative file offset. There's no quick fix. Even if you get around the API by using a SEEK_SET up to LONG_MAX and follow it up with a SEEK_CUR for the remainder, the kernel simply cannot deal with it. and the second seek will just fail. Therefore, this change does not actually fix the root cause. It just makes sure we're not spitting out all kinds of garbage or that the get_struct() function in particular does not cause truss(1) to exit. This, I might add, invariably happened way too soon for truss(1) to be of any use on ia64...
Notes
Notes: svn path=/head/; revision=122606
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/truss/syscalls.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 7d021835614d..c9e5e750fb29 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -171,12 +171,14 @@ get_struct(int procfd, void *offset, void *buf, int len) {
err(1, "dup");
if ((p = fdopen(fd, "r")) == NULL)
err(1, "fdopen");
- fseeko(p, (uintptr_t)offset, SEEK_SET);
- for (pos = (char *)buf; len--; pos++) {
- if ((c = fgetc(p)) == EOF)
- return -1;
- *pos = c;
- }
+ if (fseeko(p, (uintptr_t)offset, SEEK_SET) == 0) {
+ for (pos = (char *)buf; len--; pos++) {
+ if ((c = fgetc(p)) == EOF)
+ return (-1);
+ *pos = c;
+ }
+ } else
+ bzero(buf, len);
fclose(p);
return 0;
}
@@ -201,27 +203,27 @@ get_string(int procfd, void *offset, int max) {
buf = malloc( size = (max ? max : 64 ) );
len = 0;
buf[0] = 0;
- fseeko(p, (uintptr_t)offset, SEEK_SET);
- while ((c = fgetc(p)) != EOF) {
- buf[len++] = c;
- if (c == 0 || len == max) {
- buf[len] = 0;
- break;
- }
- if (len == size) {
- char *tmp;
- tmp = realloc(buf, size+64);
- if (tmp == NULL) {
+ if (fseeko(p, (uintptr_t)offset, SEEK_SET) == 0) {
+ while ((c = fgetc(p)) != EOF) {
+ buf[len++] = c;
+ if (c == 0 || len == max) {
buf[len] = 0;
- fclose(p);
- return buf;
+ break;
+ }
+ if (len == size) {
+ char *tmp;
+ tmp = realloc(buf, size+64);
+ if (tmp == NULL) {
+ buf[len] = 0;
+ break;
+ }
+ size += 64;
+ buf = tmp;
}
- size += 64;
- buf = tmp;
}
}
fclose(p);
- return buf;
+ return (buf);
}