Unix Programming - Locking in C++

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > September 2004 > Locking in C++





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Locking in C++
Kristofer Pettijohn

2004-08-29, 2:49 am

What are people using to lock files in C++ these days?

The OS I'm mainly using is FreeBSD 5.2.1, GCC 3.3.3, and of course, in
C++ with [io]?fstream.

Thanks!

--
Kristofer Pettijohn
kristofer@cybernetik.net
Nils Weller

2004-08-29, 5:52 pm

In article <41318407$0$2917$d5a6236f@newsreader.cybernetik.net>,
Kristofer Pettijohn wrote:
> What are people using to lock files in C++ these days?
>
> The OS I'm mainly using is FreeBSD 5.2.1, GCC 3.3.3, and of course, in
> C++ with [io]?fstream.


POSIX and UNIX are based on C - they do not even know C++ I/O streams.
But it's even worse than that; The locking functions provided to obtain
a lock operate on file descriptors, not file streams.

That said, what you want is the fcntl() function because this way is the
most portable one (the traditional System V way was lockf() and the
traditional BSD way was flock(). The latter is even part of SUSx, the
former is not.)

Here's how you write lock an entire file using fcntl():

struct flock f;
int fd;

if ((fd = open("file", O_RDWR)) == -1) {
/* Error */
}
f.l_type = F_WRLCK;
f.l_whence = 0;
f.l_start = SEEK_CUR;
f.l_len = 0;
f.l_pid = getpid();
if (fcntl(fd, F_SETLK, &f) == -1) {
/* Error */
}

There are two important things to note here. First of all, there is a
distinction between ``advisory locking'' and ``mandatory locking''. An
advisory lock is intended to be used between a group of friendly
processes who voluntarily check every file they access for such a lock.
If they do not check for lock requests or do not listen to them, they
are free to use the file as they wish, despite the lock. Advisory
locking is the default, so if you intend to prevent unrelated processes
who are unaware of your intentions from using the file, you will need to
turn on mandatory locking.

Mandatory locking is enforced by the kernel and cannot be ignored. In
order to turn on mandatory locking on a file, a file permission kludge
is used: If you turn on the set-gid bit and turn off the group
executable bit of the file, then every subsequent lock on it will be
mandatory. Note that this kind of locking is not as widespread as
advisory locking; Modern BSD systems for one do not support it.

The second point is that you must keep the file descriptor you used to
obtain the lock open. As soon as you close it, the lock(s) is (are) gone
as well.

--
My real email address is ``nils<at>sipoc<dot>de''
Nils Weller

2004-08-29, 5:52 pm

In article <2pe7egFk298pU1@uni-berlin.de>, Nils Weller wrote:
> most portable one (the traditional System V way was lockf() and the
> traditional BSD way was flock(). The latter is even part of SUSx, the

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^[vbc
ol=seagreen]
> former is not.)[/vbcol]
^^^^^^^^^^^^^

Bah. It's the other way around, of course!

--
My real email address is ``nils<at>sipoc<dot>de''
amsa

2004-09-02, 6:50 pm

how does fcntl() function differ from the traditional lockf()
function.
even if the file is locked by fcntl or lockf, another process can
always read a locked file.

av.

Nils Weller <me@privacy.net> wrote in message news:<2pe7egFk298pU1@uni-berlin.de>...
> In article <41318407$0$2917$d5a6236f@newsreader.cybernetik.net>,
> Kristofer Pettijohn wrote:
>
> POSIX and UNIX are based on C - they do not even know C++ I/O streams.
> But it's even worse than that; The locking functions provided to obtain
> a lock operate on file descriptors, not file streams.
>
> That said, what you want is the fcntl() function because this way is the
> most portable one (the traditional System V way was lockf() and the
> traditional BSD way was flock(). The latter is even part of SUSx, the
> former is not.)
>
> Here's how you write lock an entire file using fcntl():
>
> struct flock f;
> int fd;
>
> if ((fd = open("file", O_RDWR)) == -1) {
> /* Error */
> }
> f.l_type = F_WRLCK;
> f.l_whence = 0;
> f.l_start = SEEK_CUR;
> f.l_len = 0;
> f.l_pid = getpid();
> if (fcntl(fd, F_SETLK, &f) == -1) {
> /* Error */
> }
>
> There are two important things to note here. First of all, there is a
> distinction between ``advisory locking'' and ``mandatory locking''. An
> advisory lock is intended to be used between a group of friendly
> processes who voluntarily check every file they access for such a lock.
> If they do not check for lock requests or do not listen to them, they
> are free to use the file as they wish, despite the lock. Advisory
> locking is the default, so if you intend to prevent unrelated processes
> who are unaware of your intentions from using the file, you will need to
> turn on mandatory locking.
>
> Mandatory locking is enforced by the kernel and cannot be ignored. In
> order to turn on mandatory locking on a file, a file permission kludge
> is used: If you turn on the set-gid bit and turn off the group
> executable bit of the file, then every subsequent lock on it will be
> mandatory. Note that this kind of locking is not as widespread as
> advisory locking; Modern BSD systems for one do not support it.
>
> The second point is that you must keep the file descriptor you used to
> obtain the lock open. As soon as you close it, the lock(s) is (are) gone
> as well.

Kristofer Pettijohn

2004-09-02, 6:50 pm

Nils Weller <me@privacy.net> wrote:
> In article <2pe7egFk298pU1@uni-berlin.de>, Nils Weller wrote:
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ^^^^^^^^^^^^^
>
> Bah. It's the other way around, of course!


I'm aware of flock(), lockf(), and fcntl().. I guess I'm wondering
if there is a way to lock an opened fstream.. I realize it's not
part of the standard and there are no functions to do it, and some
people use fstream.rdbuf()->fd() to get the file descriptor, but
as far as I can tell, my version of GNU (gcc version 3.3.3 [FreeBSD] 20031106)
doesn't offer the fd() member... so I'm guessing I will just have to
either use the C-style fopen() and attach the file descriptor to a
filebuf object so I have a valid descriptor I can put a lock on, or
is that a bad idea?

--
Kristofer Pettijohn
kristofer@cybernetik.net
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com