[comp.lang.perl] DBM Problems in PL28

arne@yc.estec.nl (Arne Lundberg) (08/17/90)

Since installing patch 28 I have found a problem with dbm files,
exemplified with the following small example:

------------------------------------------------------------------
dbmopen(I,  "/tmp/index", 0666) || die "cant open index dbm";


# $I{'#'} = '#';	#	This kludge will eliminate the problem

while (($k, $v) = each %I) {
    if ($s = $I{$k}) {
	    print "$k FOUND in dbm file\n"; 
    } else {
	    print "$k not found in dbm file\n";
    }
}
dbmclose(I);
exit(0);
------------------------------------------------------------------

When this is run and the dbm file contains a few entries the following
is printed:

a not found in dbm file
b not found in dbm file
c not found in dbm file
abc not found in dbm file
def not found in dbm file
# not found in dbm file

If the kludge line is activated it will correctly find all entries in
the dbm file.

I am running perl on a hp9000/835 with HP-UX 7.0.

Has anyone seen this before, what can I do?


Arne Lundberg

European Space Technology Centre, Noordwijk, the Netherlands
arne@yc.estec.nl or ALUNDBER@ESTEC.BITNET
Phone: +31 1719 84865, Fax: +31 1719 12142, Telex: 39098

Andrew.Vignaux@comp.vuw.ac.nz (Andrew Vignaux) (08/18/90)

In article <1414@esatst.yc.estec.nl>, arne@yc.estec.nl (Arne Lundberg) writes:
|> Since installing patch 28 I have found a problem with dbm files,

I think the problem is in the lazy array creation that went in in
pl.28.  hfetch() only creates the array if the access is an lval and
it hasn't been stored into already.  Unfortunately, dbm files can
already have stuff in them.  The local fix:

      if (!tb->tbl_array) {
! 	if (lval)
  	    Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*);

to

      if (!tb->tbl_array) {
! 	if (lval || tb->tbl_dbm)
  	    Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*);

works, but it means that

	dbmopen(FOO,"foo",0666); print defined(%FOO), "\n";

still prints 0.

Here's a completely unofficial patch that (I think) fixes this
problem.  I'm posting this because I can't believe I'm the only one
who depends on dbm files in perl.  I don't want to go back to 18
because of the lack of dbmopen(FOO, "foo", undef) ;-)

*** ./hash.c~	Tue Aug 14 21:17:53 1990
--- ./hash.c	Sat Aug 18 14:22:50 1990
***************
*** 551,556 ****
--- 551,558 ----
      }
      tb->tbl_dbm = dbminit(fname) >= 0;
  #endif
+     if (!tb->tbl_array && tb->tbl_dbm != 0)
+ 	Newz(507,tb->tbl_array, tb->tbl_max + 1, HENT*);
      return tb->tbl_dbm != 0;
  }


This fix also means that

	dbmopen(FOO,"foo",undef); print defined(%FOO), "\n";
and
	dbmopen(BAR,"bar",0666); print defined(%BAR), "\n";

prints 0 if "foo.dir" doesn't exist, or "bar.{dir,pag}" can't be
created.

Both "fixes" pass make test on a MORE/bsd hp300.

Andrew
-- 
Domain address: Andrew.Vignaux@comp.vuw.ac.nz

boetsch@lan.informatik.tu-muenchen.dbp.de (Ernst Boetsch) (08/22/90)

I got the same problem with perl 3.0 PL.28 on SUN-Sparc (4.0.3) and
VaxStation II (Ultrix 3.1).
A work around is also a dummy assignment
	$DBM{'dummy'} = 'dummy';
previos to the `dbmopen(DBM3, ...);' (important, if the database shall
not be changed by the dummy entry).

Additionally, I found the following problems with ndbm associative
arrays:
- I cannot read (!!!) ndbm associative arrays if I do not have also
  write access (contrary to the manual).
  This problem did not appear in patch level 18 and before.
- `Configure' defines both
	d_ndbm='define'
	d_odbm='define'
  The problem also appeared in previous patch levels.
- ndbm-arrays cannot be set by the construct
	%DBMarray = (key1, val1, key2, val2 ...)


Ernst Boetsch,			Leibniz-Rechenzentrum
		       der Bayerischen Akademie der Wissenschaften
	       Barer Strasse 21,  D-8000 Muenchen 2,  West Germany
boetsch@informatik.tu-muenchen.dbp.de	    Tel.: +49 89 2105 7480
boetsch%informatik.tu-muenchen.dbp.de @ {relay.cs.net, unido.uucp}

gorpong@ping.uucp (Gordon C. Galligher) (09/06/90)

In article <26E5495D.7759@ics.uci.edu> nagel@wintermute.ics.uci.edu (Mark Nagel) writes:
>$dbm00{some_key} fails for whatever (valid) key is used.  I don't
>think it is a bug in man, but a bug in dbm access under pl28.

That would go along with a problem I am experiencing in PL28 on SCO UNIX.
In order to get PERL to compile and begin the tests without core dumping
I was forced to use the 'rcc' compiler (the standard distribution AT&T
compiler, as opposed to 'cc' which is the Microsoft C compiler).  Once
I did that, I then attempted to test PL28 on the system.  It failed io.dup
test 2, and io.pipe test 6, and when it attempted to do op.dbm, it just
hung.  It is hanging on the loop:
	while (($key,$value) = each(h)) {
		$i++;
	}
The dbm file does not exist, therefore this program just created it with
the dbmopen() function.  It is expecting that loop to exit the first time,
but what really happens is it just hangs in that loop incrementing $i.
This test did pass PL18.  In fact, PL18 works just fine on this system,
even using the MicroSoft C compiler.  I am curious as to why I have had
to go through all these hoops.  (When using 'cc', it attempts to do test
base.if, and segmentation fault/core dumps.)

Is anyone else running SCO UNIX?  Have you had any problems getting PERL PL28
to (1) compile, (2) pass the tests, (3) just plain work?

It does look like a bug in PL28 with the dbm, but it could just be a problem
with the way I have things set up.  I have no idea.

		-- Gordon.


-- 
Gordon C. Galligher	9127 Potter Rd. #2E	Des. Plaines, Ill.    60016-4881
     telxon!ping%gorpong@uunet.uu.net (not tested)  (Is this even legal??)
     ...!uunet!telxon!ping!gorpong      (tested)    (And it works!)
"It seems to me, Golan, that the advance of civilization is nothing but an
 exercise in the limiting of privacy." - Janov Pelorat -- _Foundation's Edge_