authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-16 11:39:18+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 13:45:52-04:00
log4843c3b4c386008418ff8ab7238feebab3711352
tree9d6ae6578a92bde27f718a6597a9872b486f2ead
parentb1537b525fa0cd8d51ff89519254db0f066fc04b
signaturelock-open Commit is signed but in an unrecognized format.

std: Introduce fnctl wrapper


7 files changed, 67 insertions(+), 1 deletions(-)

lib/std/os.zig+25
......@@ -3163,6 +3163,31 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
31633163 }
31643164}
31653165
3166pub const FcntlError = error{
3167 PermissionDenied,
3168 FileBusy,
3169 ProcessFdQuotaExceeded,
3170 Locked,
3171} || UnexpectedError;
3172
3173pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
3174 while (true) {
3175 const rc = system.fcntl(fd, cmd, arg);
3176 switch (errno(rc)) {
3177 0 => return @intCast(usize, rc),
3178 EINTR => continue,
3179 EACCES => return error.Locked,
3180 EBADF => unreachable,
3181 EBUSY => return error.FileBusy,
3182 EINVAL => unreachable, // invalid parameters
3183 EPERM => return error.PermissionDenied,
3184 EMFILE => return error.ProcessFdQuotaExceeded,
3185 ENOTDIR => unreachable, // invalid parameter
3186 else => |err| return unexpectedErrno(err),
3187 }
3188 }
3189}
3190
31663191pub const RealPathError = error{
31673192 FileNotFound,
31683193 AccessDenied,
lib/std/os/bits/dragonfly.zig+2
......@@ -283,6 +283,8 @@ pub const F_LOCK = 1;
283283pub const F_TLOCK = 2;
284284pub const F_TEST = 3;
285285
286pub const FD_CLOEXEC = 1;
287
286288pub const AT_FDCWD = -328243;
287289pub const AT_SYMLINK_NOFOLLOW = 1;
288290pub const AT_REMOVEDIR = 2;
lib/std/os/bits/freebsd.zig+2
......@@ -355,6 +355,8 @@ pub const F_GETOWN_EX = 16;
355355
356356pub const F_GETOWNER_UIDS = 17;
357357
358pub const FD_CLOEXEC = 1;
359
358360pub const SEEK_SET = 0;
359361pub const SEEK_CUR = 1;
360362pub const SEEK_END = 2;
lib/std/os/bits/linux.zig+2
......@@ -136,6 +136,8 @@ pub const MAP_FIXED_NOREPLACE = 0x100000;
136136/// For anonymous mmap, memory could be uninitialized
137137pub const MAP_UNINITIALIZED = 0x4000000;
138138
139pub const FD_CLOEXEC = 1;
140
139141pub const F_OK = 0;
140142pub const X_OK = 1;
141143pub const W_OK = 2;
lib/std/os/bits/netbsd.zig+2
......@@ -312,6 +312,8 @@ pub const F_GETLK = 7;
312312pub const F_SETLK = 8;
313313pub const F_SETLKW = 9;
314314
315pub const FD_CLOEXEC = 1;
316
315317pub const SEEK_SET = 0;
316318pub const SEEK_CUR = 1;
317319pub const SEEK_END = 2;
lib/std/os/linux.zig+4
......@@ -588,6 +588,10 @@ pub fn waitpid(pid: pid_t, status: *u32, flags: u32) usize {
588588 return syscall4(SYS_wait4, @bitCast(usize, @as(isize, pid)), @ptrToInt(status), flags, 0);
589589}
590590
591pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) usize {
592 return syscall3(SYS_fcntl, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, cmd)), arg);
593}
594
591595var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
592596
593597// We must follow the C calling convention when we call into the VDSO
lib/std/os/test.zig+30-1
......@@ -1,7 +1,8 @@
11const std = @import("../std.zig");
22const os = std.os;
33const testing = std.testing;
4const expect = std.testing.expect;
4const expect = testing.expect;
5const expectEqual = testing.expectEqual;
56const io = std.io;
67const fs = std.fs;
78const mem = std.mem;
......@@ -446,3 +447,31 @@ test "getenv" {
446447 expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
447448 }
448449}
450
451test "fcntl" {
452 if (builtin.os.tag == .windows)
453 return error.SkipZigTest;
454
455 const test_out_file = "os_tmp_test";
456
457 const file = try fs.cwd().createFile(test_out_file, .{});
458 defer file.close();
459
460 // Note: The test assumes createFile opens the file with O_CLOEXEC
461 {
462 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);
463 expect((flags & os.FD_CLOEXEC) != 0);
464 }
465 {
466 _ = try os.fcntl(file.handle, os.F_SETFD, 0);
467 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);
468 expect((flags & os.FD_CLOEXEC) == 0);
469 }
470 {
471 _ = try os.fcntl(file.handle, os.F_SETFD, os.FD_CLOEXEC);
472 const flags = try os.fcntl(file.handle, os.F_GETFD, 0);
473 expect((flags & os.FD_CLOEXEC) != 0);
474 }
475
476 try fs.cwd().deleteFile(test_out_file);
477}