2015-09-29
od指令的简单实现
od以八进制或其他进制导出显示文件内容。
1.第一列显示的是文件的位移
2.默认每行显示16个字节
3.当显示多个文件时,会将多个文件合并显示
4.当连续的多行相同时,相同的第二行会显示为星号(*),之后的相同行将不会显示,直到遇到新的不同行
int
do_od( int fd, unsigned long *ulOffset, unsigned char *cpBuf, int iLen )
{
int iRdNum = 0; /* the number of bytes been read */
static int iCnt = 0; /* accumulate the number of bytes have bee read before printing */
static int iIgnoreFlg = 0; /* record the duplicate times */
static unsigned char caStd[ BUFLEN ] = { 0 }; /* previous line, at first it's all zeros */
while( ( iRdNum = read( fd, cpBuf + iCnt, iLen - iCnt ) ) > 0 )
{
iCnt += iRdNum;
if( iCnt == iLen )
{
if( memcmp( cpBuf, caStd, BUFLEN ) == 0 )
{
if( !iIgnoreFlg )
{
/*
** when the first line at first is all zeros, will fall
** into this flow
*/
printf( "%07lo ", *ulOffset );
print_oct( cpBuf, iLen );
putchar( '\n' );
iIgnoreFlg = 1;
}
else if( iIgnoreFlg == 1 )
{
/*
** the previous line is the same, the second line
** just print a '*'
** if the third line and the follows are the same too,
** just record the offset
*/
printf( "*\n" );
++iIgnoreFlg;
}
}
else
{
/*
** read a full line, and print
*/
printf( "%07lo ", *ulOffset );
print_oct( cpBuf, iLen );
putchar( '\n' );
memcpy( caStd, cpBuf, sizeof( caStd ) );
iIgnoreFlg = 1;
}
*ulOffset += iLen; /* record the offset */
iCnt = 0;
}
}
if( iRdNum < 0 )
{
fprintf( stderr, "read error\n" );
return -1;
}
return iCnt;
}
5.大小端显示,因为每列显示的内容是两个字节,如果主机是小端模式,则每列显示为“MSB+LSB”;如果主机为大端模式,则每列显示为“LSB+MSB”
e.g
echo abcd | od -t xS
小端模式,输出:
0000000 6261 6463 000a
大端模式,输出:
0000000 6162 6364 0a00
int
print_oct( unsigned char *cpStr, int iLen )
{
int i = 0;
int iCnt = 0;
unsigned short usPrtValue = 0;
for( i = 0; i < iLen; i++ )
{
if( iCnt++ == 1 )
{
#if BYTE_ORDER == LITTLE_ENDIAN
usPrtValue |= ( cpStr[ i ] << 8 );
#elif BYTE_ORDER == BIG_ENDIAN
usPrtValue |= cpStr[ i ];
#endif
printf( "%06o", usPrtValue );
putchar( ' ' );
usPrtValue = 0;
iCnt = 0;
}
else
{
#if BYTE_ORDER == LITTLE_ENDIAN
usPrtValue = cpStr[ i ];
#elif BYTE_ORDER == BIG_ENDIAN
usPtrValue = cpStr[ i ] << 8;
#endif
}
}
if( iCnt == 1 )
printf( "%06o", usPrtValue );
fflush( stdout );
return 0;
}
6.运行结果:
1)标准输入
2)文本文件
3)二进制文件
7.源代码