A problem with fork() and subsequent flock()
Manish Jain
unxfbsdi at gmail.com
Fri Nov 7 16:16:58 PST 2008
Hi,
I am starting out as a C/C++ programmer on FreeBSD and I am stuck with a
small but irritating problem. I was trying out the flock() call and
wrote flocksample.cpp, which starts out with a fork() and subsequent
calls to flock() from both processes (parent as well as child; the child
does an initial sleep(1) before anything else). It compiles okay and the
parent's flock() call succeeds. But the child's flock() call too
succeeds on the same file descriptor even before the first flock()
unlocks. Can anyone please point out where the problem is ? I am not
even sure whether the problem is FreeBSD specific.
Attached is flocksample.cpp
Thanks for any help
Manish Jain
unxfbsdi at gmail.com
-------------- next part --------------
#include <sys/stat.h>
#include <sys/file.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cassert>
using namespace std;
const char * szFileName = "/tmp/flock.log";
int addfunc(int fd);
int readfunc(int fd);
int main()
{
int fd = open(szFileName, O_RDWR | O_CREAT);
assert(fd > 2);
if (fork())
{
return addfunc(fd);
}
else
{
cout << "Child sleeping for 1s before attempting to read log" << endl;
sleep(1); //ensure that child's readfunc starts after parent's addfunc
return readfunc(fd);
}
}
int addfunc(int fd)
{
char buffer[4];
int i = 0;
int result = flock(fd, LOCK_EX);
assert(result == 0);
while(i < 10)
{
sprintf(buffer, "%d\n\0", ++i);
write(fd, buffer, strlen(buffer));
}
while(*buffer != 'U')
{
cout << "Blocking on addfunc. Type U to unlock log" << endl;
cin >> buffer;
}
cout << "Unblocking on addfunc ..." << endl;
close(fd); //automatically calls LOCK_UN
return 0;
}
int readfunc(int fd)
{
struct stat fstat;
int result = flock(fd, LOCK_SH);
assert(result == 0);
cout << "readfunc got hold of log ..." << endl;
lstat(szFileName, &fstat);
char * buffer = new char[fstat.st_size + 1];
lseek(fd, 0, SEEK_SET);
while (result < fstat.st_size)
{
result += read(fd, buffer + result, (fstat.st_size - result));
}
close(fd); //automatically calls LOCK_UN
buffer[result] = 0;
cout << "Following are the contents of the file flock.log :" << endl;
cout << buffer << endl;
delete[] buffer;
return 0;
}
More information about the freebsd-fs
mailing list