I neede to do something like 'tail -f' but...
I don't want to access the drive every 250ms, since it has to run for ever.
So what todo...
Use inotify

You can set 'watches' on files or directories and tell the system what to check.
(Access, modification, open, close etc.)
Since it is handled by the kernel (> 2.6.13) you have no drive access
(the kernel knows when he does something at the filesystem)
Unfortunately I was not able to call the functions via an attached underscore (API).
So I had to wrote my own stuff.
Here is the file inotify.pbi:
Code: Select all
#IN_ACCESS =$00000001
#IN_MODIFY = $00000002
#IN_ATTRIB = $00000004
#IN_CLOSE_WRITE = $00000008
#IN_CLOSE_NOWRITE = $00000010
#IN_OPEN = $00000020
#IN_MOVED_FROM = $00000040
#IN_MOVED_TO = $00000080
#IN_CREATE = $00000100
#IN_DELETE = $00000200
#IN_DELETE_SELF = $00000400
#IN_MOVE_SELF = $00000800
#IN_UNMOUNT = $00002000
#IN_Q_OVERFLOW = $00004000
#IN_IGNORED = $00008000
#IN_CLOSE = (#IN_CLOSE_WRITE | #IN_CLOSE_NOWRITE)
#IN_MOVE = (#IN_MOVED_FROM | #IN_MOVED_TO)
#IN_ONLYDIR = $01000000
#IN_DONT_FOLLOW = $02000000
#IN_MASK_ADD = $20000000
#IN_ISDIR = $40000000
#IN_ONESHOT = $80000000
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
#NR_inotify_init = 291
#NR_inotify_add_watch = 292
#NR_inotify_rm_watch = 293
CompilerEndIf
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
#NR_inotify_init = 253
#NR_inotify_add_watch = 254
#NR_inotify_rm_watch = 255
CompilerEndIf
Structure inotify_event
wd.i
mask.l
cookie.l
len.l
name.s
EndStructure
Global inotify_errno.i
Procedure.i inotify_init()
!mov dword eax, 291
!xor dword ebx, ebx
!xor dword ecx, ecx
!xor dword edx, edx
!int byte 0x80
!test dword eax, eax
!js _inotify_init_error ;Jump short if sign (SF=1) (if <> 0 => error)
ProcedureReturn ; return value in EAX
!_inotify_init_error:
!mov dword [v_inotify_errno], eax
ProcedureReturn -1
EndProcedure
Procedure.i inotify_add_watch(fd.i, name.s, mask.l)
!mov dword eax, 292
!mov dword ebx, [p.v_fd]
!mov dword ecx, [p.v_name]
!mov dword edx, [p.v_mask]
!int byte 0x80
!test dword eax, eax
!js _inotify_add_watch_error ;Jump short if sign (SF=1) (if <> 0 => error)
ProcedureReturn ; return value in EAX
!_inotify_add_watch_error:
!mov dword [v_inotify_errno], eax
ProcedureReturn -1
EndProcedure
Procedure.i inotify_rm_watch(fd.i, wd.l)
!mov dword eax, 293
!mov dword ebx, [p.v_fd]
!mov dword ecx, [p.v_wd]
!xor dword edx, edx
!int byte 0x80
!test dword eax, eax
!js _inotify_rm_watch_error ;Jump short if sign (SF=1) (if <> 0 => error)
ProcedureReturn ; return value in EAX
!_inotify_rm_watch_error:
!mov dword [v_inotify_errno], eax
ProcedureReturn -1
EndProcedure
Also the callnumbers are different.
So feel free to adjust this code.
Here a small examble:
touch /tmp/test
and start
Code: Select all
IncludeFile "inotify.pbi"
#F_SETFL = 4
#O_NONBLOCK = 4000
fd = inotify_init()
Debug fd
If fd > 0
Debug "fd: " + Str(fd)
wd = inotify_add_watch(fd, "/tmp/test", #IN_MODIFY) ; change the filename
If wd > 0
Debug "wd: " + Str(wd)
*Buffer = AllocateMemory(10 * (SizeOf(inotify_event) + 16))
read_(fd, *Buffer, MemorySize(*Buffer)) ; blocking read
*Ptr.inotify_event = *Buffer
Debug *Ptr\wd
Debug Hex(*Ptr\mask)
fcntl_(fd, #F_SETFL, #O_NONBLOCK) ; unblock the filehandle
Exit = #False
Repeat
Len = read_(fd, *Buffer, MemorySize(*Buffer))
If Len > 0
i = 0
While i < Len
*Ptr = *Buffer + i
Debug Hex(*Ptr\mask)
If *Ptr\mask = #IN_IGNORED ; repeat until the file is deleted
Exit = #True
EndIf
i = i + SizeOf(inotify_event) + *Ptr\len
Wend
EndIf
Delay(250)
Until Exit
EndIf
close_(fd)
EndIf
Repeat this a few times.
To stop the program you can do a rm /tmp/test
I hope it is usefull for someone.
Bernd
P.S.: Thanks to Flaith, which I have copied a bit.