[comp.sys.amiga] chdir

hadeishi@husc7.HARVARD.EDU (Mitsuharu Hadeishi) (04/22/87)

	I've just spent some time tracking down a 24-byte memory leak
in SlideShow 1.2.  What I realized is that the Lattice chdir() must
be doing something like the following:

	CurrentDir(Lock(pathname,ACCESS_READ));

	The problem with this is that the lock obtained from Lock() takes
up 24 bytes and is never freed.  That is, every time I ran my program
I lost 24 bytes, until I replaced chdir() with

	newdir = Lock(pathname,ACCESS_READ);
	olddir = CurrentDir(newdir);

	and later, on exit:

	CurrentDir(olddir);
	UnLock(newdir);

	Now I can't see how one can implement chdir() to be UNIX-
compatible unless you also add some bookkeeping code to keep track
of when chdir() is invoked and what file system locks it is obtaining,
and on exit() UnLock those locks.  Ideally, you should only have to
unlock one lock, since a succession of chdir() calls should automatically
UnLock() the old directory lock if it was obtained from a previous
chdir() Lock() call.

					-Mitsu

page@ulowell.UUCP (04/23/87)

>I can't see how one can implement chdir() to be UNIX-compatible

UNIX chdir doesn't remember the old directory.   Use:

	newdir = Lock(pathname,ACCESS_READ) ;  /* get a lock on the file */
	UnLock(CurrentDir(newdir)) ;           /* change to it, unlock   */
                                               /* the old directory      */

Note you should check to make sure the Lock() succeeded and that 'pathname'
is a directory before you do the Currentdir().

Of course if your application NEEDS to remember the old directory, 
save it yourself.  chdir() shouldn't have to.  It's still a bug in the
Lattice library, however, since they don't UnLock the old directory.

..Bob
-- 
Bob Page, U of Lowell CS Dept.   page@ulowell.{uucp,edu,csnet} 

cmcmanis@sun.uucp (Chuck McManis) (04/24/87)

In article <1212@ulowell.cs.ulowell.edu>, (Bob Page) writes:
> >I can't see how one can implement chdir() to be UNIX-compatible

> UNIX chdir doesn't remember the old directory.   Use:

> 	newdir = Lock(pathname,ACCESS_READ) ;  /* get a lock on the file */
> 	UnLock(CurrentDir(newdir)) ;           /* change to it, unlock   */
>                                                /* the old directory      */
 
> Note you should check to make sure the Lock() succeeded and that 'pathname'
> is a directory before you do the Currentdir().
> ..Bob

Last time I checked the Lattice Startup code a copy of the Lock on the
current directory and then Unlocked it on exit. The end result was that
UnLock(CurrentDir(newdir)); would cause a GURU on exit from the program
when exit() tried to UnLock the directory again. I will check the c.a
code when I get home to verify the exact sequence that causes it to 
fail.


-- 
--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These views are my own and no one elses. They could be yours too, just
call MrgCop() and then ReThinkDisplay()!

gary@mit-eddie.UUCP (04/29/87)

In article <1720@husc6.UUCP> hadeishi@husc7.UUCP (Mitsuharu Hadeishi) writes:
>
>	I've just spent some time tracking down a 24-byte memory leak
>in SlideShow 1.2.  What I realized is that the Lattice chdir() must
>be doing something like the following:
>
>	CurrentDir(Lock(pathname,ACCESS_READ));
>
>	The problem with this is that the lock obtained from Lock() takes
>up 24 bytes and is never freed.  That is, every time I ran my program
>I lost 24 bytes, until I replaced chdir() with
>
>	newdir = Lock(pathname,ACCESS_READ);
>	olddir = CurrentDir(newdir);
>
>	and later, on exit:
>
>	CurrentDir(olddir);
>	UnLock(newdir);
>
>	Now I can't see how one can implement chdir() to be UNIX-
>compatible unless you also add some bookkeeping code to keep track

As long as you don't mind never being able to get back to the dir you
chdired from this will work:

	if ((templock=CurrentDir(Lock(pathname,ACCESS_READ)) != NULL)
	  UnLock(templock);

Don't forget the check for NULL!!!  You can cause latent machine crashes by
UnLocking a NULL lock!

	Gary

[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]
[restriction defeat]

bryce@COGSCI.BERKELEY.EDU (Bryce Nesbitt) (07/31/87)

In article <> jrh4373@tamvenus Joel << Hatchet >> Hall typed:
>
> A lot of you have responded to try UnLock.  I neglected to mention that I
> had already tried this.  The exact sequence is this:
>
>  0. starting in the directory 'original_dir'
>  1. lock = CreateDir("temp")
>  2. unlock(lock)
>  3. chdir("temp")
>  4. lock = CreateDir("temp")
>  5. unlock(lock)
>  6. chdir("temp")
>  7. So now I am in 'original_dir/temp/temp'
>  8. chdir("original_dir/temp") /* go back to first created directory */
>  9. DeleteFile("temp")        /* This works fine */
> 10. chdir("original_dir")    /* I am now back at the original directory */
> 11. DeleteFile("temp")      /* This DOES NOT WORK!  Object in use error */


I must first assume that when you say "unlock" you really meant "UnLock".
The functions with the capitalization are direct DOS calls.

Where you say "chdir" you should really be using "CurrentDir".  Now here's
the fun part: It returns a lock.  When you chdir'ed into the temp directory
something opened a lock on it (what havoc if some processes's current
directory was to be deleted!!!).  Now that you are backing out, you need to
free that lock.

In general it is unwise to mix direct DOS calls and C language calls with
wild abandon.  Unless you are clairvoyant, use one *or* the other.  1/2 :-)

If you check free memory before and after running your program you will find
that you are loosing memory.  Probably the amount that a FileLock takes!

Count all your locks, use only one class of calls, examine function returns
for locks, and check for memory loss.

	Hope it helps!

-----
|\ /|  . Ack! (NAK, EOT, SOH)
{o O} . 
( " )	bryce@cogsci.berkeley.EDU -or- ucbvax!cogsci!bryce
  U 	"Aparantly, Uncle Sam is Ma Bell's wife."