Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!snorkelwacker!bloom-beacon!eru!hagbard!sunic!bmc.uu.se!kuling!jand From: jand@kuling.UUCP (Jan Dj{rv) Newsgroups: comp.lang.perl Subject: Re: Tom Christiansen's man program no longer works with pl28 Keywords: perl pl28 man xenix Message-ID: <1652@kuling.UUCP> Date: 6 Sep 90 06:33:59 GMT References: <578@seer.UUCP> Reply-To: jand@kuling.UUCP (Jan Dj{rv) Organization: Dept. of Computer Systems, Uppsala University, Sweden Lines: 102 In article <578@seer.UUCP> bll@seer.UUCP (Brad Lanam) writes: > > I just brought perl up to patchlevel 28, and everything except >Tom Christiansen's man program seems to work. It can't seem to find >anything in the dbm database. I rebuilt the database, but that didn't >help. He uses those eval things... I can't figure out how to print >out what is in the dbm array. > > Has anyone else had this problem? The man program uses ndbm and PL 28 has problems with it. It's not anything wrong with Tom's program, it's perl. The first problem is that perl doesn't allow open of a dbm file readonly. Here's my patch for that: *** hash.c.Distributed Fri Aug 17 12:26:43 1990 --- hash.c Mon Aug 20 09:19:37 1990 *************** *** 538,543 **** --- 538,545 ---- tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode); if (!tb->tbl_dbm) tb->tbl_dbm = dbm_open(fname, O_RDWR, mode); + if (!tb->tbl_dbm) + tb->tbl_dbm = dbm_open(fname, O_RDONLY, mode); #else if (dbmrefcnt++) fatal("Old dbm can only open one database"); *************** *** 551,556 **** --- 553,560 ---- } 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; } The other problem (the one you encountered) was discovered by Andrew Vignaux . I include his posting here. With these two patches Tom's man works OK for me. Jan D. Andrew Vignaux writes: 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