Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 08 Nov 2008 05:23:37 +0530
From:      Manish Jain <unxfbsdi@gmail.com>
To:        freebsd-fs@freebsd.org
Subject:   A problem with fork() and subsequent flock()
Message-ID:  <4914D501.4090400@gmail.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------090009080504050803020107
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit


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@gmail.com


--------------090009080504050803020107
Content-Type: text/plain;
 name="flocksample.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="flocksample.cpp"

#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;
}

--------------090009080504050803020107--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4914D501.4090400>