mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Split out the macOS specific parts
This commit is contained in:
85
src/c.zig
85
src/c.zig
@@ -4,3 +4,88 @@ pub usingnamespace switch (std.Target.current.os.tag) {
|
||||
.macos => @import("./darwin_c.zig"),
|
||||
else => struct {},
|
||||
};
|
||||
|
||||
usingnamespace std.c;
|
||||
const builtin = @import("builtin");
|
||||
const os = std.os;
|
||||
const mem = std.mem;
|
||||
const Stat = std.fs.File.Stat;
|
||||
const Kind = std.fs.File.Kind;
|
||||
const StatError = std.fs.File.StatError;
|
||||
const errno = os.errno;
|
||||
const zeroes = mem.zeroes;
|
||||
|
||||
pub extern "c" fn chmod([*c]const u8, mode_t) c_int;
|
||||
pub extern "c" fn fchmod(c_int, mode_t) c_int;
|
||||
pub extern "c" fn umask(mode_t) mode_t;
|
||||
pub extern "c" fn fchmodat(c_int, [*c]const u8, mode_t, c_int) c_int;
|
||||
|
||||
pub extern "c" fn lstat([*c]const u8, [*c]libc_stat) c_int;
|
||||
pub extern "c" fn lstat64([*c]const u8, [*c]libc_stat) c_int;
|
||||
|
||||
pub fn lstat_absolute(path: [:0]const u8) StatError!Stat {
|
||||
if (builtin.os.tag == .windows) {
|
||||
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
||||
var info: windows.FILE_ALL_INFORMATION = undefined;
|
||||
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
||||
switch (rc) {
|
||||
.SUCCESS => {},
|
||||
.BUFFER_OVERFLOW => {},
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => return windows.unexpectedStatus(rc),
|
||||
}
|
||||
return Stat{
|
||||
.inode = info.InternalInformation.IndexNumber,
|
||||
.size = @bitCast(u64, info.StandardInformation.EndOfFile),
|
||||
.mode = 0,
|
||||
.kind = if (info.StandardInformation.Directory == 0) .File else .Directory,
|
||||
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
||||
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
||||
.ctime = windows.fromSysTime(info.BasicInformation.CreationTime),
|
||||
};
|
||||
}
|
||||
|
||||
var st = zeroes(libc_stat);
|
||||
switch (errno(lstat64(path.ptr, &st))) {
|
||||
.SUCCESS => {},
|
||||
// .EINVAL => unreachable,
|
||||
.BADF => unreachable, // Always a race condition.
|
||||
.NOMEM => return error.SystemResources,
|
||||
.ACCES => return error.AccessDenied,
|
||||
else => |err| return os.unexpectedErrno(err),
|
||||
}
|
||||
|
||||
const atime = st.atime();
|
||||
const mtime = st.mtime();
|
||||
const ctime = st.ctime();
|
||||
return Stat{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(u64, st.size),
|
||||
.mode = st.mode,
|
||||
.kind = switch (builtin.os.tag) {
|
||||
.wasi => switch (st.filetype) {
|
||||
os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice,
|
||||
os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice,
|
||||
os.FILETYPE_DIRECTORY => Kind.Directory,
|
||||
os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink,
|
||||
os.FILETYPE_REGULAR_FILE => Kind.File,
|
||||
os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
else => switch (st.mode & os.S_IFMT) {
|
||||
os.S_IFBLK => Kind.BlockDevice,
|
||||
os.S_IFCHR => Kind.CharacterDevice,
|
||||
os.S_IFDIR => Kind.Directory,
|
||||
os.S_IFIFO => Kind.NamedPipe,
|
||||
os.S_IFLNK => Kind.SymLink,
|
||||
os.S_IFREG => Kind.File,
|
||||
os.S_IFSOCK => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
},
|
||||
.atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
|
||||
.mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
|
||||
.ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
|
||||
};
|
||||
}
|
||||
|
||||
204
src/darwin_c.zig
204
src/darwin_c.zig
@@ -8,6 +8,7 @@ const Kind = std.fs.File.Kind;
|
||||
const StatError = std.fs.File.StatError;
|
||||
const errno = os.errno;
|
||||
const zeroes = mem.zeroes;
|
||||
|
||||
// int clonefileat(int src_dirfd, const char * src, int dst_dirfd, const char * dst, int flags);
|
||||
pub extern "c" fn clonefileat(c_int, [*c]const u8, c_int, [*c]const u8, uint32_t: c_int) c_int;
|
||||
// int fclonefileat(int srcfd, int dst_dirfd, const char * dst, int flags);
|
||||
@@ -15,147 +16,72 @@ pub extern "c" fn fclonefileat(c_int, c_int, [*c]const u8, uint32_t: c_int) c_in
|
||||
// int clonefile(const char * src, const char * dst, int flags);
|
||||
pub extern "c" fn clonefile([*c]const u8, [*c]const u8, uint32_t: c_int) c_int;
|
||||
|
||||
pub extern "c" fn chmod([*c]const u8, mode_t) c_int;
|
||||
pub extern "c" fn fchmod(c_int, mode_t) c_int;
|
||||
pub extern "c" fn umask(mode_t) mode_t;
|
||||
pub extern "c" fn fchmodat(c_int, [*c]const u8, mode_t, c_int) c_int;
|
||||
// pub fn stat_absolute(path: [:0]const u8) StatError!Stat {
|
||||
// if (builtin.os.tag == .windows) {
|
||||
// var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
||||
// var info: windows.FILE_ALL_INFORMATION = undefined;
|
||||
// const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
||||
// switch (rc) {
|
||||
// .SUCCESS => {},
|
||||
// .BUFFER_OVERFLOW => {},
|
||||
// .INVALID_PARAMETER => unreachable,
|
||||
// .ACCESS_DENIED => return error.AccessDenied,
|
||||
// else => return windows.unexpectedStatus(rc),
|
||||
// }
|
||||
// return Stat{
|
||||
// .inode = info.InternalInformation.IndexNumber,
|
||||
// .size = @bitCast(u64, info.StandardInformation.EndOfFile),
|
||||
// .mode = 0,
|
||||
// .kind = if (info.StandardInformation.Directory == 0) .File else .Directory,
|
||||
// .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
||||
// .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
||||
// .ctime = windows.fromSysTime(info.BasicInformation.CreationTime),
|
||||
// };
|
||||
// }
|
||||
|
||||
pub extern "c" fn lstat([*c]const u8, [*c]libc_stat) c_int;
|
||||
pub extern "c" fn lstat64([*c]const u8, [*c]libc_stat) c_int;
|
||||
// var st = zeroes(libc_stat);
|
||||
// switch (errno(stat(path.ptr, &st))) {
|
||||
// 0 => {},
|
||||
// // .EINVAL => unreachable,
|
||||
// .EBADF => unreachable, // Always a race condition.
|
||||
// .ENOMEM => return error.SystemResources,
|
||||
// .EACCES => return error.AccessDenied,
|
||||
// else => |err| return os.unexpectedErrno(err),
|
||||
// }
|
||||
|
||||
pub fn lstat_absolute(path: [:0]const u8) StatError!Stat {
|
||||
if (builtin.os.tag == .windows) {
|
||||
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
||||
var info: windows.FILE_ALL_INFORMATION = undefined;
|
||||
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
||||
switch (rc) {
|
||||
.SUCCESS => {},
|
||||
.BUFFER_OVERFLOW => {},
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => return windows.unexpectedStatus(rc),
|
||||
}
|
||||
return Stat{
|
||||
.inode = info.InternalInformation.IndexNumber,
|
||||
.size = @bitCast(u64, info.StandardInformation.EndOfFile),
|
||||
.mode = 0,
|
||||
.kind = if (info.StandardInformation.Directory == 0) .File else .Directory,
|
||||
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
||||
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
||||
.ctime = windows.fromSysTime(info.BasicInformation.CreationTime),
|
||||
};
|
||||
}
|
||||
|
||||
var st = zeroes(libc_stat);
|
||||
switch (errno(lstat64(path.ptr, &st))) {
|
||||
.SUCCESS => {},
|
||||
// .EINVAL => unreachable,
|
||||
.BADF => unreachable, // Always a race condition.
|
||||
.NOMEM => return error.SystemResources,
|
||||
.ACCES => return error.AccessDenied,
|
||||
else => |err| return os.unexpectedErrno(err),
|
||||
}
|
||||
|
||||
const atime = st.atime();
|
||||
const mtime = st.mtime();
|
||||
const ctime = st.ctime();
|
||||
return Stat{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(u64, st.size),
|
||||
.mode = st.mode,
|
||||
.kind = switch (builtin.os.tag) {
|
||||
.wasi => switch (st.filetype) {
|
||||
os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice,
|
||||
os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice,
|
||||
os.FILETYPE_DIRECTORY => Kind.Directory,
|
||||
os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink,
|
||||
os.FILETYPE_REGULAR_FILE => Kind.File,
|
||||
os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
else => switch (st.mode & os.S_IFMT) {
|
||||
os.S_IFBLK => Kind.BlockDevice,
|
||||
os.S_IFCHR => Kind.CharacterDevice,
|
||||
os.S_IFDIR => Kind.Directory,
|
||||
os.S_IFIFO => Kind.NamedPipe,
|
||||
os.S_IFLNK => Kind.SymLink,
|
||||
os.S_IFREG => Kind.File,
|
||||
os.S_IFSOCK => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
},
|
||||
.atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
|
||||
.mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
|
||||
.ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stat_absolute(path: [:0]const u8) StatError!Stat {
|
||||
if (builtin.os.tag == .windows) {
|
||||
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
||||
var info: windows.FILE_ALL_INFORMATION = undefined;
|
||||
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
||||
switch (rc) {
|
||||
.SUCCESS => {},
|
||||
.BUFFER_OVERFLOW => {},
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => return windows.unexpectedStatus(rc),
|
||||
}
|
||||
return Stat{
|
||||
.inode = info.InternalInformation.IndexNumber,
|
||||
.size = @bitCast(u64, info.StandardInformation.EndOfFile),
|
||||
.mode = 0,
|
||||
.kind = if (info.StandardInformation.Directory == 0) .File else .Directory,
|
||||
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
||||
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
||||
.ctime = windows.fromSysTime(info.BasicInformation.CreationTime),
|
||||
};
|
||||
}
|
||||
|
||||
var st = zeroes(libc_stat);
|
||||
switch (errno(stat(path.ptr, &st))) {
|
||||
0 => {},
|
||||
// .EINVAL => unreachable,
|
||||
.EBADF => unreachable, // Always a race condition.
|
||||
.ENOMEM => return error.SystemResources,
|
||||
.EACCES => return error.AccessDenied,
|
||||
else => |err| return os.unexpectedErrno(err),
|
||||
}
|
||||
|
||||
const atime = st.atime();
|
||||
const mtime = st.mtime();
|
||||
const ctime = st.ctime();
|
||||
return Stat{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(u64, st.size),
|
||||
.mode = st.mode,
|
||||
.kind = switch (builtin.os.tag) {
|
||||
.wasi => switch (st.filetype) {
|
||||
os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice,
|
||||
os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice,
|
||||
os.FILETYPE_DIRECTORY => Kind.Directory,
|
||||
os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink,
|
||||
os.FILETYPE_REGULAR_FILE => Kind.File,
|
||||
os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
else => switch (st.mode & os.S_IFMT) {
|
||||
os.S_IFBLK => Kind.BlockDevice,
|
||||
os.S_IFCHR => Kind.CharacterDevice,
|
||||
os.S_IFDIR => Kind.Directory,
|
||||
os.S_IFIFO => Kind.NamedPipe,
|
||||
os.S_IFLNK => Kind.SymLink,
|
||||
os.S_IFREG => Kind.File,
|
||||
os.S_IFSOCK => Kind.UnixDomainSocket,
|
||||
else => Kind.Unknown,
|
||||
},
|
||||
},
|
||||
.atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
|
||||
.mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
|
||||
.ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
|
||||
};
|
||||
}
|
||||
// const atime = st.atime();
|
||||
// const mtime = st.mtime();
|
||||
// const ctime = st.ctime();
|
||||
// return Stat{
|
||||
// .inode = st.ino,
|
||||
// .size = @bitCast(u64, st.size),
|
||||
// .mode = st.mode,
|
||||
// .kind = switch (builtin.os.tag) {
|
||||
// .wasi => switch (st.filetype) {
|
||||
// os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice,
|
||||
// os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice,
|
||||
// os.FILETYPE_DIRECTORY => Kind.Directory,
|
||||
// os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink,
|
||||
// os.FILETYPE_REGULAR_FILE => Kind.File,
|
||||
// os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket,
|
||||
// else => Kind.Unknown,
|
||||
// },
|
||||
// else => switch (st.mode & os.S_IFMT) {
|
||||
// os.S_IFBLK => Kind.BlockDevice,
|
||||
// os.S_IFCHR => Kind.CharacterDevice,
|
||||
// os.S_IFDIR => Kind.Directory,
|
||||
// os.S_IFIFO => Kind.NamedPipe,
|
||||
// os.S_IFLNK => Kind.SymLink,
|
||||
// os.S_IFREG => Kind.File,
|
||||
// os.S_IFSOCK => Kind.UnixDomainSocket,
|
||||
// else => Kind.Unknown,
|
||||
// },
|
||||
// },
|
||||
// .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
|
||||
// .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
|
||||
// .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const struct_fstore = extern struct {
|
||||
fst_flags: c_uint,
|
||||
|
||||
@@ -4,7 +4,8 @@ pub usingnamespace @import("strings.zig");
|
||||
pub const default_allocator: *std.mem.Allocator = if (isTest) std.heap.c_allocator else @import("./memory_allocator.zig").c_allocator;
|
||||
|
||||
pub const C = @import("c.zig");
|
||||
pub usingnamespace @import("env.zig");
|
||||
pub const Environment = @import("env.zig");
|
||||
pub usingnamespace Environment;
|
||||
|
||||
pub const FeatureFlags = @import("feature_flags.zig");
|
||||
const root = @import("root");
|
||||
|
||||
143
src/watcher.zig
143
src/watcher.zig
@@ -5,6 +5,7 @@ const options = @import("./options.zig");
|
||||
const IndexType = @import("./allocators.zig").IndexType;
|
||||
|
||||
const os = std.os;
|
||||
|
||||
const KEvent = std.os.Kevent;
|
||||
|
||||
const Mutex = @import("./lock.zig").Lock;
|
||||
@@ -12,6 +13,8 @@ const WatchItemIndex = u16;
|
||||
const NoWatchItem: WatchItemIndex = std.math.maxInt(WatchItemIndex);
|
||||
const PackageJSON = @import("./resolver/package_json.zig").PackageJSON;
|
||||
|
||||
const WATCHER_MAX_LIST = 8096;
|
||||
|
||||
pub const WatchItem = struct {
|
||||
file_path: string,
|
||||
// filepath hash for quick comparison
|
||||
@@ -49,6 +52,20 @@ pub const WatchEvent = struct {
|
||||
|
||||
pub const Watchlist = std.MultiArrayList(WatchItem);
|
||||
|
||||
const DarwinWatcher = struct {
|
||||
|
||||
// Internal
|
||||
changelist: [128]KEvent = undefined,
|
||||
|
||||
// Everything being watched
|
||||
eventlist: [WATCHER_MAX_LIST]KEvent = undefined,
|
||||
};
|
||||
|
||||
const PlatformWatcher = if (Environment.isMac)
|
||||
DarwinWatcher
|
||||
else
|
||||
void;
|
||||
|
||||
// This implementation only works on macOS, for now.
|
||||
// The Internet seems to suggest basically always using FSEvents instead of kqueue
|
||||
// It seems like the main concern is max open file descriptors
|
||||
@@ -57,23 +74,17 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
return struct {
|
||||
const Watcher = @This();
|
||||
|
||||
const KEventArrayList = std.ArrayList(KEvent);
|
||||
const WATCHER_MAX_LIST = 8096;
|
||||
|
||||
watchlist: Watchlist,
|
||||
watched_count: usize = 0,
|
||||
mutex: Mutex,
|
||||
|
||||
// Internal
|
||||
changelist: [128]KEvent = undefined,
|
||||
eventlist_used: usize = 0,
|
||||
|
||||
platform: PlatformWatcher = PlatformWatcher{},
|
||||
|
||||
// User-facing
|
||||
watch_events: [128]WatchEvent = undefined,
|
||||
|
||||
// Everything being watched
|
||||
eventlist: [WATCHER_MAX_LIST]KEvent = undefined,
|
||||
eventlist_used: usize = 0,
|
||||
|
||||
fs: *Fs.FileSystem,
|
||||
// this is what kqueue knows about
|
||||
fd: StoredFileDescriptorType,
|
||||
@@ -108,9 +119,11 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
|
||||
pub fn getQueue(this: *Watcher) !StoredFileDescriptorType {
|
||||
if (this.fd == 0) {
|
||||
this.fd = try os.kqueue();
|
||||
if (this.fd == 0) {
|
||||
return error.WatcherFailed;
|
||||
if (Environment.isMac) {
|
||||
this.fd = try os.kqueue();
|
||||
if (this.fd == 0) {
|
||||
return error.WatcherFailed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,28 +215,31 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
fn _watchLoop(this: *Watcher) !void {
|
||||
const time = std.time;
|
||||
|
||||
std.debug.assert(this.fd > 0);
|
||||
if (Environment.isMac) {
|
||||
std.debug.assert(this.fd > 0);
|
||||
|
||||
var changelist_array: [1]KEvent = std.mem.zeroes([1]KEvent);
|
||||
var changelist = &changelist_array;
|
||||
while (true) {
|
||||
defer Output.flush();
|
||||
var code = std.os.system.kevent(
|
||||
try this.getQueue(),
|
||||
@as([*]KEvent, changelist),
|
||||
0,
|
||||
@as([*]KEvent, changelist),
|
||||
1,
|
||||
var changelist_array: [1]KEvent = std.mem.zeroes([1]KEvent);
|
||||
var changelist = &changelist_array;
|
||||
while (true) {
|
||||
defer Output.flush();
|
||||
|
||||
null,
|
||||
);
|
||||
_ = std.os.system.kevent(
|
||||
try this.getQueue(),
|
||||
@as([*]KEvent, changelist),
|
||||
0,
|
||||
@as([*]KEvent, changelist),
|
||||
1,
|
||||
|
||||
var watchevents = this.watch_events[0..1];
|
||||
for (changelist) |event, i| {
|
||||
watchevents[i].fromKEvent(&event);
|
||||
null,
|
||||
);
|
||||
|
||||
var watchevents = this.watch_events[0..1];
|
||||
for (changelist) |event, i| {
|
||||
watchevents[i].fromKEvent(&event);
|
||||
}
|
||||
|
||||
this.ctx.onFileUpdate(watchevents, this.watchlist);
|
||||
}
|
||||
|
||||
this.ctx.onFileUpdate(watchevents, this.watchlist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +282,7 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
const index = this.eventlist_used;
|
||||
const watchlist_id = this.watchlist.len;
|
||||
|
||||
if (isMac) {
|
||||
if (Environment.isMac) {
|
||||
|
||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
|
||||
var event = std.mem.zeroes(KEvent);
|
||||
@@ -290,7 +306,7 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
|
||||
// Store the hash for fast filtering later
|
||||
event.udata = @intCast(usize, watchlist_id);
|
||||
this.eventlist[index] = event;
|
||||
this.platform.eventlist[index] = event;
|
||||
|
||||
// This took a lot of work to figure out the right permutation
|
||||
// Basically:
|
||||
@@ -298,9 +314,9 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
// our while(true) loop above receives notification of changes to any of the events created here.
|
||||
_ = std.os.system.kevent(
|
||||
try this.getQueue(),
|
||||
this.eventlist[index .. index + 1].ptr,
|
||||
this.platform.eventlist[index .. index + 1].ptr,
|
||||
1,
|
||||
this.eventlist[index .. index + 1].ptr,
|
||||
this.platform.eventlist[index .. index + 1].ptr,
|
||||
0,
|
||||
null,
|
||||
);
|
||||
@@ -337,39 +353,42 @@ pub fn NewWatcher(comptime ContextType: type) type {
|
||||
const index = this.eventlist_used;
|
||||
const watchlist_id = this.watchlist.len;
|
||||
|
||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
|
||||
var event = std.mem.zeroes(KEvent);
|
||||
if (Environment.isMac) {
|
||||
|
||||
event.flags = os.EV_ADD | os.EV_CLEAR | os.EV_ENABLE;
|
||||
// we want to know about the vnode
|
||||
event.filter = std.os.EVFILT_VNODE;
|
||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
|
||||
var event = std.mem.zeroes(KEvent);
|
||||
|
||||
// monitor:
|
||||
// - Write
|
||||
// - Rename
|
||||
// - Delete
|
||||
event.fflags = std.os.NOTE_WRITE | std.os.NOTE_RENAME | std.os.NOTE_DELETE;
|
||||
event.flags = os.EV_ADD | os.EV_CLEAR | os.EV_ENABLE;
|
||||
// we want to know about the vnode
|
||||
event.filter = std.os.EVFILT_VNODE;
|
||||
|
||||
// id
|
||||
event.ident = @intCast(usize, fd);
|
||||
// monitor:
|
||||
// - Write
|
||||
// - Rename
|
||||
// - Delete
|
||||
event.fflags = std.os.NOTE_WRITE | std.os.NOTE_RENAME | std.os.NOTE_DELETE;
|
||||
|
||||
this.eventlist_used += 1;
|
||||
// Store the hash for fast filtering later
|
||||
event.udata = @intCast(usize, watchlist_id);
|
||||
this.eventlist[index] = event;
|
||||
// id
|
||||
event.ident = @intCast(usize, fd);
|
||||
|
||||
// This took a lot of work to figure out the right permutation
|
||||
// Basically:
|
||||
// - We register the event here.
|
||||
// our while(true) loop above receives notification of changes to any of the events created here.
|
||||
_ = std.os.system.kevent(
|
||||
try this.getQueue(),
|
||||
this.eventlist[index .. index + 1].ptr,
|
||||
1,
|
||||
this.eventlist[index .. index + 1].ptr,
|
||||
0,
|
||||
null,
|
||||
);
|
||||
this.eventlist_used += 1;
|
||||
// Store the hash for fast filtering later
|
||||
event.udata = @intCast(usize, watchlist_id);
|
||||
this.platform.eventlist[index] = event;
|
||||
|
||||
// This took a lot of work to figure out the right permutation
|
||||
// Basically:
|
||||
// - We register the event here.
|
||||
// our while(true) loop above receives notification of changes to any of the events created here.
|
||||
_ = std.os.system.kevent(
|
||||
try this.getQueue(),
|
||||
this.platform.eventlist[index .. index + 1].ptr,
|
||||
1,
|
||||
this.platform.eventlist[index .. index + 1].ptr,
|
||||
0,
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
this.watchlist.appendAssumeCapacity(.{
|
||||
.file_path = if (copy_file_path) try this.allocator.dupe(u8, file_path) else file_path,
|
||||
|
||||
Reference in New Issue
Block a user