《unix环境高级环境编程》4.6 网上找的程序,转来。方便以后回顾。看了一遍,觉得是不是应该把标准输入和输出改成文件名好点呢,也就是argv[1]和argv[2],然后再利用open获得其文件描述符。
/*
* filename: mycp.c
* descritption: copy file with hole
* author: soforthhe, at 2010-3-30
* example: mycp < src.txt > dst.txt
* contact: soforth@qq.com
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef BUFSIZE
#define BUFSIZE 4096
#endif
static int
iszeros(char *buf, int len)
{
int i;
for( i = 0; i < len; i++ )
{
if( buf[i] != 0 )
return 0;
}
return 1;
}
int
main(int argc, char**argv)
{
ssize_t nread; /* bytes read*/
ssize_t nwrite; /* bytes write*/
char *buf;
size_t len = BUFSIZE;
struct stat st;
if( fstat(STDIN_FILENO,&st) != 0 )
{
perror("fstat");
}
else
{
len = st.st_blksize; /* 1024 on SUSE Linux 2.6.16 */
}
if((buf = (char*)malloc(len)) == NULL )
{
perror( "malloc error");
exit(-1);
}
while( (nread = read(STDIN_FILENO, buf, len)) > 0 )
{
if( iszeros(buf, len) ) /* find out whether it's a hole block */
{
if(lseek(STDOUT_FILENO, len, SEEK_CUR) < 0 ) /* make a hole */
{
perror("seek error");
exit(-1);
}
continue;
}
if( (nwrite = write(STDOUT_FILENO, buf, nread)) < 0 )
{
perror("write error");
exit(-1);
}
}
if( nread < 0 ) /* read error */
{
perror("read error");
exit(-1);
}
/* reach end of file */
free(buf);
return 0;
}