Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#define _LARGEFILE64_SOURCE /* See feature_test_macros(7) */
//void *mmap(void *addr, size_t length, int prot, int flags,/int fd, off_t offset);
//int munmap(void *addr, size_t length);
//void *memmove(void *dest, const void *src, size_t n);
//size_t pagesize = getpagesize();
//printf("System page size: %lu bytes\n", pagesize);
//char * region = mmap(
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#define EXTENDSIZE 8
#define FILESIZE (NUMINTS * sizeof(int))
int
main(
int argc,
char **argv)
{
int i;
int fd;
char *map; /* mmapped array of char * */
long extendSize;
if (argc!=3) {
fprintf(stderr,"?Require 2 param: filename spaceToInsert\n");
exit(EXIT_FAILURE);
}
/* Open a file for writing.
* - Creating the file if it doesn't exist.
* - Truncating it to 0 size if it already exists. (not really needed)
*
* Note: "O_WRONLY" mode is not sufficient when mmaping.
*/
fd = open(argv[1], O_RDWR, 0); // | O_CREAT | O_TRUNC, (mode_t)0600);
if (fd == -1) {
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
extendSize = atoi( argv[2] );
if ( extendSize <= 0 ) {
perror( "Extend size must be positive integer" );
exit( EXIT_FAILURE );
}
struct stat fsize { 0 };
if (fstat(fd, &fsize) < 0) {
int saveErrno = errno;
fprintf(stderr, "fstat(%d) returned errno=%d.", fd, saveErrno);
exit(EXIT_FAILURE);
}
fprintf(stderr, "%%sizeof fstat.off_t is %d\n", sizeof(fsize.st_size));
off_t eopos = lseek(fd, 0, SEEK_END);
if (eopos == -1) {
close(fd);
perror("Error calling lseek() to get file length");
exit(EXIT_FAILURE);
}
fprintf(stderr, "%%Sought size is %ld\n", eopos);
fprintf(stderr, "%%Adding head-end %ld bytes\n", extendSize );
//result = lseek(fd, 0, SEEK_END);
off_t neweopos = eopos + extendSize - 1;
off_t seekres = lseek(fd, neweopos, SEEK_SET);
if (seekres == -1) {
close(fd);
perror("Error calling lseek() to 'expand' the file");
exit(EXIT_FAILURE);
}
int result = write(fd, "", 1); //Write a null bytes to expand file
if (result != 1) {
close(fd);
perror("Error writing last byte of the file");
exit(EXIT_FAILURE);
}
neweopos++;
/* Now the file is ready to be mmapped.
*/
map = (char*)mmap(0, neweopos, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Now move the file contents forward (just leave the original junk hanging around at beginning of file)
*/
memmove(map + extendSize, map, eopos);
/* free the mmapped memory
*/
if (munmap(map, neweopos) == -1) {
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
// zero out the first extendSize bytes of file
if ( fseek( fd, 0, SEEK_SET ) !== 0 ) {
perror( "Error getting to beginning of file" );
exit();
}
// write zeros
while ( extendSize-- ) {
fputc( 0, fd );
}
/* Un-mmaping doesn't close the file, so we still need to do that.
*/
close(fd);
return 0;
}