I have a file which will be read and write by the multiple process. So to synchronize the file between multiple processes I was using fcntl()
.
Let's assume we have a file orignal.txt
and we have some content in the orignal.txt
. Assume the contents in the file are:
show core status
show table status
show action status
Now let's say we have three process A,B,C
which would be accessing orignal.txt
for deleting the content from it. Say A
will delete show core status
. B
will delete show table status
and C
will delete show action status
.
Actually show core status
,show table status
and show action status
are some commands which is related to particular process, So I am assuming show core status
is related to A
so whenever A will come he will write show core status
into the file orignal.txt
and before A
terminates it will delete the show core status
from the file orignal.txt
. Same with other processes also.
So for that I have written the code.
Note: This is a common API for deleting the content from the file which all three processes (A,B,C
) will use.
#define ACQUIRE_LOCK 1
#define RELEASE_LOCK 0
int delete_content_from_file(char *command)
{
FILE *fp, *tempFd;
char buf[4096];
int ret;
fp = fopen ("orignal.txt", "r+");
if (fp == NULL)
{
printf("orignal.txt does not exist");
return -1;
}
printf("Acquiring lock for orignal.txt");
ret = fileSync(fp,ACQUIRE_LOCK,F_WRLCK);
if(ret == -1)
{
printf("Failed to acquire lock");
exit(EXIT_FAILURE);
}
tempFd = fopen ("duplicate.txt", "w");
if (tempFd == NULL)
{
printf("Duplicate.txt not exist");
return -1;
}
// read text until newline
while (!feof(fp))
{
if (fgets (buf, sizeof(buf), fp) != NULL)
{
buf[strlen(buf)-1]='\0';
if ((ret = strcmp (command, buf)) != 0) {
fprintf(tempFd, "%s\n", buf);
}
}
fclose(tempFd);
system("cp duplicate.txt orignal.txt");
remove("duplicate.txt");
printf("Releasing lock");
ret = fileSync(fp,RELEASE_LOCK,F_UNLCK);
if(ret == -1)
{
printf("unable to release the lock for orignal.txt");
return -1;
}
fclose (fp);
return 0;
}
int fileSync(FILE *fd,bool flag,short lock_type)
{
struct flock lock;
lock.l_type = lock_type;
lock.l_whence = SEEK_SET; // Starting from the begining of the file
lock.l_start = 0; // no offset
lock.l_len = 0; // to the end of file. 0 means EOF
if(flag == ACQUIRE_LOCK)
{
if(fcntl(fileno(fd), F_SETLKW, &lock) < 0)
{
perror("Error to acquire lock");
return -1;
}
}
else
{
if(fcntl(fileno(fd), F_UNLCK, &lock) < 0)
{
perror("Error releasing lock");
return -1;
}
}
return 0;
}
What I expected : When A
will release the lock, the content of the file should become
show table status
show action status
and when B
will release the lock, the content of the file should become
show action status
and when C
will release the lock, the file will become empty.
But
What I got: When A
has released the lock, content of the file is same. All three lines are present. But When B
has released the lock , I saw B
has deleted the content show table status
from the file and same C
also deleted the show action status
This is not fixed behaviour, sometimes B
does not delete the content but A
deletes or C
deletes.
I have got struck at this point. Looks to me that file is not getting sync between processes. Any help will be appreciated. Thanks in Advance!