[comp.lang.perl] Manipulating dbm files, a sun strangeness

kannan@oar.net (Kannan Varadhan) (06/21/91)

Systems are all SUN 4s running Sun OS 4.1. (one is a 4/110, the other a
4/40).

perl is verion 4.009.  perl is interesting because it is easy to bring
out the error conditions trivially in it.  Also, I am unable to
reproduce all possible execution patterns in C.

Three different programs exist.

1)	A C version for reading all the entries in a  dbm database...
The C version has a for loop as...

datum		msgloc, msgstatus;
DBM		*newmail;

	newmail = dbm_open (slocal, O_RDONLY, 0600);
	for (msgloc = dbm_firstkey (newmail); msgloc.dptr;
				msgloc = dbm_nextkey (newmail)) {
	  msgstatus = dbm_fetch (newmail, msgloc);
	  }
	dbmclose (newmail);

This version seems to miss out certain datapoints, that are "present" in
the database.

2)	A perl version below, exhibits similar problems:

#! /usr/local/bin/perl

	dbmopen (NEWMAIL, "NewMail", 0600);
	while (($key,$val) = each %NEWMAIL) {
	  print STDOUT "$key->$val\n";
	  }
	dbmclose (NEWMAIL);

3)	On the contrary, the following version below, does not exhibit
the problem...

#! /usr/local/bin/perl

	dbmopen (NEWMAIL, "NewMail", 0600);
	foreach $i (keys %NEWMAIL) {
	  print STDOUT "$i->$NEWMAIL{$i}\n";
	  }
	dbmclose (NEWMAIL);


Firstly,  what's different in cases 2 and 3.

Secondly, Cases 1 and 2 give the same result, identically different from
case 3.  Even otherwise, a straight forward scrutiny leads me to assume
that case 2 would yield code similar to case 1.
Therefore, how does perl execute case 3, such that it does not miss out
the data?

Thirdly, this seems to be a terrible ndbm bug on the SUNs, no?

I have backup copies of the dbm files, in case it would be interesting.

Puzzled,


Kannan
-- 
Kannan Varadhan, Internet Engineer (OARnet),		+1 614 292 4137
Ohio Supercomputer Center, 1224, Kinnear Rd.,  Columbus, OH 43212