Inotify listening to moved_from/moved_to events

0

I'm using inotify to listen to events on a directory IN_MOVED_FROM/IN_MOVED_TO pair. Here is the simple assembly program:

SYS_exit equ 0x3C

SYS_inotify_init equ 253

SYS_read equ 0x00
MEMPAGE_SIZE equ 4096

SYS_inotify_add_watch equ 254
IN_MOVED_FROM equ 0x40
IN_MOVED_TO equ 0x80

section .text
    global _start

_start:
    mov rax, SYS_inotify_init
    syscall
    mov r13, rax            ;storing inotify instance

    mov rax, SYS_inotify_add_watch
    mov rdi, r13
    mov rsi, watcher_dir
    mov rdx, IN_MOVED_TO
    syscall 

    mov rax, SYS_inotify_add_watch
    mov rdi, r13
    mov rsi, watcher_dir
    mov rdx, IN_MOVED_FROM
    syscall

    mov rax, SYS_read
    mov rdi, r13
    mov rsi, buf
    mov rdx, MEMPAGE_SIZE
    syscall          <------ I set gdb breakpoint here

    mov eax, SYS_exit
    mov rdi, 0x00
    syscall

section .bss
    buf resb MEMPAGE_SIZE           ;reserving a page
section .data
    watcher_dir: db '/home/me/asm/inotify/data', 0

Ok I run the program in gdb with breakpoint set to reading from inotify descriptor and examine the

struct inotify_event {
     int      wd;       /* Watch descriptor */
     uint32_t mask;     /* Mask describing event */
     uint32_t cookie;   /* Unique cookie associating related
                           events (for rename(2)) */
     uint32_t len;      /* Size of name field */
     char     name[];   /* Optional null-terminated name */
};

And when I move a file as follows

mv data/test data/test.moved

I got only one event IN_MOVED_FROM

(gdb) x/1xw $rsi + 4                                                                                      
0x600138:       0x00000040

The lenght is 0x10:

(gdb) x/1xw $rsi + 12
0x600140:       0x00000010

and

(gdb) x/1xw $rsi + 32
0x600154:       0x00000000

But I expected IN_MOVED_TO event in the buf (get lost?). When I swap the order of the inotify_add_watch in the code the first again get lost. Why?

linux
assembly
x86-64
inotify
asked on Stack Overflow Jul 9, 2018 by St.Antario

1 Answer

2

This is not an assembly problem, you just used the system call wrong. You forgot to specify IN_MASK_ADD. This is what man inotify says:

IN_MASK_ADD

If a watch instance already exists for the filesystem object corresponding to pathname, add (OR) the events in mask to the watch mask (instead of replacing the mask).

Admittedly it's counter-intuitive that inotify_add_watch replaces by default and only adds if you ask for it explicitly.

answered on Stack Overflow Jul 9, 2018 by Jester

User contributions licensed under CC BY-SA 3.0