This is my answer to my original question. The code below will always write the number of commits at the end of the file. Whenever new entries are written to the file, I make sure it will overwrite the last number of commits and append new number of commits at the end. This way will increment the number of commits and maintain only one copy of num_commit always at the end of the file.
int main()
{
int name_length;
char pathFile[MAX_PATHNAME_LEN];
sprintf(pathFile, "my_log2.bin");
int filedescriptor = open(pathFile, O_RDWR | O_CREAT, 0777);
int num_segs = 10;
int mods = 200;
const char *segname = "testfil";
char real_segname[128];
strcpy(real_segname, segname); /* in my real program segname is passed into the function */
int i;
for (i = 1; i <= 100; i++)
{
if (i > 1)
{
lseek(filedescriptor, -sizeof(int), SEEK_END); /* overwrite the last num_commit */
}
write(filedescriptor, &num_segs, sizeof(int));
name_length = strlen(real_segname);
write(filedescriptor, &name_length, sizeof(int));
write(filedescriptor, real_segname, name_length);
write(filedescriptor, &mods, sizeof(int));
write(filedescriptor, &i, sizeof(int)); /* number of commits */
}
close(filedescriptor);
/* now read back the file */
int readfd = open(pathFile, O_RDONLY);
lseek(readfd, -sizeof(int), SEEK_END); /* read the number of commit first from the end of the file */
int num_commit;
read(readfd, &num_commit, sizeof(int));
printf("num_commit = %d \n", num_commit);
lseek(readfd, 0, SEEK_SET); /* start reading from the beginning of the file*/
int a, b, m;
char *name;
for (i = 0; i < num_commit; i++)
{
read(readfd, &a, sizeof(int));
read(readfd, &b, sizeof(int));
name = malloc(b);
read(readfd, name, b);
read(readfd, &m, sizeof(int));
printf("commit# = %d, num_segs=%d, name_length=%d, real_segname=%s, mods=%d \n", i+1, a, b, name, m);
free(name);
name = NULL;
}
close(readfd);
return 0;
}
As an alternative, I also tested maintaining the num_commit at the beginning of the file, which is a lot easier/less mind-twisting than using SEEK_END:
#define MAX_PATHNAME_LEN 256
int main()
{
int commit_times = 10;
char pathFile[MAX_PATHNAME_LEN];
sprintf(pathFile, "my_log2.bin");
int filedescriptor = open(pathFile, O_RDWR | O_CREAT, 0777);
int num_segs = 10;
int mods = 200;
const char *segname = "testfil";
char real_segname[128];
// strncpy(real_segname, segname, sizeof(real_segname));
strcpy(real_segname, segname);
lseek(filedescriptor, 0, SEEK_SET); /* write commit_times always at the beginning of the file */
write(filedescriptor, &commit_times, sizeof(int));
lseek(filedescriptor, sizeof(int), SEEK_SET); /* start writing after num_commit value */
write(filedescriptor, &num_segs, sizeof(int));
int name_length = strlen(real_segname);
write(filedescriptor, &name_length, sizeof(int));
write(filedescriptor, real_segname, name_length);
write(filedescriptor, &mods, sizeof(int));
commit_times++;
lseek(filedescriptor, 0, SEEK_SET); /* update the commit_times at the beginning of the file */
write(filedescriptor, &commit_times, sizeof(int));
close(filedescriptor);
/* now read back the file */
int readfd = open(pathFile, O_RDONLY);
int num_commit;
read(readfd, &num_commit, sizeof(int));
read(readfd, &num_segs, sizeof(int));
read(readfd, &name_length, sizeof(int));
read(readfd, real_segname, name_length);
read(readfd, &mods, sizeof(int));
printf("num_segs=%d, name_length=%d, real_segname=%s, mods=%d, num_commit=%d \n", num_segs, name_length, real_segname, mods, num_commit);
close(readfd);
return 0;
}