Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

     I'd like to flock() a socket passed to a child process 
via a filehandle (STDOUT). I've tried doing this in the child:
flock(STDOUT, 2); # LOCK_EX = 2 - grab lock syswrite(STDOUT, "$message"); flock(STDOUT, 8); # LOCK_UN = 8 - free lock
But flock() doesn't work, I think because all children
share the same sockethandle - flock() is always
successful in gaining a lock - it seems flock() does
not work across child processes. One solution I've heard of is to open a new filehandle in
each child - and flock on this per-child filehandle. Does anyone know how to do that to a socket? Is something like this feasible?
open(CHILDHANDLE); # not sure how to do this? *CHILDHANDLE = *STDOUT; # unique handle on parent socket flock(CHILDHANDLE, 2); # LOCK_EX = 2 - grab lock syswrite(CHILDHANDLE, "$message"); flock(CHILDHANDLE, 8); # LOCK_UN = 8 - free lock
Any perls of wisdom would be much appreciated... Nige

Replies are listed 'Best First'.
Re: flocking a socket
by kschwab (Vicar) on Jan 25, 2002 at 19:54 UTC
    The following text from my Solaris man page for flock() would seem to indicate that you can't do this:

    Locks are on files, not file descriptors. That is, file descriptors duplicated through dup(2) or fork(2) do not result in multiple instances of a lock, but rather multiple references to a single lock. If a process holding a lock on a file forks and the child explicitly unlocks the file, the parent will lose its lock. Locks are not inherited by a child process.

    I'm guessing that you are trying to coordinate reads or writes between the parent and child. I think that restating the higher-level problem you are trying to solve would be more helpful.

Re: flocking a socket
by clintp (Curate) on Jan 25, 2002 at 19:45 UTC
    This code:
    flock(HANDLE, 2);
    Probably isn't doing what you think it is. flock() has a return value, and it's important. Try this:
    flock(HANDLE, 2) || warn "flock failed: $!";
    I won't even begin to nag you about fcntl constants, you've got a harsh lesson ahead of you already. :)