authorgravatar for halildrk@gmail.comnikneym <halildrk@gmail.com> 2023-10-03 23:21:01+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-10-04 13:48:22+03:00
log9f0d2f94175a131d965e86a6396f5ac508b27bf8
treecd1b9212068ee75f9cc2281b60d3204a65dd70e1
parent398db54434dad366748d63f37dcfc5e770cfd278

linux: add fanotify API


2 files changed, 127 insertions(+), 0 deletions(-)

lib/std/os.zig+67
......@@ -4340,6 +4340,73 @@ pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {
43404340 }
43414341}
43424342
4343pub const FanotifyInitError = error{
4344 ProcessFdQuotaExceeded,
4345 SystemFdQuotaExceeded,
4346 SystemResources,
4347 OperationNotSupported,
4348 PermissionDenied,
4349} || UnexpectedError;
4350
4351pub fn fanotify_init(flags: u32, event_f_flags: u32) FanotifyInitError!i32 {
4352 const rc = system.fanotify_init(flags, event_f_flags);
4353 switch (errno(rc)) {
4354 .SUCCESS => return @as(i32, @intCast(rc)),
4355 .INVAL => unreachable,
4356 .MFILE => return error.ProcessFdQuotaExceeded,
4357 .NFILE => return error.SystemFdQuotaExceeded,
4358 .NOMEM => return error.SystemResources,
4359 .NOSYS => return error.OperationNotSupported,
4360 .PERM => return error.PermissionDenied,
4361 else => |err| return unexpectedErrno(err),
4362 }
4363}
4364
4365pub const FanotifyMarkError = error{
4366 MarkAlreadyExists,
4367 IsDir,
4368 NotAssociatedWithFileSystem,
4369 FileNotFound,
4370 SystemResources,
4371 UserMarkQuotaExceeded,
4372 NotImplemented,
4373 NotDir,
4374 OperationNotSupported,
4375 PermissionDenied,
4376 NotSameFileSystem,
4377 NameTooLong,
4378} || UnexpectedError;
4379
4380pub fn fanotify_mark(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[]const u8) FanotifyMarkError!void {
4381 if (pathname) |path| {
4382 const path_c = try toPosixPath(path);
4383 return fanotify_markZ(fanotify_fd, flags, mask, dirfd, &path_c);
4384 }
4385
4386 return fanotify_markZ(fanotify_fd, flags, mask, dirfd, null);
4387}
4388
4389pub fn fanotify_markZ(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[*:0]const u8) FanotifyMarkError!void {
4390 const rc = system.fanotify_mark(fanotify_fd, flags, mask, dirfd, pathname);
4391 switch (errno(rc)) {
4392 .SUCCESS => return,
4393 .BADF => unreachable,
4394 .EXIST => return error.MarkAlreadyExists,
4395 .INVAL => unreachable,
4396 .ISDIR => return error.IsDir,
4397 .NODEV => return error.NotAssociatedWithFileSystem,
4398 .NOENT => return error.FileNotFound,
4399 .NOMEM => return error.SystemResources,
4400 .NOSPC => return error.UserMarkQuotaExceeded,
4401 .NOSYS => return error.NotImplemented,
4402 .NOTDIR => return error.NotDir,
4403 .OPNOTSUPP => return error.OperationNotSupported,
4404 .PERM => return error.PermissionDenied,
4405 .XDEV => return error.NotSameFileSystem,
4406 else => |err| return unexpectedErrno(err),
4407 }
4408}
4409
43434410pub const MProtectError = error{
43444411 /// The memory cannot be given the specified access. This can happen, for example, if you
43454412 /// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it
lib/std/os/linux.zig+60
......@@ -357,6 +357,14 @@ pub fn inotify_rm_watch(fd: i32, wd: i32) usize {
357357 return syscall2(.inotify_rm_watch, @as(usize, @bitCast(@as(isize, fd))), @as(usize, @bitCast(@as(isize, wd))));
358358}
359359
360pub fn fanotify_init(flags: u32, event_f_flags: u32) usize {
361 return syscall2(.fanotify_init, flags, event_f_flags);
362}
363
364pub fn fanotify_mark(fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[*:0]const u8) usize {
365 return syscall5(.fanotify_mark, @as(usize, @bitCast(@as(isize, fd))), flags, mask, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(pathname));
366}
367
360368pub fn readlink(noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
361369 if (@hasField(SYS, "readlink")) {
362370 return syscall3(.readlink, @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
......@@ -3165,6 +3173,58 @@ pub const IN = struct {
31653173 pub const ONESHOT = 0x80000000;
31663174};
31673175
3176pub const FAN = struct {
3177 pub const ACCESS = 0x00000001;
3178 pub const MODIFY = 0x00000002;
3179 pub const CLOSE_WRITE = 0x00000008;
3180 pub const CLOSE_NOWRITE = 0x00000010;
3181 pub const OPEN = 0x00000020;
3182 pub const Q_OVERFLOW = 0x00004000;
3183 pub const OPEN_PERM = 0x00010000;
3184 pub const ACCESS_PERM = 0x00020000;
3185 pub const ONDIR = 0x40000000;
3186 pub const EVENT_ON_CHILD = 0x08000000;
3187 pub const CLOSE = CLOSE_WRITE | CLOSE_NOWRITE;
3188 pub const CLOEXEC = 0x00000001;
3189 pub const NONBLOCK = 0x00000002;
3190 pub const CLASS_NOTIF = 0x00000000;
3191 pub const CLASS_CONTENT = 0x00000004;
3192 pub const CLASS_PRE_CONTENT = 0x00000008;
3193 pub const ALL_CLASS_BITS = CLASS_NOTIF | CLASS_CONTENT | CLASS_PRE_CONTENT;
3194 pub const UNLIMITED_QUEUE = 0x00000010;
3195 pub const UNLIMITED_MARKS = 0x00000020;
3196 pub const ALL_INIT_FLAGS = CLOEXEC | NONBLOCK | ALL_CLASS_BITS | UNLIMITED_QUEUE | UNLIMITED_MARKS;
3197 pub const MARK_ADD = 0x00000001;
3198 pub const MARK_REMOVE = 0x00000002;
3199 pub const MARK_DONT_FOLLOW = 0x00000004;
3200 pub const MARK_ONLYDIR = 0x00000008;
3201 pub const MARK_MOUNT = 0x00000010;
3202 pub const MARK_IGNORED_MASK = 0x00000020;
3203 pub const MARK_IGNORED_SURV_MODIFY = 0x00000040;
3204 pub const MARK_FLUSH = 0x00000080;
3205 pub const ALL_MARK_FLAGS = MARK_ADD | MARK_REMOVE | MARK_DONT_FOLLOW | MARK_ONLYDIR | MARK_MOUNT | MARK_IGNORED_MASK | MARK_IGNORED_SURV_MODIFY | MARK_FLUSH;
3206 pub const ALL_EVENTS = ACCESS | MODIFY | CLOSE | OPEN;
3207 pub const ALL_PERM_EVENTS = OPEN_PERM | ACCESS_PERM;
3208 pub const ALL_OUTGOING_EVENTS = ALL_EVENTS | ALL_PERM_EVENTS | Q_OVERFLOW;
3209 pub const ALLOW = 0x01;
3210 pub const DENY = 0x02;
3211};
3212
3213pub const fanotify_event_metadata = extern struct {
3214 event_len: u32,
3215 vers: u8,
3216 reserved: u8,
3217 metadata_len: u16,
3218 mask: u64 align(8),
3219 fd: i32,
3220 pid: i32,
3221};
3222
3223pub const fanotify_response = extern struct {
3224 fd: i32,
3225 response: u32,
3226};
3227
31683228pub const S = struct {
31693229 pub const IFMT = 0o170000;
31703230