This started as a plea for help, but then I solved the problem - usual thing
of trying to explain to someone else and things become clearer.
I had an irritating problem with Perl and GDBM. One Perl program execs
another and the second can't tie to a GDBM file which is used for passing
information. The problem appears to be that the first program is not
properly closing the file, as shown by debugging code which runs lsof on the
GDBM file. Test code like this
#!/usr/bin/perl
#
use GDBM_File;
use strict "vars";
my (%session);
$| = 1; # autoflush
my $lsof = lsof $ARGV[0];
print "before tie - lsof of session file $ARGV[0]\n$lsof";
tie(%session, GDBM_File, $ARGV[0], &GDBM_WRITER, 0640) or
die("can't opensession file $ARGV[0]");
$lsof = lsof $ARGV[0];
print "after tie - lsof of session file $ARGV[0]\n$lsof";
untie %session;
$lsof = lsof $ARGV[0];
print "after untie - lsof of session file $ARGV[0]\n$lsof";
exit 0;
works perfectly (doesn't it bloody always :-( ) but in my real program,
after the untie lsof still shows my program to have the file open and the
untie appears to succeed as in
untie %session or die("untie failed");
prints nothing.
When I started writing this, I anticipated the obvious question which was
"How does your real code differ from your test code ?" and my immediate
answer was that it doesn't, at least in so far as tying / untying was
concerned. But then I looked at the code and saw that the untie was done
in some code like this
unless ($session{'key1'} =~ /,/) {
if ($some_value = $some_value - $session{'key2'} * $session{'key3'}) < 0) {
untie . . .
%session is the tied hash and attempting to untie it inside references to it
doesn't work, although untie returns no eror. Changing the code to
$multiple = ($session{'key1'} =~ /,/);
unless ($multiple) {
$flag = ($some_value = $some_value - $session{'key2'} * $session{'key3'}) < 0);
if ($flag) {
untie . . .
so that there are no 'hanging' references to %session solves the problem.
Any Perl wizards care to hazard a guess as to why this may be so ?
Regards,
Niall
Maintained by the ILUG website team. The aim of Linux.ie is to
support and help commercial and private users of Linux in Ireland. You can
display ILUG news in your own webpages, read backend
information to find out how. Networking services kindly provided by HEAnet, server kindly donated by
Dell. Linux is a trademark of Linus Torvalds,
used with permission. No penguins were harmed in the production or maintenance
of this highly praised website. Looking for the
Indian Linux Users' Group? Try here. If you've read all this and aren't a lawyer: you should be!