aboutsummaryrefslogtreecommitdiff
path: root/std/os
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-07-29 23:27:21 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-07-30 13:46:09 -0400
commit3c8d4e04ea000d087af4e77331340db1c8b1cef3 (patch)
tree8f6cc5c2e61d2659189f235529e7208b341270e7 /std/os
parenta870228ab467906ecc663bf89ecd042b49e116f5 (diff)
downloadzig-3c8d4e04ea000d087af4e77331340db1c8b1cef3.tar.gz
zig-3c8d4e04ea000d087af4e77331340db1c8b1cef3.zip
std: file system watching for linux
Diffstat (limited to 'std/os')
-rw-r--r--std/os/file.zig4
-rw-r--r--std/os/index.zig64
-rw-r--r--std/os/linux/index.zig60
3 files changed, 124 insertions, 4 deletions
diff --git a/std/os/file.zig b/std/os/file.zig
index c402aa0522..24c3128350 100644
--- a/std/os/file.zig
+++ b/std/os/file.zig
@@ -29,7 +29,6 @@ pub const File = struct {
/// `path` needs to be copied in memory to add a null terminating byte, hence the allocator.
/// Call close to clean up.
- /// TODO deprecated, just use open
pub fn openRead(allocator: *mem.Allocator, path: []const u8) OpenError!File {
if (is_posix) {
const flags = posix.O_LARGEFILE | posix.O_RDONLY;
@@ -51,7 +50,6 @@ pub const File = struct {
}
/// Calls `openWriteMode` with os.File.default_mode for the mode.
- /// TODO deprecated, just use open
pub fn openWrite(allocator: *mem.Allocator, path: []const u8) OpenError!File {
return openWriteMode(allocator, path, os.File.default_mode);
}
@@ -60,7 +58,6 @@ pub const File = struct {
/// If a file already exists in the destination it will be truncated.
/// `path` needs to be copied in memory to add a null terminating byte, hence the allocator.
/// Call close to clean up.
- /// TODO deprecated, just use open
pub fn openWriteMode(allocator: *mem.Allocator, path: []const u8, file_mode: Mode) OpenError!File {
if (is_posix) {
const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;
@@ -85,7 +82,6 @@ pub const File = struct {
/// If a file already exists in the destination this returns OpenError.PathAlreadyExists
/// `path` needs to be copied in memory to add a null terminating byte, hence the allocator.
/// Call close to clean up.
- /// TODO deprecated, just use open
pub fn openWriteNoClobber(allocator: *mem.Allocator, path: []const u8, file_mode: Mode) OpenError!File {
if (is_posix) {
const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_EXCL;
diff --git a/std/os/index.zig b/std/os/index.zig
index 727c71c435..943e1259b3 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -310,6 +310,29 @@ pub fn posixWrite(fd: i32, bytes: []const u8) !void {
}
}
+pub fn posix_pwritev(fd: i32, iov: [*]const posix.iovec_const, count: usize, offset: u64) PosixWriteError!void {
+ while (true) {
+ const rc = posix.pwritev(fd, iov, count, offset);
+ const err = posix.getErrno(rc);
+ switch (err) {
+ 0 => return,
+ posix.EINTR => continue,
+ posix.EINVAL => unreachable,
+ posix.EFAULT => unreachable,
+ posix.EAGAIN => return PosixWriteError.WouldBlock,
+ posix.EBADF => return PosixWriteError.FileClosed,
+ posix.EDESTADDRREQ => return PosixWriteError.DestinationAddressRequired,
+ posix.EDQUOT => return PosixWriteError.DiskQuota,
+ posix.EFBIG => return PosixWriteError.FileTooBig,
+ posix.EIO => return PosixWriteError.InputOutput,
+ posix.ENOSPC => return PosixWriteError.NoSpaceLeft,
+ posix.EPERM => return PosixWriteError.AccessDenied,
+ posix.EPIPE => return PosixWriteError.BrokenPipe,
+ else => return unexpectedErrorPosix(err),
+ }
+ }
+}
+
pub const PosixOpenError = error{
OutOfMemory,
AccessDenied,
@@ -2913,3 +2936,44 @@ pub fn bsdKEvent(
}
}
}
+
+pub fn linuxINotifyInit1(flags: u32) !i32 {
+ const rc = linux.inotify_init1(flags);
+ const err = posix.getErrno(rc);
+ switch (err) {
+ 0 => return @intCast(i32, rc),
+ posix.EINVAL => unreachable,
+ posix.EMFILE => return error.ProcessFdQuotaExceeded,
+ posix.ENFILE => return error.SystemFdQuotaExceeded,
+ posix.ENOMEM => return error.SystemResources,
+ else => return unexpectedErrorPosix(err),
+ }
+}
+
+pub fn linuxINotifyAddWatchC(inotify_fd: i32, pathname: [*]const u8, mask: u32) !i32 {
+ const rc = linux.inotify_add_watch(inotify_fd, pathname, mask);
+ const err = posix.getErrno(rc);
+ switch (err) {
+ 0 => return @intCast(i32, rc),
+ posix.EACCES => return error.AccessDenied,
+ posix.EBADF => unreachable,
+ posix.EFAULT => unreachable,
+ posix.EINVAL => unreachable,
+ posix.ENAMETOOLONG => return error.NameTooLong,
+ posix.ENOENT => return error.FileNotFound,
+ posix.ENOMEM => return error.SystemResources,
+ posix.ENOSPC => return error.UserResourceLimitReached,
+ else => return unexpectedErrorPosix(err),
+ }
+}
+
+pub fn linuxINotifyRmWatch(inotify_fd: i32, wd: i32) !void {
+ const rc = linux.inotify_rm_watch(inotify_fd, wd);
+ const err = posix.getErrno(rc);
+ switch (err) {
+ 0 => return rc,
+ posix.EBADF => unreachable,
+ posix.EINVAL => unreachable,
+ else => unreachable,
+ }
+}
diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig
index cf68e03ff0..2b0e5e8288 100644
--- a/std/os/linux/index.zig
+++ b/std/os/linux/index.zig
@@ -567,6 +567,37 @@ pub const MNT_DETACH = 2;
pub const MNT_EXPIRE = 4;
pub const UMOUNT_NOFOLLOW = 8;
+pub const IN_CLOEXEC = O_CLOEXEC;
+pub const IN_NONBLOCK = O_NONBLOCK;
+
+pub const IN_ACCESS = 0x00000001;
+pub const IN_MODIFY = 0x00000002;
+pub const IN_ATTRIB = 0x00000004;
+pub const IN_CLOSE_WRITE = 0x00000008;
+pub const IN_CLOSE_NOWRITE = 0x00000010;
+pub const IN_CLOSE = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE;
+pub const IN_OPEN = 0x00000020;
+pub const IN_MOVED_FROM = 0x00000040;
+pub const IN_MOVED_TO = 0x00000080;
+pub const IN_MOVE = IN_MOVED_FROM | IN_MOVED_TO;
+pub const IN_CREATE = 0x00000100;
+pub const IN_DELETE = 0x00000200;
+pub const IN_DELETE_SELF = 0x00000400;
+pub const IN_MOVE_SELF = 0x00000800;
+pub const IN_ALL_EVENTS = 0x00000fff;
+
+pub const IN_UNMOUNT = 0x00002000;
+pub const IN_Q_OVERFLOW = 0x00004000;
+pub const IN_IGNORED = 0x00008000;
+
+pub const IN_ONLYDIR = 0x01000000;
+pub const IN_DONT_FOLLOW = 0x02000000;
+pub const IN_EXCL_UNLINK = 0x04000000;
+pub const IN_MASK_ADD = 0x20000000;
+
+pub const IN_ISDIR = 0x40000000;
+pub const IN_ONESHOT = 0x80000000;
+
pub const S_IFMT = 0o170000;
pub const S_IFDIR = 0o040000;
@@ -704,6 +735,18 @@ pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
return syscall3(SYS_getdents, @intCast(usize, fd), @ptrToInt(dirp), count);
}
+pub fn inotify_init1(flags: u32) usize {
+ return syscall1(SYS_inotify_init1, flags);
+}
+
+pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize {
+ return syscall3(SYS_inotify_add_watch, @intCast(usize, fd), @ptrToInt(pathname), mask);
+}
+
+pub fn inotify_rm_watch(fd: i32, wd: i32) usize {
+ return syscall2(SYS_inotify_rm_watch, @intCast(usize, fd), @intCast(usize, wd));
+}
+
pub fn isatty(fd: i32) bool {
var wsz: winsize = undefined;
return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
@@ -750,6 +793,10 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
return syscall4(SYS_preadv, @intCast(usize, fd), @ptrToInt(iov), count, offset);
}
+pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
+ return syscall4(SYS_pwritev, @intCast(usize, fd), @ptrToInt(iov), count, offset);
+}
+
// TODO https://github.com/ziglang/zig/issues/265
pub fn rmdir(path: [*]const u8) usize {
return syscall1(SYS_rmdir, @ptrToInt(path));
@@ -1068,6 +1115,11 @@ pub const iovec = extern struct {
iov_len: usize,
};
+pub const iovec_const = extern struct {
+ iov_base: [*]const u8,
+ iov_len: usize,
+};
+
pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len));
}
@@ -1376,6 +1428,14 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize {
return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap));
}
+pub const inotify_event = extern struct {
+ wd: i32,
+ mask: u32,
+ cookie: u32,
+ len: u32,
+ //name: [?]u8,
+};
+
test "import" {
if (builtin.os == builtin.Os.linux) {
_ = @import("test.zig");