Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
142 user(s) are online (78 user(s) are browsing Forums)

Members: 0
Guests: 142

more...

Headlines

 
  Register To Post  

[Solved] Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
How do you subscribe to changes in the file system?

Such as if files are deleted or added from a specific folder.


Edited by orgin on 2009/3/22 10:42:56
Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@orgin

I suppose I must do something like this:

FSMsgPort IExec->CreateMsgPort();

if(
FSMsgPort)
{
 
APTR ptr IDOS->AllocDocObjectTagListTags(DOS_NOTIFYREQUEST,
    
ADO_NotifyName, (STRPTR)"my:path"
    
ADO_NotifyMethodNRF_SEND_MESSAGE,
    
ADO_NotifyPortMyPort,
    
TAG_DONE);

 
IDOS->StartNotify(ptr);

 
struct Message *msg;

 
//event loop 
 
while( (msg IExec->GetMsg(FSMsgPort)) ) 
 {
  
msgtype = ????;
  
msgid = ????;
  
msgdata = ????;

  switch(
msgtype)
  {
   case 
yyyy:
    
// react to yyyy
    
break;
   case 
zzzz:
    
// react to zzzz
  
}
 }

 
IDOS->EndNotify(ptr);

 
IDOS->FreeDosObject(DOS_NOTIFYREQUEST);
 
IExec->deleteMsgPort(FSMsgPort);
}


(Didn't add all error checking or the example would grow into gigantic proportions)

How do I obtain msgtype/msgid and msgdata?

What types of messages is there? (yyyy/zzzz)


Edited by orgin on 2009/3/21 7:25:07
Edited by orgin on 2009/3/21 8:09:00
Edited by orgin on 2009/3/21 8:32:21
Edited by orgin on 2009/3/21 8:32:35
Edited by orgin on 2009/3/21 8:45:45
Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Not too shy to talk
Not too shy to talk


See User information

Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@thomas

I've already read the autodocs.

The autodocs does not have any information on how to deal with "NRF_SEND_MESSAGE" notifications, it just states that you can use it.

The example you supplied seems to be using "NRF_SEND_SIGNAL".




Or are you saying that all I need to do is to receive the message (msg = IExec->GetMsg(FSMsgPort))) , and if I do I can assume that the entry is updated and that the message does not provide any more information than that? How do I obtain ADO_NotifyUserData ?

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Not too shy to talk
Not too shy to talk


See User information
@orgin

Why is it so difficult to read the *entire* description ?

If you requested that messages should be sentvia the
    NRF_SEND_MESSAGE method
the MsgPort pointed to by the
    NotifyRequest
->nr_stuff.nr_Msg.nr_Port field will receive
    a NotifyMessage
The following message fields are of
    interest
:

        
NotifyMessage->nm_Class
            This is set to the value NOTIFY_CLASS
.

        
NotifyMessage->nm_Code
            This is set to the value NOTIFY_CODE
.

        
NotifyMessage->nm_NReq
            This points back to the NotifyRequest which caused
            the NotifyMessage to be sent
.

    
Note that you must return this message when you no longer need
    it
Specificallyall NotifyMessages must be returned before you
    can safely end the notification process by calling EndNotify
().



And the include file (dos/notify.h) for additional information:

/* --- NotifyMessage Class ------------------------------------------------ */
#define NOTIFY_CLASS    0x40000000

/* --- NotifyMessage Codes ------------------------------------------------ */
#define NOTIFY_CODE     0x1234

/* Sent to the application if SEND_MESSAGE is specified. */
struct NotifyMessage
{
    
struct Message 
              nm_ExecMessage
;
    
ULONG     nm_Class;
    
UWORD     nm_Code;
    
struct NotifyRequest *
              
nm_NReq;          /* don't modify the request! */
    
ULONG     nm_DoNotTouch;    /* like it says! For use by handlers */
    
ULONG     nm_DoNotTouch2;   /* ditto */
};


You can get the user data from NotifyMessage->nm_NReq->nr_UserData.

Bye,
Thomas

Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@thomas

I've read both of them (been reading the autodocs back and forth for 4 hours now, including tons of examples and include files) .

And that info doesn't help me one bit on the way no matter how many times I read it.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@thomas

These are the questions that that info spawns:

Am I supposed to use the ((struct NotifyRequest *)ptr)->nr_stuff.nr_Msg.nr_Port instead of the supplied port to receive messages? (why then supply a port to AllocDocObjectTagListTags() if it's supplying me with a new port anyway?)

How do I query the message port for something else than struct Message * ? (IExec->GetMsg() returns struct Message *, not struct NotifyMessage* or can you safely typecast it)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@thomas

Is this on the right track?

struct MsgPort *FSMsgPort IExec->CreateMsgPort(); // Not really used?
 
struct MsgPort *NMsgPort;

 if(
FSMsgPort!=0)
 {
  
APTR ptr IDOS->AllocDocObjectTagListTags(DOS_NOTIFYREQUEST,
    
ADO_NotifyName, (STRPTR)"my:path"
    
ADO_NotifyMethodNRF_SEND_MESSAGE,
    
ADO_NotifyPortMyPort,
    
ADO_NotifyUserDatamyuserdata,
    
TAG_DONE);

  if(
ptr!=0)
  {
   
NMsgPort = ((struct NotifyRequest *)ptr)->nr_stuff.nr_Msg.nr_Port;
   
   if(
NMsgPort!=0)
   {
    if(
IDOS->StartNotify(ptr))
    {
     
struct NotifyMessage *msg;

     
//event loop 
     
while( (msg = (struct NotifyMessage *)IExec->GetMsg(NMsgPort)) ) 
     {
      
mydata msg->nm_NReq->nr_UserData;

      
// Act on message

      
IExec->ReplyMsg(msg);
     }
     
IDOS->EndNotify(ptr);
    }
   }
   
IDOS->FreeDosObject(DOS_NOTIFYREQUEST);
  }
  
IExec->deleteMsgPort(FSMsgPort);
 }

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Just popping in
Just popping in


See User information
@orgin

Quote:
Am I supposed to use the ((struct NotifyRequest *)ptr)->nr_stuff.nr_Msg.nr_Port instead of the supplied port to receive messages? (why then supply a port to AllocDosObjectTags() if it's supplying me with a new port anyway?)


As I understand it, it's the "same" port you supply with AllocDosObjectTags().


Quote:
How do I query the message port for something else than struct Message * ? (IExec->GetMsg() returns struct Message *, not struct NotifyMessage* or can you safely typecast it)


If you use the Port only for your filenotification it should be save to typecast it, or not?

FSMsgPort IExec->CreateMsgPort();

if(
FSMsgPort)
{
  
ULONG notify_mask 1UL << FSMsgPort->mp_SigBit;
  
APTR ptr IDOS->AllocDosObjectTags(DOS_NOTIFYREQUEST,
                                      
ADO_NotifyName, (STRPTR)"my:path"
                                      
ADO_NotifyMethodNRF_SEND_MESSAGE,
                                      
ADO_NotifyPortFSMsgPort,
                                      
ADO_NotifyUserDatamyuserdata,
                                      
TAG_DONE);

  if (
ptr)
  {
    if (
IDOS->StartNotify(ptr))
    {
      
ULONG signals;
      
BOOL done FALSE;
      
struct NotifyMessage *msg;

      do
      {
        
signals IExec->Wait(SIGBREAKF_CTRL_C notify_mask)

        if (
signals notify_mask)
        {
          while( (
msg = (struct NotifyMessage *)IExec->GetMsg(FSMsgPort)) ) 
          {
            if (
msg->nm_Class == NOTIFY_CLASS && msg->nm_Code == NOTIFY_CODE)
            {
              
/* do something */
              // msg->nm_NReq->nr_Name
              // msg->nm_NReq->nr_UserData
            
}
            
IExec->ReplyMsg((struct Message *)msg);
          }
        }

        if (
signals SIGBREAKF_CTRL_Cdone TRUE;
      }
      while( !
done );

      
IDOS->EndNotify(ptr);
    }
    
IDOS->FreeDosObject(DOS_NOTIFYREQUESTptr);
  }
  
IExec->DeleteMsgPort(FSMsgPort);
}

Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@Gazelle

Okey thank you for your reply. I will see how far I get with it.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Just popping in
Just popping in


See User information
@orgin
Here's the source code for a test program I used for the DOS notify handler.
It's a bit messy, but i'm too-lazy to tidy it up.
Compile it as is (with -nostdlib) and you will see all three methods at work.

Start it from a shell with one argument that is the path to the filesystem object to be monitored.

=====================================================



#define __NOLIBBASE__
#define __NOGLOBALIFACE__
#include <proto/exec.h>
#include <proto/dos.h>

#include <dos/startup.h>

/****************************************************************************/ 

struct CustomHook 
{
 
struct Hook       H;  /* must be first */
 
struct ExecIFace *IExec;
 
struct DOSIFace  *IDOS;
 
BPTR              Output;
 
ULONG             Line;
};

TEXT *actions[] = 
{
 
"NHM_ACTION_INITIAL",
 
"NHM_ACTION_ADD",
 
"NHM_ACTION_CHANGE",
 
"NHM_ACTION_DELETE",
 
NULL
};

/****************************************************************************/

STATIC LONG HookFuncstruct CustomHook *hookAPTR resv UNUSEDstruct NotifyHookMsg *msg )
{
 
LONG indx msg->nhm_Action;

 
indx ++;  /* starts at -1 */
 
indx &= 3;
 
 
hook->IDOS->FPrintf(hook->Output,"%04lu HOOK Ping; '%s'  [%s]\n"
     
hook->Line++, msg->nhm_Nameactions[indx]);

 return(
0);
}

/****************************************************************************/

STATIC LONG mmainstruct ExecIFace *IExecstruct DOSIFace IDOS )
{    
 
TEXT namebuf[256];
 
struct NotifyRequest *nr_hook NULL;
 
struct NotifyRequest *nr_sig NULL;
 
struct NotifyRequest *nr_msg NULL;
 
struct MsgPort *mport NULL;
 
struct CustomHook HK;
 
LONG   numnotify =0;
 
LONG   ok 0;
 
STRPTR args;


 
IDOS->ReadItem(namebuf,sizeof(namebuf),NULL);
 
args namebuf;

 
 if( *
args <= 32 )
 {
  
args "RAM:";
 }
 
 if( 
'?' == *args )
 {
  
IDOS->PutStr("USAGE:    Notify  <file/directory> \nIf not specified, defaults to RAM:\n\n");
  return(
RETURN_FAIL);
 }







/***************  HOOK  **************/
 
HK.H.h_Entry = (APTR) &HookFunc;
 
HK.IExec     IExec;
 
HK.IDOS      IDOS;
 
HK.Output    IDOS->Output();
 
numnotify  ++;

 
nr_hook IDOS->AllocDosObjectTagsDOS_NOTIFYREQUEST
   
ADO_NotifyNameargs,
   
ADO_NotifyMethodNRF_CALL_HOOK,
   
ADO_DOSMethodOnly,TRUE,
   
ADO_NotifyInitialTRUE,
   
ADO_NotifyHook, &HK,
   
TAG_DONE );

 if( 
nr_hook )
 {
    if( 
IDOS->StartNotifynr_hook ) )
  {
//   IDOS->Printf("DOS HOOK Notification started for '%s' as '%s'\n", nr_hook->nr_Name, nr_hook->nr_FullName);
   
ok ++;
  }
  else
  {
   
IDOS->Printf("DOS HOOK Notification FAILED because; %m\n"0);
  }
 }
 else
 {
  
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,HOOK) FAILED because; %m \n",0);
 }





/***************  SIGNAL  **************/
 
numnotify ++;
 
nr_sig IDOS->AllocDosObjectTagsDOS_NOTIFYREQUEST
   
ADO_NotifyNameargs,
   
ADO_NotifyMethodNRF_SEND_SIGNAL,
   
ADO_DOSMethodOnly,TRUE,
   
ADO_NotifyTaskIExec->FindTask(NULL),
   
ADO_NotifySignalNumberSIGBREAKB_CTRL_F,
   
ADO_NotifyInitialTRUE,
   
TAG_DONE );

 if( 
nr_sig )
 {
    if( 
IDOS->StartNotifynr_sig ) )
  {
//   IDOS->Printf("DOS SIGNAL Notification started for '%s' as '%s'\n", nr_sig->nr_Name, nr_sig->nr_FullName);
   
ok ++;
  }
  else
  {
   
IDOS->Printf("DOS SIGNAL Notification FAILED because; %m\n"0);
  }
 }
 else
 {
  
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,SIGNAL) FAILED because; %m \n",0);
 }







/***************  MESSAGE  **************/
 
numnotify ++;
 if(( 
mport IExec->CreateMsgPort() ))
 {

  
nr_msg IDOS->AllocDosObjectTagsDOS_NOTIFYREQUEST
   
ADO_NotifyNameargs,
   
ADO_NotifyMethodNRF_SEND_MESSAGE,
   
ADO_DOSMethodOnly,TRUE,
   
ADO_NotifyPortmport,
   
ADO_NotifyInitialTRUE,
   
TAG_DONE );

  if( 
nr_msg )
  {
     if( 
IDOS->StartNotifynr_msg ) )
   {
//    IDOS->Printf("DOS MESSAGE Notification started for '%s' as '%s'\n", nr_msg->nr_Name, nr_msg->nr_FullName);
    
ok ++;
   }
   else
   {
    
IDOS->Printf("DOS MESSAGE Notification FAILED because; %m\n"0);
   }
  }
  else
  {
   
IDOS->Printf("ADO(DOS_NOTIFYREQUEST,MESSAGE) FAILED because; %m \n",0);
  }

 }



//leave:
 
if( numnotify == ok )
 {
  
ULONG signalportmask=0;
  
struct Message *msg NULL;


  
HK.Line 1;


  
IDOS->PutStr("Ready:  ^C to exit.......\n");

  if( 
mport )
  {
   
portmask 1UL << mport->mp_SigBit;
  }

  do
  {
//   IDOS->PutStr("\n");

   
signal IExec->WaitSIGBREAKF_CTRL_C SIGBREAKF_CTRL_F portmask );


   if( 
signal SIGBREAKF_CTRL_F )
   {
    
IDOS->Printf("%04lu SIGNAL Ping; '%s'\n"HK.Line++, nr_sig->nr_FullName);
   }

   if( 
signal portmask )
   {
    
IDOS->Printf("%04lu MESSAGE Ping; '%s'\n"HK.Line++, nr_sig->nr_FullName);

    while(( 
msg IExec->GetMsg(mport) ))
    {
     
IDOS->PutStr(" -- MESSAGE_REPLIED\n\n");

     
IExec->ReplyMsg(msg);
    }
   }

  }
  while( ! (
signal SIGBREAKF_CTRL_C)); 

  
IDOS->PutStr("\nProgram Exit.....\n\n");
 
 }


 
IDOS->EndNotifynr_hook );
 
IDOS->FreeDosObjectDOS_NOTIFYREQUESTnr_hook );

 
IDOS->EndNotifynr_sig );
 
IDOS->FreeDosObjectDOS_NOTIFYREQUESTnr_sig );

 
IDOS->EndNotifynr_msg );
 
IDOS->FreeDosObjectDOS_NOTIFYREQUESTnr_msg );


 if( 
mport )
 {
  
IExec->DeleteMsgPort(mport);
 }

    return(
RETURN_OK);
}


/****************************************************************************/

LONG _start(STRPTR args UNUSEDLONG arglen UNUSEDstruct ExecBase *SysBase)
{
    
struct ExecIFace *IExec = (struct ExecIFace *)SysBase->MainInterface;
    
struct Library *DOSBase = (struct Library *)IExec->OpenLibrary(DOSNAME50);
    
long rc RETURN_ERROR;

    if (
DOSBase)
    {
        
struct DOSIFace *IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase"main"1NULL);

        if (
IDOS)
        {
            
rc mmain(IExecIDOS);

            
IExec->DropInterface((struct Interface *)IDOS);
        }

        
IExec->CloseLibrary(DOSBase);
    }

    return( 
rc );
}

/****************************************************************************/

TEXT USED vers[] = "\0$VER: It's just a test program, Dammit !!, 52.1 (28.12.2007)\n\r";


/****************************************************************************/
/* EOF */

=====================================================


Edit: Added code tags


Edited by orgin on 2009/3/21 17:35:34
Edited by colinw on 2009/3/22 12:35:29
Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@colinw&Gazelle

I've added notifications to my app now and it works fine. Thanks for your help.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Subscribing to file system notifications
Quite a regular
Quite a regular


See User information
@colinw

such kind of code source could integrate very well in the SDK's Examples drawer. Any sample code is good to take in our current situation.
There are many different source samples I'd like to see into this so desperatly *near* empty Examples drawer : a sample generic device, a sample animation datatype, a sample generic handler, a sample boopsi class, to name just a few of them.
Of course I understand that currently time is best spent on improving the OS itself rather than on writing sample tutorials however when some test code exists why not just share it ?

Back to a quiet home... At last
Go to top
Re: Subscribing to file system notifications
Just can't stay away
Just can't stay away


See User information
@abalaban

Yes, good (and working) examples are very important.

Rock lobster bit me - so I'm here forever
X1000 + AmigaOS 4.1 FE
"Anyone can build a fast CPU. The trick is to build a fast system." - Seymour Cray
Go to top
Re: Subscribing to file system notifications
Supreme Council
Supreme Council


See User information
@abalaban

Anyone that wants to contribute source code examples to future versions of the SDK is more than welcome to do so.

As credits for included stuff would be a real headache in this situation, I would suggest that you include any information you want to be made public in the source code itself.

Obviously, examples need to be kept simple, be well commented, and be compilable with the minumum of ease. That means either a makefile, or (in the old SAS/c days) executing the source file.

Examples can be sent to me, and I'll see about adding them to the CVS for future SDK disttributions.

Simon

Go to top
Re: Subscribing to file system notifications
Quite a regular
Quite a regular


See User information
@Rigo

Yes but if I was asking it's because for the mentionned things I don't know the right way to do things myself, else I won't be asking for them
Anyway my comment was mainly because Colin often has some small test codes for DOS.library (which is really a tricky under documented part of AmigaOS) that he publish here and there to demonstrate usage of one DOS.library's function or another, they are generaly relatively small and more importantly they work (as they constitute part of his DOS.library testing process .

Anyway if Colin is okay (and has no time to do it himself) I could try to gather all his samples I can find on websites, provide a makefile and then send them to you for inclusion in the SDK.

EDIT: typo

Back to a quiet home... At last
Go to top
Re: Subscribing to file system notifications
Just popping in
Just popping in


See User information
@abalaban
Yes, go ahead....

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