Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
129 user(s) are online (90 user(s) are browsing Forums)

Members: 0
Guests: 129

more...

Headlines

 
  Register To Post  

Lock() problem
Supreme Council
Supreme Council


See User information
I'm trying to determine what kind of object a path is by using either

Lock(path,SHARED_LOCK)+ExamineObjectTags(EX_fileLockInput...)

or

ExamineObjectTags(EX_StringNameInput,...)


However neither method is able to access file information for a file that was created as FOpen(.., MODE_NEWFILE) but was never FClosed().

Lock() doesn't even give me a lock.

(IoErr() gives me "object is in use")

Both diropus and workbench however is able to retrieve file information such as protection flags and file size.

I'm assuming that they don't use any of the methods I've tried.


Anyone got a tip for an airtight way to determine what type of object a path points to?

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Not too shy to talk
Not too shy to talk


See User information
@orgin

A file which has just been created by Open or FOpen is exclusively locked and therfore cannot be accessed by anyone else. DirOpus and Workbench do not access the file but its parent directory. The directory entry has already been saved and can be accessed.

So if you Lock() the directory and read all entries with ExNext or ExAll or whatever OS 4 now offers, you'll see the file's properties.

Bye,
Thomas

Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@thomas

Hmm that's cumbersome. Seems ExamineObject() should be updated to allow you to get the same data as ExamineDir() can.

Ohh well, I guess I could do the following if I can't lock the file and the ioerr is not "object not found":

context=IDOS->ObtainDirContectTags(EX_StringNameInput, pathpart, EX_MatchString,filepart,...);

data=IDOS->ExamineDir(context);

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Amigans Defender
Amigans Defender


See User information
@orgin

ExamineFH() can give details on open files. There should be a newer function call that does the same thing as well.

Go to top
Re: Lock() problem
Just can't stay away
Just can't stay away


See User information
@orgin

Quote:
I'm trying to determine what kind of object a path is by using either

Lock(path,SHARED_LOCK)+ExamineObjectTags(EX_fileLockInput...)

or

ExamineObjectTags(EX_StringNameInput,...)
Neither of both can work since they need an additional lock (internally) which isn't possible for files opened with an exclusive mode like MODE_NEWFILE, you have to use IDOS->ExamineObjectTags(EX_FileHandleInput, ...) instead.
Or open the file in shared mode (MODE_READWRITE). Or open it in exclusive mode but change it to shared with IDOS->ChangeMode(CHANGE_FH, file, SHARED_LOCK) after it was opened successfully.

Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@Chris

Nope, you can't get a handle (FOpen) of a file that is FOpened (NEWFILE)by another process that never FClosed() it.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@joerg

Nope, neither of those methods work on a file that was opened as NEWFILE by another process that never closed it.

FOpen() returns 0 regardless of mode used.

Lock() returns 0 regardless of mode used.

Neither method of ExamineObjectTags() works since they require that you either use FOpen()/Lock() first or that is can create its own lock internally.

The only way that seems to work is a ObtainDirContext()+ExamineDir() combo.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
This is what I ended up doing if anyone else needs to do the same thing:

uint32 PathType(STRPTR path)
{
 
uint32 result;
 
STRPTR strptr;
 
char parent[1024];
 
APTR context;
 
 
struct ExamineData *data;
 
 
strptr IDOS->PathPart(path);
 
IUtility->Strlcpy(parent,path,strptr-path+1);
 
 
// @ToDo: Should probably parse EX_MatchString before using it, even without wildcards 
 
context IDOS->ObtainDirContextTags((STRPTR)EX_StringNameInput,parent,
   
EX_MatchString,(STRPTR)IDOS->FilePart(path),
   
TAG_END);
   
 if(
context!=NULL)
 {
  
data IDOS->ExamineDir(context);
  
  if(
data!=NULL)
  {
   if(
EXD_IS_LINK(data))
   {
    if(
EXD_IS_SOFTLINK(data))
    {
     
result PATH_IS_SOFTLINK;
    }
    else
    {
     
result PATH_IS_HARDLINK;
    }
   }
   else
   {
    if(
EXD_IS_FILE(data))
    {
     
result PATH_IS_FILE;
    }
    else if(
EXD_IS_DIRECTORY(data))
    {
     
result PATH_IS_DIRECTORY;
    }
    else
    {
     
result PATH_IS_UNKNOWN;
    }
   }
   
IDOS->FreeDosObject(DOS_EXAMINEDATA,data);
  }
  else 
// can't obtain examinedata for path
  
{
  
result PATH_NON_EXISTANT;
  }
 
  
IDOS->ReleaseDirContext(context);
 }
 else 
// No context on parent
 
{
  
result PATH_NON_EXISTANT;
 }
 
 return 
result;
}

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@orgin

You cannot second Lock() and exclusive lock.

If you read the docs for ExamineObject() you will
see that passing a string name implies a Lock().
That's why it fails.

If you already have the exclusive lock, just call
ExamineObject() with EX_FileLockInput, that will
work on exclusive locks as it is passed to the filesystem directly.

If you want to know the parent directory of the exclusive lock, then call ParentDir() of the exclusive lock,
and don't forget to unlock what ParentDir() returns.

Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@orgin
// @ToDo: Should probably parse EX_MatchString before using it, even without wildcards


I'll say, it will blow up in your face later if you don't.

Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@colinw

PS:
The EX_FileHandleInput also works the same way as locks
when using Examineobject().

Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@colinw

If you look carefully you'll notice that I was asking for an air tight way of solving the problem. I was not asking what creates a lock or not, that information is available in the autodocs.

Anyway, the ObtainDirContextTags()+ExamineDir() combo works, I just wanted to know if there was a better way to solve the problem since it's not very elegant. Way too many calls, buffers and parsing for what should be a simple task. But i guess there isn't one (yet, nudge nudge).

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@orgin

The issue is that an exclusive lock implies that it is exclusive, and that means no-one else is allowed to futz-around with it.

The best you can do is get a listing of it with a directory scan of the parent directory if you do not have access to the original lock itself.

The filesystem is serious about exclusivity, and if it's not your lock, you're out of luck trying to force access from another client.

The fact that you have limited access to these is by design and not actually a fault.

BTW:
You really should first attempt a normal ExamineObject() with the string name before falling through to this fallback
method of scanning this entire directory, only if you hit a ERROR_OBJECT_IN_USE error, it will be a hell of a lot faster.

Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@colinw

True, here's what I use now in case someone else wants to do similar stuff.

/*
** Check if a path exists and what type it is. 
** PATH_NON_EXISTANT
** PATH_IS_SOFTLINK
** PATH_IS_HARDLINK
** PATH_IS_FILE
** PATH_IS_DIRECTORY
** PATH_IS_UNKNOWN
** Passing null is ok
*/
uint32 PathType(STRPTR path)
{
    
uint32 result;
    
struct ExamineData *data;
    
    if(
path==NULL)
    {
        
result PATH_NON_EXISTANT;
    }
    else
    {
        
data IDOS->ExamineObjectTags(EX_StringNameInputpathTAG_END);
        if(
data!=NULL)
        {
            
result ExaminePathType(data);
            
IDOS->FreeDosObject(DOS_EXAMINEDATA,data);
        }
        else 
        {
            
int32 ioerr IDOS->IoErr();
        
            if(
ioerr==ERROR_OBJECT_IN_USE)
            { 
// Fallback to expensive examinedir function
                
result PathTypeFallback(path);
            }
            else
            {
                
result PATH_NON_EXISTANT;
            }
        }
    }
    
    return 
result;
}

/*
** Local function, expensive ObtainDirContext()+ExamineDir() combo used if 
** the requested path is in use and cannot be locked
*/
uint32 PathTypeFallback(STRPTR path)
{
    
uint32 result;
    
STRPTR strptr;
    
char parent[1024];
    
char parsed[2050];
    
APTR context;
    
struct ExamineData *data;
    
    
strptr IDOS->PathPart(path);
    
IUtility->Strlcpy(parent,path,strptr-path+1);
    
    
// It's crap that I have to parse a pattern for this simple function.
    // Why can't DOS just have a simple ExaminePath() function that doesn't use locks?
    
IDOS->ParsePatternNoCase((STRPTR)IDOS->FilePart(path), parsed2050);
    
context IDOS->ObtainDirContextTags((STRPTR)EX_StringNameInput,parent,
        
EX_MatchString,parsed,
        
TAG_END);
            
    if(
context!=NULL)
    {
        
data IDOS->ExamineDir(context);
        
        if(
data!=NULL)
        {
            
result ExaminePathType(data);
            
// No need to free ExamineData here, ReleaseDirContext does that for you
        
}
        else 
// can't obtain examinedata for path
        
{
            
result PATH_NON_EXISTANT;
        }
    
        
IDOS->ReleaseDirContext(context);
    }
    else 
// No context on parent
    
{
        
result PATH_NON_EXISTANT;
    }
    
    return 
result;
}


/*
** Check if a path exists and what type it is
** PATH_NON_EXISTANT
** PATH_IS_SOFTLINK
** PATH_IS_HARDLINK
** PATH_IS_FILE
** PATH_IS_DIRECTORY
** PATH_IS_UNKNOWN
** You must free the ExamineData yourself, passing NULL is ok
*/
uint32 ExaminePathType(struct ExamineData *data)
{
    
uint32 result;
    
    if(
data==NULL)
    {
        
result PATH_NON_EXISTANT;
    }
    else
    {
        if(
EXD_IS_LINK(data))
        {
            if(
EXD_IS_SOFTLINK(data))
            {
                
result PATH_IS_SOFTLINK;
            }
            else
            {
                
result PATH_IS_HARDLINK;
            }
        }
        else
        {
            if(
EXD_IS_FILE(data))
            {
                
result PATH_IS_FILE;
            }
            else if(
EXD_IS_DIRECTORY(data))
            {
                
result PATH_IS_DIRECTORY;
            }
            else
            {
                
result PATH_IS_UNKNOWN;
            }
        }
    }
    
    return 
result;
}


Edited by orgin on 2009/3/15 16:45:32
Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@orgin

Just spotted something.....

The FreeDosObject() of the data block from ExamineDir()
is not appropriate in your PathTypeFallback() function.

The data blocks are allocated from a memory pool and
stored in the internal list and the whole lot is freed
when you call ReleaseDirContext().

However, as you are not looping here, you'd probably never
know anything was up.

Because ExamineDir() uses a memory pool and can reuse
the nodes on subsequent calls, if you were looping,
you'd likely be visited by the reaper for putting
it back into the pool but leaving it still in the list
without calling IExec->Remove() first.
However, seeing you only call ExamineDir() once, you got away with it.


Only ExamineObject() requires you free the data blocks individually when you're done with it.


I've just updated the autodocs to make this point much clearer.

Go to top
Re: Lock() problem
Supreme Council
Supreme Council


See User information
@colinw

Example updated.

Btw on the topic of things in the autodoc, in dos.doc there is a code example that says:

if( EXD_IS_SOFTLINK(dat) )
 {
    
linkedobj=IDOS->ExamineObject(EX_StringNameInput,dat->Link,TAG_END);
     ....
    
/* Use linkedobj data then free it. -  See; ExamineObject() */
     
    
IExec->FreeDosObject(DOS_EXAMINEDATAlinkedobj);
 }


(IExec?)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Lock() problem
Just popping in
Just popping in


See User information
@orgin

Oops !! - Fixed now.

Hmmm, why it took all this time for someone to spot that one. (":/

Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project