Listing 2: holify.c
/*
* Copyright (C) 1995
* Marty Leisner leisner@sdsp.mc.xerox.com.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <assert.h>
static const char *id = \
"$Id: holify.c,v 1.1 1995/01/24 02:47:20 leisner Exp $";
static char *progname;
static void usage(void)
{
exit(1);
}
/* write the last byte if its not written...
* this makes some systems work better
*/
static void copy_file(const int input, const int output)
{
int total_written = 0;
int total_read = 0;
int virtual_written;
int holes = 0;
/* indicates the last buffer was written */
int did_write = 0;
while(1) {
int bytes_read;
int bytes_written;
char buffer[4096 + 1];
char *cp;
bytes_read = read(input, &buffer, sizeof(buffer) - 1);
if(bytes_read == 0)
break;
if(bytes_read == -1) {
if(errno == EINTR)
continue;
fprintf(stderr, "Fatal error, %s\n", strerror(errno));
exit(1);
}
total_read += bytes_read;
buffer[bytes_read] = 1; /* sentinnel */
for(cp = buffer; !*cp; cp++)
;
if(cp == &buffer[bytes_read]) {
/* have hole */
int result;
result = lseek(output, bytes_read, SEEK_CUR);
did_write = 0;
assert(result != -1);
holes++;
} else {
bytes_written = write(output, buffer, bytes_read);
assert(bytes_written == bytes_read);
did_write = 1;
total_written += bytes_written;
}
virtual_written += bytes_read;
}
fprintf(stderr, "Wrote %d real bytes, %d virtual bytes\n", total_written,
virtual_written);
#ifndef NO_LAST_WRITE
if(!did_write) {
const char zero = 0;
lseek(output, -1, SEEK_CUR); /* back up */
write(output, &zero, 1); /* write a zero byte */
}
#endif
}
main(int argc, char **argv)
{
int i;
progname = argv[0];
if(argc == 1) {
/* input may be a pipe, stdout must be a file */
if(isatty(1)) {
fprintf(stderr, "Need to write to a file");
usage();
}
}
if(argc == 1)
copy_file(0, 1);
else {
fprintf(stderr, "can't do this yet\n");
usage();
for(i = 1; i < argc; i++) {
}
}
}
|