Subversion Repositories sysadmin_scripts

Rev

Rev 58 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
58 rodolico 1
#define _LARGEFILE64_SOURCE /* See feature_test_macros(7) */
2
 
3
 
4
 
5
       //void *mmap(void *addr, size_t length, int prot, int flags,/int fd, off_t offset);
6
       //int munmap(void *addr, size_t length);
7
       //void *memmove(void *dest, const void *src, size_t n);
8
 
9
//size_t pagesize = getpagesize();
10
//printf("System page size: %lu bytes\n", pagesize);
11
//char * region = mmap(
12
 
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <sys/types.h>
16
#include <sys/stat.h>
17
#include <unistd.h>
18
#include <fcntl.h>
19
#include <sys/mman.h>
20
#include <string.h>
21
#include <errno.h>
22
 
23
#define EXTENDSIZE 8
24
#define FILESIZE (NUMINTS * sizeof(int))
25
 
26
int
27
main(
28
  int argc,
29
  char **argv)
30
{
31
  int i;
32
  int fd;
33
  char *map;  /* mmapped array of char * */
34
  long extendSize;
35
 
36
  if (argc!=3) {
37
    fprintf(stderr,"?Require 2 param: filename spaceToInsert\n");
38
    exit(EXIT_FAILURE);
39
  }
40
 
41
  /* Open a file for writing.
42
   *  - Creating the file if it doesn't exist.
43
   *  - Truncating it to 0 size if it already exists. (not really needed)
44
   *
45
   * Note: "O_WRONLY" mode is not sufficient when mmaping.
46
   */
47
  fd = open(argv[1], O_RDWR, 0);    // | O_CREAT | O_TRUNC, (mode_t)0600);
48
  if (fd == -1) {
49
    perror("Error opening file for writing");
50
    exit(EXIT_FAILURE);
51
  }
52
 
53
  extendSize = atoi( argv[2] );
54
 
55
  if ( extendSize <= 0 ) {
56
     perror( "Extend size must be positive integer" );
57
     exit( EXIT_FAILURE );
58
  }
59
 
60
 
61
  struct stat fsize { 0 };
62
 
63
  if (fstat(fd, &fsize) < 0) {
64
    int saveErrno = errno;
65
    fprintf(stderr, "fstat(%d) returned errno=%d.", fd, saveErrno);
66
    exit(EXIT_FAILURE);
67
  }
68
 
69
  fprintf(stderr, "%%sizeof fstat.off_t is %d\n", sizeof(fsize.st_size));
70
 
71
 
72
  off_t eopos = lseek(fd, 0, SEEK_END); 
73
 
74
  if (eopos == -1) {
75
    close(fd);
76
    perror("Error calling lseek() to get file length");
77
    exit(EXIT_FAILURE);
78
  }
79
 
80
  fprintf(stderr, "%%Sought size is %ld\n", eopos);
81
  fprintf(stderr, "%%Adding head-end %ld bytes\n", extendSize );
82
 
83
 
84
  //result = lseek(fd, 0, SEEK_END);
85
 
86
  off_t neweopos = eopos + extendSize - 1;
87
  off_t seekres = lseek(fd, neweopos, SEEK_SET);
88
  if (seekres == -1) {
89
    close(fd); 
90
    perror("Error calling lseek() to 'expand' the file");
91
    exit(EXIT_FAILURE);
92
  } 
93
  int result = write(fd, "", 1); //Write a null bytes to expand file
94
  if (result != 1) {
95
    close(fd);
96
    perror("Error writing last byte of the file");
97
    exit(EXIT_FAILURE);
98
  }
99
 
100
  neweopos++;
101
 
102
  /* Now the file is ready to be mmapped.
103
   */
104
  map = (char*)mmap(0, neweopos, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
105
  if (map == MAP_FAILED) {
106
    close(fd);
107
    perror("Error mmapping the file");
108
    exit(EXIT_FAILURE);
109
  }
110
 
111
  /* Now move the file contents forward (just leave the original junk hanging around at beginning of file)
112
   */
113
  memmove(map + extendSize, map, eopos);
114
 
115
  /* free the mmapped memory
116
   */
117
  if (munmap(map, neweopos) == -1) {
118
    perror("Error un-mmapping the file");
119
    exit(EXIT_FAILURE);
120
    /* Decide here whether to close(fd) and exit() or not. Depends... */
121
  }
122
 
123
 
124
  // zero out the first extendSize bytes of file
125
  if ( fseek( fd, 0, SEEK_SET ) !== 0 ) {
126
     perror( "Error getting to beginning of file" );
127
     exit();
128
  }
129
 
130
  // write zeros
131
  while ( extendSize-- ) {
132
     fputc( 0, fd );
133
   }
134
 
135
 
136
  /* Un-mmaping doesn't close the file, so we still need to do that.
137
   */
138
  close(fd);
139
  return 0;
140
}