Fix wr_ranlib() for big-endian machines.

With this change, I built and ran ack on a big-endian PowerPC Linux
machine.  I used gcc 4.9.4 to build ack, and I only built the linuxppc
back end.

Before this change, wr_ranlib() corrupted a value by changing it from
0x66 to 0x66000066.  This value was too big, so led made a fatal
error, "bad ranlib string offset".
This commit is contained in:
George Koehler 2018-03-08 11:49:40 -05:00
parent b1badf1851
commit 0720671f7a

View file

@ -10,16 +10,27 @@ wr_ranlib(fd, ran, cnt1)
struct ranlib *ran; struct ranlib *ran;
long cnt1; long cnt1;
{ {
{ struct ranlib *r;
register long cnt = cnt1; long cnt, val;
register struct ranlib *r = ran; char *c;
register char *c = (char *) r;
while (cnt--) { /*
put4(r->ran_off,c); c += 4; * We overwrite the structs in r with the bytes in c, so we
put4(r->ran_pos,c); c += 4; * don't need to allocate another buffer.
r++; *
} * put4(r->ran_off, c) can fail if r->ran_off and c overlap in
* memory, if this is a big-endian machine. It tries to swap
* the bytes from big to little endian, but overwrites some
* bytes before reading them. To prevent this, we must copy
* each value before we overwrite it.
*/
r = ran;
c = (char *)r;
cnt = cnt1;
while (cnt--) {
val = r->ran_off; put4(val, c); c += 4;
val = r->ran_pos; put4(val, c); c += 4;
r++;
} }
wr_bytes(fd, (char *) ran, cnt1 * SZ_RAN); wr_bytes(fd, (char *) ran, cnt1 * SZ_RAN);
} }