[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

od for large files

From: Gareth Williams
Subject: od for large files
Date: Wed, 11 Jul 2001 01:29:38 +0100

I had to modify od to work with large files (>2.1GB) on SGI/IRIX 6.4,
using egcs-2.91.66 (egcs-1.1.2 release).

The problem is basically that 'long' is 4-bytes. You need 'long long'
for an 8-byte int. I do not think this is specific to SGI - it is
also true for egcs under Intel/Linux (though accademic since my kernel
does not support files >2.1 GB anyway) so it may be of more general
interest for people whose OSes do support big files.

Of course I was only using GNU od because IRIX od does not work
with big files either. But I could fix the GNU program :-) :-)

Below is the diff of my simple hack, and a copy of the note I have
added into the textutils/src directory where we use it. Of course
you have my permission to use the code and/or analysis how you like.

Do let me know if this is any use.


> cat od.diff
< static const char *(*format_address) PARAMS ((long unsigned int));
> static const char *(*format_address) PARAMS ((off_t));
< format_address_none (long unsigned int address)
> format_address_none (off_t address)
< format_address_std (long unsigned int address)
> format_address_std (off_t address)
< format_address_label (long unsigned int address)
> format_address_label (off_t address)
< write_block (long unsigned int current_offset, long unsigned int
> write_block (off_t current_offset, long unsigned int n_bytes,
<   output_address_fmt_string = "%07o";
> /*output_address_fmt_string = "%07o"; */
>   output_address_fmt_string = "%07llo";
<             output_address_fmt_string = "%07d";
>          /* output_address_fmt_string = "%07d"; */
>             output_address_fmt_string = "%07lld";
<             output_address_fmt_string = "%07o";
>          /* output_address_fmt_string = "%07o"; */
>             output_address_fmt_string = "%07llo";
<             output_address_fmt_string = "%06x";
>          /* output_address_fmt_string = "%06x"; */
>             output_address_fmt_string = "%06llx";
<             output_address_fmt_string = "(%07o)";
>          /* output_address_fmt_string = "(%07o)"; */
>             output_address_fmt_string = "(%07llo)"


od has been modified to allow it to read large files
on SGI, with the egcs-2.91.66 compiler.

Original code is in od_gnu.c
Modified version in od_dgw.c
Differences in      od.diff

The original code could in fact read files > 2.1GB but it
displayed the addresses wrong. This was because current_offset
is of type off_t (8-byte) but was passed to the formatting
procedures as unsigned long (*4* byte on this system).

The type passed to the format_address functions has been
changed to off_t, and the printf format strings modified
for long long integers, eg %lld instead of %d.

This code seems to assume that if there is an 8-byte
integer it is unsigned long. Here it is unsigned long long.
A better fix would pick this up at the configure stage
and use typedefs for all the integer types.

Gareth Williams
DGW Software Consultants LTD


Gareth Williams <address@hidden>

** DGW Software Consultants LTD ******************
*  Montrose, Ledbury Road, Ross-on-Wye, HR9 7BE  *
*  Tel/Fax 01989 563704                          *

reply via email to

[Prev in Thread] Current Thread [Next in Thread]