Write a C program that reverses the bytes of a given arbitra
Write a C program that reverses the bytes of a given arbitrary length file in-place, as in, the contents of the file are swapped without a temporary file and without producing a second file. Use mmap(). E.g. ./reverse2 infile results in the contents of infile being reversed after the call, and calling ./reverse2 infile twice should result in the same file as you started with.
Solution
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char * argv[]) {
File *in, *out;
int errflg = 0;
size_t blocksize = 0;
size_t bufsize = 0;
char* instr;
char* outstr;
char **endptr;
char *buf;
char c;
char tmpbuf[L_tmpnam+1];
off_t inlen, ipos;
size_t nbytes;
static struct stat fstatus;
/* Extract options */
instr = (char *)NULL;
outstr = (char *)NULL;
/* scan for the positional arguments */
for (; optind < argc; optind++) {
if (!instr) {
instr = argv[optind];
} else {
if (!outstr) {
outstr = argv[optind];
} else {
errflg++;
}
}
}
/* Report option errors */
if (errflg) {
fprintf(stderr,\"reverse: Usage: \ \");
fprintf(stderr,\" reverse [-b blocksize] [[-i] input] [[-o] output]\ \");
fprintf(stderr,\"\ \");
exit(2);
}
bufsize = blocksize;
if (blocksize < 512) bufsize = 512;
if (blocksize < 1) blocksize = 1;
if(! (buf=(char *)malloc(bufsize)) ) {
fprintf(stderr,\"reverse: Insufficient memory to allocate buffer\ \ \");
exit(1);
}
/* Now copy from the back of the input file to the start
of the output file, in blocks of size blocksize,
reversing each block as it is read */
for (ipos = 0; ipos < inlen; ipos += blocksize ) {
off_t postn;
size_t kbytes=blocksize;
int ii;
if (ipos+blocksize > inlen) {
kbytes += inlen-blocksize-ipos;
}
fseek(in, inlen-kbytes-ipos, SEEK_SET);
if (kbytes != (nbytes = fread(buf,1,kbytes,in))) {
fprintf(stderr,
\"reverse: Read failed at position %ld for %ld bytes, got %ld.\ \",
(long)(inlen-kbytes-ipos), (long)kbytes, (long)nbytes);
}
for(ii = 0; ii < nbytes/2; ii++) {
char t;
t = buf[nbytes-1-ii];
buf[nbytes-1-ii] = buf[ii];
buf[ii] = t;
}
fwrite(buf,1,nbytes,out);
}
/* close the input file, but not the output if it is stdout
but we will do an fflush. Note the the final exit would
have done the same closes */
fclose(in);
if (out != stdout) {
fclose(out);
} else {
fflush(out); /* usually not necessary, but we\'ll be cautious */
}
exit(0);
}



