better examples for std/inotify (#23415)

Previous example wouldn't run unless `std/posix` was imported and it
wasn't mentioned anywhere in the docs.

Other changes in the example:
- replaced magic number with constant `MaxWatches` .
- changed seq buffer to array, because length is already constant +
pointer is a bit nicer: `addr seq[0]` vs `addr arr`
- added example for getting a `cstring` name value from `InotifyEvent`
struct with explicit cast.
- added a bit more description to `inotify_init1` (copied from `man
inotify(7)`)

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
This commit is contained in:
Archar Gelod
2024-08-14 22:35:40 +08:00
committed by GitHub
parent a33e2b76ae
commit 2a046e6487

View File

@@ -67,7 +67,8 @@ proc inotify_init*(): FileHandle {.cdecl, importc: "inotify_init",
proc inotify_init1*(flags: cint): FileHandle {.cdecl, importc: "inotify_init1",
header: "<sys/inotify.h>".}
## Create and initialize inotify instance.
## Like `inotify_init<#inotify_init>`_ ,
## but has a flags argument that provides access to some extra functionality.
proc inotify_add_watch*(fd: cint; name: cstring; mask: uint32): cint {.cdecl,
importc: "inotify_add_watch", header: "<sys/inotify.h>".}
@@ -79,11 +80,18 @@ proc inotify_rm_watch*(fd: cint; wd: cint): cint {.cdecl,
iterator inotify_events*(evs: pointer, n: int): ptr InotifyEvent =
## Abstract the packed buffer interface to yield event object pointers.
## ```Nim
## var evs = newSeq[byte](8192) # Already did inotify_init+add_watch
## while (let n = read(fd, evs[0].addr, 8192); n) > 0: # read forever
## for e in inotify_events(evs[0].addr, n): echo e[].len # echo name lens
## ```
runnableExamples("-r:off"):
when defined(linux):
import std/posix # needed for FileHandle read procedure
const MaxWatches = 8192
let inotifyFd = inotify_init() # create new inotify instance and get it's FileHandle
let wd = inotifyFd.inotify_add_watch("/tmp", IN_CREATE or IN_DELETE) # Add new watch
var events: array[MaxWatches, byte] # event buffer
while (let n = read(inotifyFd, addr events, MaxWatches); n) > 0: # blocks until any events have been read
for e in inotify_events(addr events, n):
echo (e[].wd, e[].mask, cast[cstring](addr e[].name)) # echo watch id, mask, and name value of each event
var ev: ptr InotifyEvent = cast[ptr InotifyEvent](evs)
var n = n
while n > 0:
@@ -94,8 +102,10 @@ iterator inotify_events*(evs: pointer, n: int): ptr InotifyEvent =
runnableExamples:
when defined(linux):
let inoty: FileHandle = inotify_init() ## Create 1 Inotify.
doAssert inoty >= 0 ## Check for errors (FileHandle is alias to cint).
let watchdoge: cint = inotify_add_watch(inoty, ".", IN_ALL_EVENTS) ## Add directory to watchdog.
doAssert watchdoge >= 0 ## Check for errors.
doAssert inotify_rm_watch(inoty, watchdoge) >= 0 ## Remove directory from the watchdog
let inotifyFd = inotify_init() # create and get new inotify FileHandle
doAssert inotifyFd >= 0 # check for errors
let wd = inotifyFd.inotify_add_watch("/tmp", IN_CREATE or IN_DELETE) # Add new watch
doAssert wd >= 0 # check for errors
discard inotifyFd.inotify_rm_watch(wd) # remove watch