[comp.sys.amiga.tech] CurrentDir

bader+@andrew.cmu.edu (Miles Bader) (11/02/88)

Who's current directory does the the CurrentDir call change?  Only
the current process?

-Miles

david@starsoft.UUCP (Dave Lowrey) (03/16/90)

Reading in Rob Peck's "Programmer's Guide to the Amiga" about
the CurrentDir function, he says the proper sequence to use is:

   mylock = Lock("df0:c", ACCESS_READ);
   oldlock = CurrentDir(mylock);

Now, he also says that I shouldn't free any locks that are returned
by CurrentDir, only ones I obtained by Lock.

I understand this so far. However, is it legal to add the following
line immediately AFTER the CurrentDir call:

   Unlock(mylock);

Would this pull the rug out from under DOS, or does it get it's own
lock on the current directory?

The reason i'm asking this is that I am trying to simulate a UNIX
"chdir()" system call. I don't want to have to figure out a way to
free up all of the locks at the end of my program, if I don't have
to.

Thanks!

Dave (I need a DOS programmer's manual BAD!) Lowrey




--
----------------------------------------------------------------------------
These words be mine. The company doesn't care, because I am the company! :-)

      Dave Lowrey	 |  In Texas: {uhnix1,moray}!starsoft!david
Starbound Software Group | The World: dwl10@uts.amdahl.com (amdahl!dwl10)
      Houston, TX	 |

cmcmanis@stpeter.Sun.COM (Chuck McManis) (03/19/90)

[Lock question, included below]

The answer is, you are responsible for freeing any Locks that
you have aquired. So if you use a "lock creating" call such as
Lock() or ParentDir() then you will have to free the lock that
was returned. You are forbidden from freeing locks that you
didn't create. And in the case of CurrentDir it returns you a
stashed lock and puts yours in the stash. Bad news if you free
the one you got back from CurrentDir because you didn't create
it, and even worse news if you free the one that is currently 
in the stash. To build a chdir() system call your startup code
should really have 
	oldlock = CurrentDir(0);
	mylock = DupLock(oldlock);
	(void) CurrentDir(mylock);
	...
/* Now you own all of the locks in your process */
/* Then in _exit() */
	...
	loch = CurrentDir(oldlock); /* put the old one back */
	if (loch)
		UnLock(loch);
	...
What this does is save the current directory lock away that you
didn't create in a safe place, and put in it's place a lock that
you did create so your application can free if it chooses and the
chdir call can be coded as :
chdir(dir)
	char	*dir;
{
	ULONG	lck;
	ULONG	olck;

	lck = Lock(dir, ACCESS_READ);
	if (lck) {
		olck = CurrentDir(lck);
		if (olck)
			UnLock(olck);
	} else {
		errno = NOSUCHDIR;
		return -1;
	}
	return 0;
}

And you will be assured that you won't ever unlock a lock you don't
own.


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

-------------Included Question-------------

In article <00173.AA00173@starsoft.UUCP> (Dave Lowrey) writes:
>Reading in Rob Peck's "Programmer's Guide to the Amiga" about
>the CurrentDir function, he says the proper sequence to use is:
>
>   mylock = Lock("df0:c", ACCESS_READ);
>   oldlock = CurrentDir(mylock);
>
>Now, he also says that I shouldn't free any locks that are returned
>by CurrentDir, only ones I obtained by Lock.
>
>I understand this so far. However, is it legal to add the following
>line immediately AFTER the CurrentDir call:
>
>   Unlock(mylock);
>
>Would this pull the rug out from under DOS, or does it get it's own
>lock on the current directory?
>
>The reason i'm asking this is that I am trying to simulate a UNIX
>"chdir()" system call. I don't want to have to figure out a way to
>free up all of the locks at the end of my program, if I don't have
>to.

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  Internet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.
"If it didn't have bones in it, it wouldn't be crunchy now would it?!"

pds@quintus.UUCP (Peter Schachte) (03/21/90)

In article <133060@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes:
> You are forbidden from freeing locks that you didn't create.

But this leaves the question:  how do you write a program that leaves a
different directory current when it exits?  Is there a way not to waste
the few bytes occupied by the old lock?  How would you write CD?
-- 
-Peter Schachte
pds@quintus.uucp
...!sun!quintus!pds

justus@tko-sony-15.hut.fi (Juhana R{s{nen) (03/21/90)

In article <1332@quintus.UUCP> pds@quintus.UUCP (Peter Schachte) writes:
>In article <133060@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes:
>> You are forbidden from freeing locks that you didn't create.
>
>But this leaves the question:  how do you write a program that leaves a
>different directory current when it exits?  Is there a way not to waste
>the few bytes occupied by the old lock?  How would you write CD?

I did... I wrote a CD replacement that combines CD and unix pushd/popd
commands. I simply free the lock I got from CurrentDir, no matter what the
wise men say. The program works fine, doesn't crash, doesn't junk memory,
the only problem is that I wrote it as I shouldn't have.

>-Peter Schachte
>pds@quintus.uucp
>....!sun!quintus!pds

	Juhana R{s{nen / justus@niksula.hut.fi

cmcmanis@stpeter.Sun.COM (Chuck McManis) (03/23/90)

An amendment to the rule of "Don't unlock locks you don't own" is 
required. 

The problem that most people run into with CurrentDir() and locks
is that *Workbench* Caches the current directory lock and then 
Unlocks it when your application exits. If you change directories
by exchanging locks with CurrentDir and Unlock the one you got
back, when Workbench goes to Unlock it you will be hosed. So
the Amended rule is :

	Don't Unlock locks you don't own. If you swap locks with
	CurrentDir then the lock you gave away is no longer yours
	but the lock you got is so you can unlock it. However, if
	you are started from workbench, preserve the original
	current directory lock and return it before returning to
	workbench. (At least until they fix the bug in Workbench)


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: <none>   Internet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.
"If it didn't have bones in it, it wouldn't be crunchy now would it?!"

p554mve@mpirbn.UUCP (Michael van Elst) (03/23/90)

In article <133343@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes:
>The problem that most people run into with CurrentDir() and locks
>is that *Workbench* Caches the current directory lock and then 
>Unlocks it when your application exits.

Actually, the current directory lock is cached in the workbench startup
message. If you change this lock (or Unlock or...) you have to change
the BPTR to it in your startup message too.

Michael van Elst
p554mve@mpirbn.mpifr-bonn.mpg.de

riley@batcomputer.tn.cornell.edu (Daniel S. Riley) (03/24/90)

In article <133343@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes:
>The problem that most people run into with CurrentDir() and locks
>is that *Workbench* Caches the current directory lock and then 
>Unlocks it when your application exits. If you change directories
>by exchanging locks with CurrentDir and Unlock the one you got
>back, when Workbench goes to Unlock it you will be hosed.

Workbench doesn't exactly cache the current directory--it sends it to you
in the startup message.  The workbench startup message includes directory
locks on the directories containing the tool and any projects selected, 
and one of those (depending on how the you started the tool) will be the
same directory lock as the process current directory.  When your process
replies to the startup message (when it exits), workbench cleans up all
the locks in the startup message.  If you've already UnLock()ed any of
those locks, bad things happen.

In practice it works out to the same thing, and Chuck's rule still applies.

-Dan Riley (riley@tcgould.tn.cornell.edu, cornell!batcomputer!riley)
-Wilson Lab, Cornell University

new@udel.edu (Darren New) (03/24/90)

In article <9965@batcomputer.tn.cornell.edu> riley@tcgould.tn.cornell.edu (Daniel S. Riley) writes:
>[...]  When your process
>replies to the startup message (when it exits), workbench cleans up all
>the locks in the startup message.  If you've already UnLock()ed any of
>those locks, bad things happen.

Empirically, I have found a way around this.  I needed to be able to
close all the locks I had open so that I could pull the disk without
WB leaving the icon up.  At least under 1.3 and 1.3.2, it seems safe
to ZERO the lock field in the startup message for any lock
you unlock yourself. Then WB will not try to re-unlock it.
	      -- Darren

p554mve@mpirbn.UUCP (Michael van Elst) (03/25/90)

In article <14801@nigel.udel.EDU> new@udel.edu (Darren New) writes:
>...  At least under 1.3 and 1.3.2, it seems safe
>to ZERO the lock field in the startup message for any lock
>you unlock yourself. Then WB will not try to re-unlock it.
>	      -- Darren

Actually, WB even frees the zeroed Lock. Fortunately, this operation
is allowed by AmigaDOS since it uses the zero Lock as a pointer to
the boot device.

Michael van Elst
p554mve@mpirbn.mpifr-bonn.mpg.de

252u3130@fergvax.unl.edu (Phil Dietz) (10/11/90)

I'm using Lattice 'C' and I'm changing the current directory in it.
Well, when the program quits, the SHELL path and the current directory
are off.  I need to find out what the command is to read the name
of the current directory so I can chdir to it at the end of the program.

Unfortunately none of my books has it in it!  Jeesh, The
includes&autodocs, the Libraries&devices, and the Abacus 'C' books
should talk at least a LITTLE bit about AmigaDOS....
 
Phil Dietz


<<<=================--------- Cheap Ad ---------===================<<<
Phil Dietz                       SWL Lincoln    550 MEGS! 2 lines
252u3130@fergvax.unl.edu         (402)421-1963  IBM, GIFS, MAC, AMIGA

rbabel@babylon.UUCP (Ralph Babel) (10/11/90)

In article <1990Oct11.012013.24234@hoss.unl.edu>
252u3130@fergvax.unl.edu (Phil Dietz) writes:

> I'm using Lattice 'C' and I'm changing the current
> directory in it. Well, when the program quits, the SHELL
> path and the current directory are off.  I need to find
> out what the command is to read the name of the current
> directory so I can chdir to it at the end of the program.

Except for built-in shell commands (e.g. CD), no-one is
allowed to change the current directory permanently: The
pr_CurrentDir field of the process structure must be the
same on exit() as it was on main(), i.e. it must not only
refer to the same directory, but it must also be the _same_
lock, not just a copy of it! (As far as I remember, this is
also true for Workbench processes.)

The easiest way to achieve this, would be:

main()
 {
 BPTR orig_cd, cd;

 if(cd = Lock("", ACCESS_READ))
  {
  orig_cd = CurrentDir(cd);

  /* now you can chdir() as often as you like */

  UnLock(CurrentDir(orig_cd));
  }
 }

True, this _should_ be done by the compiler's startup-code.

Ralph

ken@cbmvax.commodore.com (Ken Farinsky - CATS) (10/11/90)

In article <1990Oct11.012013.24234@hoss.unl.edu> 252u3130@fergvax.unl.edu writes:
> I'm using Lattice 'C' and I'm changing the current directory in it.
> Well, when the program quits, the SHELL path and the current directory
> are off.  I need to find out what the command is to read the name
> of the current directory so I can chdir to it at the end of the program.

This should do it.  Randell will pipe in if I got it wrong...   ;-)

/* get a lock on the desired directory. */
if (0 != (lock = Lock(name,accessMode)))
    oldLock = CurrentDir(lock);     /* change current dir */

/* run program given new current dir.
** the program will run here if it cannot get the lock,
** but it will be run from the (potentially) wrong dir.
*/
runProgram();

if (0 != lock) /* only change back and unlock if we got it. */
    {
    CurrentDir(oldLock);   /* change back to original dir */
    UnLock(lock);
    }

-- 
--
Ken Farinsky - CATS - (215) 431-9421 - Commodore Business Machines
uucp: ken@cbmvax.commodore.com   or  ...{uunet,rutgers}!cbmvax!ken
bix:  kfarinsky

bj@cbmvax.commodore.com (Brian Jackson) (10/12/90)

In article <1990Oct11.012013.24234@hoss.unl.edu> 252u3130@fergvax.unl.edu (Phil Dietz) writes:
>I'm using Lattice 'C' and I'm changing the current directory in it.
>Well, when the program quits, the SHELL path and the current directory
>are off.  I need to find out what the command is to read the name
>of the current directory so I can chdir to it at the end of the program.
>

You don't say what version of Lattice you are using. The getcd() call
is what you want.

>Phil Dietz

bj

 ----------------------------------------------------------------------- 
 | Brian Jackson  Software Engineer @ Commodore-Amiga Inc.  GEnie: B.J. |
 | bj@cbmvax.commodore.com    or  ...{uunet|rutgers}!cbmvax!bj          |
 | "Caught in the vice of heaven and earth,                             |
 |   he turned his life into a cell"                                    |
 -----------------------------------------------------------------------