User Tools

Site Tools


19.4 Component gb.inotify

With the component gb.inotify by Tobias Boege you can access the linux-specific interface “inotify” in Gambas programs. Information about this interface can be found at The interface allows you to intercept selected file system events. You can thus monitor a path of the file system behind which a file or directory may be located.

However, when using the component, please note the following:

  • It does not specify how long apart the occurrence of a file system event and the occurrence of the corresponding Gambas event can be.
  • For example, if a file is created, the Gambas process may a priori not know about it until an hour later. By that time, however, the file may have been deleted. This is in the nature of things, because file system events are asynchronous.
  • Under normal operating load on the computer, however, the kernel makes an effort to send the events promptly.
  • A Gambas program using the Watch single class of the gb.inotify component is notified by the Linux kernel of activity in the watched directory, where Gambas events of the Watch object are evaluated.

19.4.1 Class Watch

The Watch class (gb.inotify) represents a file system object to be monitored. You can create the class. The class behaves like a static array whose values can only be read. Watching a directory is not recursive for its subdirectories. This means that you only get events from the directory itself and for its immediate entries. However, you can create a separate Watch object for each subdirectory of a base directory and even use the Create event to monitor subdirectories created at runtime.

19.4.2 Creating a Watch object

You can create Watch objects regularly using the New instruction. The signature of the constructor is as follows:

  hWatch = New Watch ( Path As String [ , NoFollowLink As Boolean, Events As Integer ] ) As "EventName"

First, the path of the file system entry to be watched is specified. With the optional parameter NoFollowLink you can forbid following symbolic links when interpreting your path. By default, links are followed. The last optional argument Events is a bitmask of events to monitor. Use the constants of the Watch class for this. For example, if you want to monitor the create and delete events of a path sPath, create the Watch object like this:

  hWatch = New Watch(sPath, False, Watch.Create + Watch.Delete) As „MyWatch”

If you do not specify the events mask, the Watch class automatically determines all events for which you have created event handlers under the specified event name. If you have entered

  Private $hWatch As Watch

  Public Sub Form_Open()
    $hWatch = New Watch(sPath) As "MyWatch"

  Public Sub MyWatch_Create()

  Public Sub MyWatch_Delete()

the Watch class recognises that you want to intercept Create and Delete events from MyWatch and sets these - and only these - events to receivable. For performance reasons, you should never specify more events in the Events mask than you need. You can later change the receivable events via the Events property of the Watch class. You use this property like an array of Boolean values and index them using the Watch constants:

  $hWatch.Events[Watch.Create] = False  ' Create-Events sind nun nicht mehr empfangbar
  $hWatch.Events[Watch.Move] = True     ' Stattdessen interessiert nun das Move-Event

Note that the only job of Watch objects is to trigger events! If you forget to give a Watch object an event name, it cannot trigger events and is useless. Static properties

The Watch class has four static properties that provide additional information for event handlers and should only be used in such. The static properties are used to store data from the kernel during event handler routines.

PropertyData typeDescription
CookieIntegerA cookie is used to link events. This is currently (1.10.2015) only necessary for linking MoveFrom and MoveTo events of the same file.
IsDirBooleanIndicates whether the observation refers or referred to a directory.
NameStringOnly applies to monitored directories: Returns the name of the file or subdirectory from which the event originated. The name is relative to the monitored directory. If the directory itself triggered the event, name = zero. For example, if the directory “abc” is monitored and a file with the file name “xyz” is created there, the create event of “abc” is triggered and Name is set to “xyz”.
UnmountBooleanReturns whether the file system in which the observed path was located was unmounted. If so, the observed object is invalidated immediately after the event is triggered.

Table : Static properties of the Watch class Properties

PropertyData typeDescription
Events.Watch.EventsReturns a virtual class to specify the event watch bitmask. This virtual class is used to manage which events are monitored by a particular Watch object.
IsPausedBooleanReturns whether the Watch is currently paused (→ methods Pause and Resume).
PathStringReturns the monitored path.
Tag VariantThe use of this property can be freely determined by the Gambas programmer.

Table : Properties of the class Watch Methods

The Watch class has only these two methods:

PausePauses a Watch object, preventing it from triggering events.
ResumeEnds the pause mode of a Watch object.

Table : Methods of the Watch class Events

The Watch class has these events:

CloseThe event is triggered when the monitored file or a file in the monitored directory is closed.
CreateThe event is triggered when an entry (file or directory) is created in the monitored directory.
DeleteThe event is triggered when an entry in the monitored directory or the monitored object itself is deleted.
MoveThe event is triggered when the monitored object has been moved.
MoveFromThe event is triggered when an entry of the monitored directory is moved (event for the source directory of the move).
MoveToThe event is triggered when an entry is moved to the monitored directory (event for the target directory of a move).
OpenThe event is triggered when the monitored file or an entry in the monitored directory is opened.
ReadThe event is triggered when the monitored file or an entry in the monitored directory has been accessed in read-only mode, including execution.
StatThe event is triggered when meta data or file attributes of the monitored object have been changed.
WriteThe event is triggered when the monitored file or an entry in the monitored directory has been write-accessed.

Table : Events of the class Watch

As you can see, the meaning and interpretation of an event depends on whether a file or directory is being watched.

19.4.3 Project

The project demonstrates the monitoring of selected temporary directories and a temporary file. The file and the directories are created at runtime and edited (open, modified, moved, deleted) in different ways.

Bild 1 - GUI

Figure Monitoring protocol

The special feature of this project by the author of the component gb.inotify is the triggering of events by an external script. It has to be realised via a task, because on the one hand the monitoring should be as close to real time as possible and on the other hand the task in the project is there to provide for events so that you automatically get to see something when you start the project (→ Task object → Chapter 20.6.0). If the script were executed synchronously, then all editing of the directories and the file would first take place and only later would all monitoring results be received. In the source text you can also see that a separate watch object is created for each new directory and inserted into a watch[ ] array. The corresponding entry in the $aSubDirs array of the type Watch[ ] is removed when the object to be watched has been deleted. If - without a task - the events were only received after the entire script has run through, the created subdirectory would already be deleted when the Gambas process receives its create event. It can therefore no longer be monitored and the process in particular does not receive the events (lying in the past) that have occurred below this subdirectory.

The processing of the directories and the file is done by a separate class → ExternalScript.class.

The source texts are presented in their entirety. The following is the source code in the file ExternalScript.class:

  ' Gambas class file
  Inherits Task
  Private $sFile As String
  Private $sDir As String
  Public Sub _new(sFile As String, sDir As String)
    $sFile = sFile
    $sDir = sDir
  Public Sub Main()
  ' &1 ist eine Datei, &2 ist ein Verzeichnis, &3 ist eine Unterverzeichnis in &2
    Shell Subst$("touch &1;  sleep 1; chmod a+w &1; sleep 1;"
    "touch &3;  sleep 1; cat &1; sleep 1;"
    "echo 'test' > &1; sleep 2;"
    "mkdir &2; sleep 1; mv &1 &2; sleep 1;"
    "rm &4; sleep 1; rmdir &2; sleep 1", $sFile, $sDir, File.Dir($sFile), $sDir &/ File.Name($sFile)) Wait
    Print "Fertig"
    Do ' Darauf warten, dass der Hauptprozess den Task beendet
      Wait 1

Source code FMain.class:

  ' Gambas class file
  Private $hTmp As Watch
  Private $aSubdirs As New Watch[]
  Private $hScript As ExternalScript
  Public Sub Form_Open()
    Dim sFile As String = Temp$(), sDir As String = Temp$()
    FMain.Resizable = True
    TextArea1.ReadOnly = True
    $hTmp = New Watch(File.Dir(sFile)) As "Tmp" ' Erzeugen eines Watch-Objektes
  ' Das Skript muss ein Task sein, weil Sie ja die Events so nah wie möglich zu der Zeit empfangen
  ' wollen, zu der sie ausgelöst werden. Wenn das Skript in diesem Prozess ausgeführt würde,
  ' erhielten Sie die Events gesammelt, nachdem das komplette Skript durchgelaufen ist. So könnten
  ' Sie zum Beispiel keine Ereignisse in den zur Laufzeit erstellten Unterverzeichnissen abfangen.
    $hScript = New ExternalScript(sFile, sDir) As "ExternalScript"
  Public Sub ExternalScript_Read(Data As String)
    If Trim$(Data) <> "Fertig" Then Return
    $hScript.Stop() ' Stoppt den Task als Hintergrund-Prozess
    TextArea1.Insert(gb.NewLine & "*** Externes Skript beendet. ***")
  Public Sub Tmp_Read()
  End ' Tmp_Read()
  Public Sub Tmp_Create()
    Dim hSubdir As Watch
    If Watch.IsDir Then
  ' Das Try steht hier, um eine 'race condition' abzufangen: Das Unterverzeichnis könnte erstellt und schon
  ' wieder gelöscht worden sein, bevor dieser Event-Handler aufgerufen wurde. Das New Watch(..) könnte
  ' fehlschlagen, weil Sie ein Create-Event bearbeiten, dessen Subjekt schon wieder gelöscht wurde.
      Try hSubdir = New Watch(Last.Path &/ Watch.Name) As "Subdir"
      If Not Error Then
         Note("Neues Unterverzeichnis")
      Note("Erstellen", "initialer Modus " & Stat(Last.Path &/ Watch.Name).Auth)
  Public Sub Tmp_Open()
  Public Sub Tmp_Close()
  Public Sub Tmp_Write()
  Public Sub Tmp_Move()
  Public Sub Tmp_MoveFrom()
    Note(Subst$("Umbenennen [ Quelle ] (Cookie &1)", Watch.Cookie))
  Public Sub Subdir_MoveTo()
    Note(Subst$("Umbenennen [ Ziel ] (Cookie &1)", Watch.Cookie))
  Public Sub Tmp_Delete()
  Public Sub Subdir_Delete()
    Note(Subst$("Löschen &1Unterverzeichnis", IIf(Watch.Name, "in ", "")))
    If Not Watch.Name Then $aSubdirs.Remove($aSubdirs.Find(Last))
  Public Sub Tmp_Stat()
    With Stat(Last.Path &/ Watch.Name)
      Note("Datenabfrage", Subst$("Modus &1, letzter Zugriff &2", .Auth, .LastAccess))
    End With
      ' Last.Path &/ Watch.Name könnte nicht mehr existieren und Stat könnte deshalb fehlschlagen.
  Private Sub Note(sWhat As String, …) ' Information:
    Dim sArg As String
    TextArea1.Insert(sWhat & "       " & Last.Path &/ Watch.Name)
    For Each sArg In Param
        TextArea1.Insert(" " & sArg)
    TextArea1.Pos = Len(TextArea1.Text)
  Public Sub btnClose_Click()
  Public Sub Form_Close()
    If $hScript.Running Then $hScript.Stop
    $hTmp = Null
    Wait 1

All monitored events are displayed when triggered by the script → Figure Monitoring log.


The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k19/k19.4/start.txt · Last modified: 14.10.2023 by emma

Page Tools