[comp.sys.amiga.tech] locks

jdp@killer.DALLAS.TX.US (Jim Pritchett) (10/31/88)

     Many thanks to all who tried to help me get the program working!  There
were TWO major blunders in my code.  Rob Peck explained to me the errors in
the Dos documentation on locks.  Phil Staub found a really stealthy bug in my
AllocMem call.  So, many thanks to Rob and Phil!!!  Thanks also to the others
who tried to help via Email or this newsgroup.  Here is a listing of the
revised and working (at least so far) program:

#include <stdio.h>

main()

{
  char cd[108];

  getcwd(cd, 108);
}

# include <functions.h>
# include <exec/types.h>
# include <exec/memory.h>
# include <libraries/dosextens.h>

getcwd(cd, length)
  char *cd;
  int length;

{
  char name[108];
  struct FileLock *lockcd, *lockram, *lockram2;
  struct FileInfoBlock *fib;
  short success;
 
  lockram = Lock("ram:t", ACCESS_READ);
  lockcd = CurrentDir(lockram);
  UnLock(lockram);

/* don't UnLock() anything except Lock() and DupLock()ed files - Thanks Rob!! */

  fib = AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);

/* Super Stealthy bug was here.  This line was:                               */
/*                                                                            */
/* fib = AllocMem((long)sizeof(fib), 1L)                                      */
/*                                                                            */
/* which allocates space for a pointer ONLY!!!  NOT enough for FileInfoBlock. */
/*                                                                            */
/* So, the Super Bug Sleuth Award goes to Phil Staub for finding this one!!!  */
/*                                                                            */

  success = Examine(lockcd, fib);
  strcpy(name, fib->fib_FileName);

printf("  %s\n", name);

  lockram2 = CurrentDir(lockcd);
  FreeMem(fib, (long)sizeof(struct FileInfoBlock));

}

     Now, I need to add some error checking...

     I have another question, though.  Several people wrote me that I should
have declared my lock pointers as 'ULONG.'  This implies to me that I may be
dealing with the infamous BPTRs here.  If so, wouldn't it be more appropriate
to declare them as BPTR rather that ULONG (yes, I realize that there is no
difference in the end result.)  Is there a simple rule I can use to tell
whether I should use an APTR or a BPTR?  Do all Dos functions use BPTRs?
What else does?  The code as written seems to work, but am I setting myself
up for problems later?  Why doesn't any of my documentation mention any of
this?  (I have the white Dos manuals, the 1.2 includes, the Mortimore book,
the Berry book, and of course, the Aztec C manuals.)

     Well, I ended up with more questions than I started with.  However,
thanks to you (the net), I am making progress.

                            Thanks,
                                     Jim Pritchett

                            UUCP:  (backbone)!killer!gtmvax!dms3b1!caleb!jdp

jdp@caleb.UUCP (Jim Pritchett) (04/24/89)

     Recently someone mentioned a program (PD) that lists all locks currently
outstanding.  Could someone please Email me a copy of this program (preferably
with source, if possible.)

                                    Thanks,


--

                                         Jim Pritchett

                                         UUCP:  killer!gtmvax!dms3b1!caleb!jdp

cmcmanis%pepper@Sun.COM (Chuck McManis) (04/27/89)

In article <0797.AA0797@caleb> jdp@caleb.UUCP (Jim Pritchett) writes:
>     Recently someone mentioned a program (PD) that lists all locks currently
>outstanding.  Could someone please Email me a copy of this program (preferably
>with source, if possible.)

I wrote one that is pretty short. It's included below ...
--Chuck

/*
 *	showlocks.c
 *
 * Written 13-Mar-88 by Chuck McManis
 * Copyright 1988 Charles McManis, All rights reserved. 
 * This file may be freely redistributed and used as long as this notice remains
 * with it.
 *
 * This program will list out all of the locks that are being held on the 
 * specified volume. You can enter either a volume name or disk device.
 *
 * The output of this program is :
 *	Lock #0 : 'Path'
 *	Lock #1 : 'Path'
 *	...
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

extern struct DosLibrary *DOSBase;
char	*GetPath();

void
main(argc,argv)

int	argc;
char	*argv[];

{
  int			i;		/* File counter			*/
  struct FileLock	*fl;
  ULONG			thislock;


  if (argc != 2) {
    printf("Usage is : ShowLocks Volumename:\n");
    exit(0);
  }

  printf("Lock Monitor, prints out outstanding locks on a given volume.\n");
  thislock = Lock(argv[1]);
  i = 0;
  for (fl = (struct FileLock *)(BADDR(thislock)); fl;
       fl = (struct FileLock *)(BADDR(fl->fl_Link))) 
      printf("    Lock #%d : '%s'\n",i++,GetPath((ULONG)(fl) >> 2));
  if (thislock) UnLock(thislock);
}


/*
 * Function GetPath()
 *
 * This function will return a pointer to a string with the path of
 * the passed lock.
 */
char *
GetPath(Lck)

ULONG	Lck;

{

  static char	LockPath[256];
  UWORD		FDATA[sizeof(struct FileInfoBlock)/2+1];
  ULONG		CurLock,NewLock;
  char		*s;
  struct FileInfoBlock	*fi;


  /* Initialize LockPath to the NULL string */
  LockPath[0]  = '\0';
  if ((Lck == 0) || (Lck == ~0L))
    return(LockPath); /* If Lock is on root (0) return */

  /* Initialize fi so that it is on a long word boundary */
  if ((long)(FDATA) & 2) fi = (struct FileInfoBlock *)(&FDATA[1]);
  else fi = (struct FileInfoBlock *)FDATA;

  CurLock = DupLock(Lck); /* Make a copy of the Lock passed */
  while (CurLock != NULL) {
    Examine(CurLock,fi);
    if ((CurLock != 0) && (fi->fib_DiskKey != 0)) {
      if (strlen(LockPath)) strins(LockPath,"/");
      strins(LockPath,fi->fib_FileName);
    }
    NewLock = ParentDir(CurLock);
    UnLock(CurLock);
    CurLock = NewLock;
  }
  /* Fix up the volume name to include a colon */
  for (s = LockPath; *s; s++) if (*s == '/') {*s = ':'; break;}
  if (!(*s)) strcat(LockPath,":"); 
  return(LockPath);
}

--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.
"A most excellent barbarian ... Genghis Kahn!"

cmcmanis%pepper@Sun.COM (Chuck McManis) (04/27/89)

Oh, and strins(s1,s2) [used in the showlocks program] is simply a Lattice
routine that prepends the string s2 onto the string s1. Sort of the inverse
to strcat().

--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.
"A most excellent barbarian ... Genghis Kahn!"